/* * seqIDataMgr.cpp * * Created on: Mar 18, 2022 * Author: Fulvio Laudisio */ #include #include #include #include #include #include "seqIDataMgr.hpp" #include "base64.h" // from64tobits SeqDataMgr * SeqDataMgr::m_pSeqDataMgr = NULL; double gDrotRef = 0.; int gIndiPort = 0; std::string gIndiAddress; SeqDataMgr::SeqDataMgr(Ltcs::IifServiceWorkerInterfacePtr &_iif, Ice::PropertiesPtr props): m_props(props), sashaSave(IProperty::Switch, "sasha_save", "enable_save"), sashaObjName(IProperty::Text, "sasha", "OBJNAME"), sashaNumSeqs(IProperty::Number, "sasha", "num_seqs"), sashaSeqNum(IProperty::Number, "sasha", "seq_num"), // sashaNumCoadds(IProperty::Number, "sasha", "acquire"), sashaNumCoadds(IProperty::Number, "sasha", "num_coadds"), sashaNumDrops(IProperty::Number, "sasha", "num_drops"), sashaNumReads(IProperty::Number, "sasha", "num_reads"), sashaNumGroups(IProperty::Number, "sasha", "num_groups"), sashaNumResets(IProperty::Number, "sasha", "num_resets"), sashaReadout(IProperty::Text, "sasha", "def_readout_region_name"), sashaReadoutRegion(IProperty::Text, "sasha", "readout_region"), sashaBlob(IProperty::Unknown, "sasha_save", "save_image"), sashaLargestFileNumber(IProperty::Number, "sasha_save", "largest_filenum"), sashaExposeProp(IProperty::Switch, "sasha", "start_acquire"), sharknirTemperatureDetector(IProperty::Unknown, "sharknir_temp", "sensor"), sharknirTemperatureColdFinger(IProperty::Unknown, "sharknir_temp", "sensor"), sharknirTemperatureInnerVessel(IProperty::Unknown, "sharknir_temp", "sensor"), sharknirTemperatureOuterVessel(IProperty::Unknown, "sharknir_temp", "sensor"), sashaPressure(IProperty::Unknown, "sharknir_pres1", "sensor"), sashaStop(IProperty::Switch, "sasha", "stop"), sashaFrequencyMode(IProperty::Text, "sasha", "def_mode_name"), sashaEnableCont(IProperty::Switch, "sasha" , "enable_cont" ) { U6_LLOG(__FUNCTION__); m_iif = _iif; m_ExpectedBlobs = 0; SeqDataMgr::m_pSeqDataMgr = this; m_pGetMotorStatus = NULL; su::getValue(m_props->getProperty("Shins.Tracking.Adc.DrotRefAngle"), gDrotRef); gIndiAddress = m_props->getProperty("Shins.SashaWs.IP"); su::getValue(m_props->getProperty("Shins.SashaWs.IndiPort"), gIndiPort); su::SetDataSaveDirectory(m_props->getProperty("Shins.DataMgr.DataSaveDirectory")); U9_LLOG(m_props->getProperty("Shins.DataMgr.DataSaveDirectory")); // sashaBlob.add(IElement("file")); // sashaBlob.setBLOBEnable(IProperty::Never); // sashaNumCoadds.add(IElement("value")); // sashaNumCoadds["value"].setValue(1); m_sashaProps.insert(std::pair("NDIT", sashaNumSeqs)); m_sashaProps.insert(std::pair("NDITINDEX", sashaSeqNum)); m_sashaProps.insert(std::pair("READOUT", sashaReadout)); m_sashaProps.insert(std::pair("READOUTREGION", sashaReadoutRegion)); m_sashaProps.insert(std::pair("SAVE", sashaSave)); m_sashaProps.insert(std::pair("OBJECTNAME", sashaObjName)); m_sashaProps.insert(std::pair("NCOADDS", sashaNumCoadds)); m_sashaProps.insert(std::pair("NDROPS", sashaNumDrops)); m_sashaProps.insert(std::pair("NGROUPS", sashaNumGroups)); m_sashaProps.insert(std::pair("NREADS", sashaNumReads)); m_sashaProps.insert(std::pair("NRESETS", sashaNumResets)); m_sashaProps.insert(std::pair("EXPOSE", sashaExposeProp)); m_sashaProps.insert(std::pair("STOP", sashaStop)); m_sashaProps.insert(std::pair("FREQUENCY", sashaFrequencyMode)); m_sashaProps.insert(std::pair("CONTINUOUS", sashaEnableCont)); m_sashaProps.insert(std::pair("LARGESTFILENUM", sashaLargestFileNumber)); m_sashaProps.insert(std::pair("SENSORTEMPDET", sharknirTemperatureDetector)); m_sashaProps.insert(std::pair("SENSORTEMPCF", sharknirTemperatureColdFinger)); m_sashaProps.insert(std::pair("SENSORTEMPIV", sharknirTemperatureInnerVessel)); m_sashaProps.insert(std::pair("SENSORTEMPOV", sharknirTemperatureOuterVessel)); m_sashaProps.insert(std::pair("SENSORPRES1", sashaPressure)); m_sashaPropsSet["NDIT"] = true; m_sashaPropsSet["NDITINDEX"] = true; m_sashaPropsSet["READOUT"] = true; m_sashaPropsSet["READOUTREGION"] = true; m_sashaPropsSet["SAVE"] = true; m_sashaPropsSet["OBJECTNAME"] = true; m_sashaPropsSet["NCOADDS"] = true; m_sashaPropsSet["NDROPS"] = true; m_sashaPropsSet["NGROUPS"] = true; m_sashaPropsSet["NREADS"] = true; m_sashaPropsSet["NRESETS"] = true; m_sashaPropsSet["EXPOSE"] = true; m_sashaPropsSet["FREQUENCY"] = true; m_sashaTiming["Full_Image"] = 4.2783f; // 4.595f; m_sashaTiming["Center"] = 2.6751f; m_sashaTiming["Bottom"] = 1.0719f; m_sashaTiming["Top"] = 1.0719f; m_sashaTiming["256x256"] = 0.2745f; m_sashaTiming["128x128"] = 0.0718f; m_sashaTiming["1000x1000"] = 4.0481; m_sashaTiming["coro_stripe"] = 0.1283; m_sashaTiming["PD_wollaston_stripe_small"] = 0.1701; m_sashaTiming["PD_wollaston_stripe_large"] = 0.2953; m_getFitsAbortFlag = 0; m_bReceivingFitsFile = false; StartIndiClientThread(); //Flags m_bFlagChanged = true; m_bSaveOnlyExposedFiles = true; m_bSaveIncomingBlob = false; m_instrumentHeader.init = true; updateInstrumentHeader(); m_sashaSetup[suc::instrument_mode] = "GEN"; m_sashaSetup["OBJECTNAME"] = ""; m_sashaSetup["NGROUPS"] = ""; m_sashaSetup["NREADS"] = ""; m_sashaSetup["NDROPS"] = ""; m_sashaSetup["NCOADDS"] = ""; m_sashaSetup["NRESETS"] = ""; m_sashaSetup["NDIT"] = ""; m_sashaSetup["SAVE"] = ""; m_sashaSetup["READOUT"] = ""; m_sashaSetup["DIT"] = ""; m_timeoutSetup.push_back("NGROUPS"); m_timeoutSetup.push_back("NGRONREADSUPS"); m_timeoutSetup.push_back("NGRNDROPSOUPS"); m_timeoutSetup.push_back("NCOADDS"); m_timeoutSetup.push_back("NRESETS"); m_rtcKeywords["TTBIASFILE"] = ""; m_rtcKeywords["TTDMFLATFILE"] = ""; pcf::TimeStamp timestamp = pcf::TimeStamp::now(); su::SetTimeWorkingDirectory(timestamp.getFormattedIso8601Str()); U8_LLOG(__FUNCTION__); } void SeqDataMgr::StartIndiClientThread() { pthread_create(&m_indi_tid, NULL, indi_client_thread, this); } SeqDataMgr::~SeqDataMgr() { } #define OCS_FRAME_TIME_FULLIMAGE 4.2783f #define OCS_FRAME_TIME_CENTER 2.6751f #define OCS_FRAME_TIME_BOTTOM 1.0719f #define OCS_FRAME_TIME_TOP 1.0719f #define OCS_FRAME_TIME_256X256 0.2745f #define OCS_FRAME_TIME_128X128 0.0718f #define OCS_FRAME_TIME_1000X1000 4.0481f #define OCS_FRAME_TIME_COROSTRIPE 0.1283f #define OCS_FRAME_TIME_WOLLASTONE 0.2953f #define OCS_NUM_MAX_FRAMES 25 void set_ramp(float exp_time, float frame_time, int num_max_frames, int ncoadds, int &groups, int &reads, int &drops) { float r = exp_time / (frame_time * ncoadds); float eff_frame_time = frame_time * ncoadds; if(r < num_max_frames) { groups = 1; reads = (int) r; if(r < 1.f) reads = 1; drops = 0; } else { groups = num_max_frames; reads = 1; float fpdrops = (exp_time - groups * eff_frame_time) / ((groups - 1) * eff_frame_time); int floor_drops = (int) fpdrops; float eff_exp_time = eff_frame_time * (groups * reads + (groups - 1) * floor_drops); float extra_time = eff_frame_time * (groups - 1); if(abs(exp_time - eff_exp_time) < abs(exp_time - (eff_exp_time + extra_time))) { drops = floor_drops; } else { drops = floor_drops + 1; } } } std::string get_current_wdir() { char buff[FILENAME_MAX]; getcwd(buff, FILENAME_MAX); std::string curr_work_dir(buff); return curr_work_dir; } float * get_modified_julian_day() { time_t rawtime; time(&rawtime); // "rawtime = Numero di secondi dal 1 Gen 1970 00:00" // "MJD = Numero di giorni dalla mezzanotte del 17 Nov 1858" const int mjd_of_01011970 = 40587; double seconds = rawtime; static float result = mjd_of_01011970 + seconds/86400.; return &result; } int SeqDataMgr::setLampsStatus(const std::map & _osLampsStatus) { U6_LLOG(__FUNCTION__); std::map::const_iterator itContext; itContext = _osLampsStatus.find("CAL_FIBER_DEFOCUS_LAMP"); if(itContext != _osLampsStatus.end()) { if(itContext->second == "ON" || itContext->second == "OFF") { m_obContext.defocus_lamp = itContext->second; } else { std::stringstream log_msg; log_msg << "Error : admitted values for " << itContext->first << " are \"ON\" or \"OFF\""; E_LLOG(log_msg.str()); U8_LLOG(""); throw(std::runtime_error(log_msg.str())); } } itContext = _osLampsStatus.find("CAL_FIBER_FOCUS_LAMP"); if(itContext != _osLampsStatus.end()) { if(itContext->second == "ON" || itContext->second == "OFF") { m_obContext.focus_lamp = itContext->second; } else { std::stringstream log_msg; log_msg << "Error : admitted values for " << itContext->first << " are \"ON\" or \"OFF\""; E_LLOG(log_msg.str()); U8_LLOG(""); throw(std::runtime_error(log_msg.str())); } } itContext = _osLampsStatus.find("CAL_FF_LAMP"); if(itContext != _osLampsStatus.end()) { if(itContext->second == "ON" || itContext->second == "OFF") { m_obContext.flat_field_lamp = itContext->second; } else { std::stringstream log_msg; log_msg << "Error : admitted values for " << itContext->first << " are \"ON\" or \"OFF\""; E_LLOG(log_msg.str()); U8_LLOG(""); throw(std::runtime_error(log_msg.str())); } } U8_LLOG(""); return EXIT_SUCCESS; } int SeqDataMgr::setContext(const std::map & _osContext) { U6_LLOG(__FUNCTION__); std::map::const_iterator itContext; bool bOB = false, bTPLID = false, bTPLSCRIPT = false, bTPL = false, bDPR = false; itContext = _osContext.find("OB"); if(itContext != _osContext.end()) { m_obContext.observation_block = itContext->second; bOB = true; } itContext = _osContext.find("TPLID"); if(itContext != _osContext.end()) { m_obContext.template_id = itContext->second; bTPLID = true; } itContext = _osContext.find("TPLSCRIPT"); if(itContext != _osContext.end()) { m_obContext.template_script = itContext->second; bTPLSCRIPT = true; } itContext = _osContext.find("TPL"); if(itContext != _osContext.end()) { m_obContext.template_name = itContext->second; bTPL = true; } itContext = _osContext.find("DPR_TYPE"); if(itContext != _osContext.end()) { m_obContext.dpr_type = itContext->second; bDPR = true; } if(false && !(bTPL && bTPLID && bTPLSCRIPT && bOB)) { std::stringstream log_msg; log_msg << "Error : Missing at least one of the mandatory parameters {OB TPL TPLID TPLSCRIPT}"; E_LLOG(log_msg.str()); U8_LLOG(""); throw(std::runtime_error(log_msg.str())); } U8_LLOG(""); return EXIT_SUCCESS; } int SeqDataMgr::sashaExpose(const std::map & _dSashaExpose) { U6_LLOG(__FUNCTION__ << " ~ DEPRECATED"); Ice::Int status = EXIT_FAILURE; #ifdef UNDEFINED // lbto::result res; lbto::DDstruct ddt; lbto::SeqDD dd; std::string ha = ""; // double za; std::vector vecFitsKey; std::vector vecFitsComment; // AIRMASS (to be asked to TCS) Airmass ddt.DDname = "AirMass"; dd.push_back(ddt); //vecFitsKey.push_back("AIRMASS"); // HA // to HA = LST - RA ha = m_iif->getHourAngle(); // status = datamgrPrintFITS("HA", ha, "hour angle at start of observation MJD-OBS", IceUtil::None, _c); // ZD (zenith distance) // za = 90 * 60 * 60 - m_iif->getAlt(); // status = datamgrPrintFITS("ZD", su::convertTypeToString(za), "zenith distance of LBT mount at MJD-OBS [deg]", IceUtil::None, _c); // MOONANGL // SUNANGL ddt.DDname = "ParAngle"; dd.push_back(ddt); //m_mapFitsComments["PARANGLE"] = "Parallactic angle at start [deg]"; ddt.DDname = "L_PosAngle"; dd.push_back(ddt); //m_mapFitsComment["POSANGLE"] = "Telescope position angle [deg]"; ddt.DDname = "L_RotAngle"; dd.push_back(ddt); //m_mapFitsComment["ROTANGLE"] = "Telescope rotator angle [deg]"; ddt.DDname = "L_RotMode"; dd.push_back(ddt); //m_mapFitsComment["ROTASTAT"] = "Telescope rotator status"; ddt.DDname = "L_M1X"; dd.push_back(ddt); //m_mapFitsComment["M1-X"] = "X position of primary mirror [mm]"; ddt.DDname = "L_M1Y"; dd.push_back(ddt); //m_mapFitsComment["M1-Y"] = "Y position of primary mirror [mm]"; ddt.DDname = "L_M1Z"; dd.push_back(ddt); //m_mapFitsComment["M1-Z"] = "Z position of primary mirror [mm]"; ddt.DDname = "L_M1RX"; dd.push_back(ddt); //m_mapFitsComment["M1-RX"] = "Tilt of primary across X axis [arcsecs]"; ddt.DDname = "L_M1RY"; dd.push_back(ddt); //m_mapFitsComment["M1-RY"] = "Tilt of primary across Y axis [arcsecs]"; ddt.DDname = "L_M1RZ"; dd.push_back(ddt); //m_mapFitsComment["M1-RZ"] = "Tilt of primary across Z axis [arcsecs]"; ddt.DDname = "L_M2X"; dd.push_back(ddt); //m_mapFitsComment["M2-X"] = "X position of secondary mirror [mm]"; ddt.DDname = "L_M2Y"; dd.push_back(ddt); //m_mapFitsComment["M2-Y"] = "Y position of secondary mirror [mm]"; ddt.DDname = "L_M2Z"; dd.push_back(ddt); //m_mapFitsComment["M2-Z"] = "Z position of secondary mirror [mm]"; ddt.DDname = "L_M2RX"; dd.push_back(ddt); //m_mapFitsComment["M2-RX"] = "Tilt of primary across X axis [arcsecs]"; ddt.DDname = "L_M2RY"; dd.push_back(ddt); //m_mapFitsComment["M2-RY"] = "Tilt of primary across Y axis [arcsecs]"; ddt.DDname = "L_M2RZ"; dd.push_back(ddt); //m_mapFitsComment["M2-RZ"] = "Tilt of primary across Z axis [arcsecs]"; //res = m_iif->iifGetParameter(dd); // if(res.rescode == EXIT_SUCCESS) // { // for(unsigned int i = 1; iiifPresetTelescopeGet(); // U1_LLOG("Getting preset result done"); // if(res.rescode != EXIT_SUCCESS) // { // errorMsg = "Unable to preset telescope"; // A_LLOG(errorMsg << " with messages:"); // for(int i=0; i(m_sashaSetup["DIT"], floatValue); // fits_write_key(fptr, TFLOAT, "DIT ", &floatValue, "Detector Integration Time (ms)", &FitStatus); floatValue = 0.f; su::getValue(m_sashaSetup["NDIT"], floatValue); fits_write_key(fptr, TFLOAT, "NDIT ", &floatValue, "Number of integrations", &FitStatus); floatValue = 0.f; fits_write_key(fptr, TSTRING, "ORIGFILE ", strValue, "...[science | calib | monit].fits orig filename at the tel (nnnnn is a 5 digit running num)", &FitStatus); fits_write_key(fptr, TSTRING, "CREATOR ", (char *)"SHINS", "Software task that created this file", &FitStatus); // fits_write_key(fptr, TINT, "GRPNUM ", &intValue, "Used to group related datafiles", &FitStatus); fits_write_key(fptr, TSTRING, "PARTNER ", strValue, "Name of institute observing", &FitStatus); fits_write_key(fptr, TSTRING, "DATE ", time_string, "'YYYY-MM-DDThh:mm:ss.sss' UTC date and time the file was written", &FitStatus); fits_write_key(fptr, TSTRING, "DATE-OBS ", time_string, "'YYYY-MM-DDThh:mm:ss.sss' UTC date and time of observation start", &FitStatus); fits_write_key(fptr, TSTRING, "UTC-OBS ", strValue, "'hh:mm:ss.sss' UTC of observation start", &FitStatus); fits_write_key(fptr, TSTRING, "LST-OBS ", strValue, "'hh:mm:ss.sss' Local sidereal time at start of observation", &FitStatus); fits_write_key(fptr, TFLOAT, "MJD-OBS ", get_modified_julian_day(), "'nnnnn.nnnnn' Modified Julian Date at the start of the observation. 5 decimals for 1 second accuracy", &FitStatus); fits_write_key(fptr, TSTRING, "OBSERVER ", strValue, "Name of the observer", &FitStatus); fits_write_key(fptr, TSTRING, "PI-COI ", strValue, "Name of PI", &FitStatus); fits_write_key(fptr, TSTRING, "PROPID ", strValue, "Proposal identification ", &FitStatus); int equinox = 2000; fits_write_key(fptr, TSTRING, "RADECSYS ", (char *) "FK5", " Reference system for the equatorial reference system", &FitStatus); fits_write_key(fptr, TINT, "EQUINOX ", &equinox, "Standard FK5 epoch for RA and DEC", &FitStatus); // U1_LLOG("getLST: " << m_iif->getLST()); // U1_LLOG("getHourAngle: " << m_iif->getHourAngle()); std::string tcs_dec = m_iif->getDEC(); std::string tcs_ra = m_iif->getRA(); float telalt; // = m_iif->getAlt(); float telaz; // = m_iif->getAz(); STelescopeEnv tenv; getTelescopeEnv(tenv); U9_LLOG("TCS RA = " << tcs_ra << " ; TCS DEC = " << tcs_dec << "; TCS_ALT = " << telalt << "; TCS_AZ = " << telaz << "; MCS_EL = " << tenv.mcs_elevation << "; MCS_AZ = " << tenv.mcs_azimuth); telaz = tenv.mcs_azimuth; telalt = tenv.mcs_elevation; fits_write_key(fptr, TSTRING, "RA ", su::get_char_star(tcs_ra), "'hh:mm:ss.ss' Right ascension (same as TELRA)", &FitStatus); fits_write_key(fptr, TSTRING, "DEC ", su::get_char_star(tcs_dec), "'dd:mm:ss.s' Declination (same as DECRA)", &FitStatus); fits_write_key(fptr, TFLOAT, "AIRMASS ", &floatValue, "Airmass at start of observation MJD-OBS", &FitStatus); fits_write_key(fptr, TSTRING, "DATASUM ", strValue, "Checksum of data section only", &FitStatus); fits_write_key(fptr, TSTRING, "CHECKSUM ", strValue, "ASCII 1's complement checksum", &FitStatus); fits_write_key(fptr, TSTRING, "CHECKVER ", (char *) "COMPLEMENT", "Checksum algorithm", &FitStatus); fits_write_key(fptr, TSTRING, "LBT_LOG ", strValue, "Operations log entry", &FitStatus); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); fits_write_key(fptr, TSTRING, "PMODEL ", strValue, "Pointing model in use", &FitStatus); fits_write_key(fptr, TSTRING, "OBJRADEC ", strValue, "RADEC system for OBJRA, OBJDEC", &FitStatus); fits_write_key(fptr, TSTRING, "OBJEQUIN ", strValue, "EQUINOX for OBJRA, OBJDEC", &FitStatus); fits_write_key(fptr, TSTRING, "OBJRA ", strValue, "'hh:mm:ss' RA requested (from OB or catalog)", &FitStatus); fits_write_key(fptr, TSTRING, "OBJDEC ", strValue, "'dd:mm:ss' DEC requested (from OB or catalog)", &FitStatus); fits_write_key(fptr, TFLOAT, "OBJPMRA ", &floatValue, "RA proper motion [mas]", &FitStatus); fits_write_key(fptr, TFLOAT, "OBJPMDEC ", &floatValue, "DEC proper motion [mas]", &FitStatus); fits_write_key(fptr, TSTRING, "TELRA ", su::get_char_star(tcs_ra), "'hh:mm:ss.ss' RA at detector center at MJD-OBS", &FitStatus); fits_write_key(fptr, TSTRING, "TELDEC ", su::get_char_star(tcs_dec), "'dd:mm:ss.s' DEC at detector center at MJD-OBS", &FitStatus); fits_write_key(fptr, TFLOAT, "TELALT ", &telalt, "'dd.dd' LBT mount altitude at detector center at MJD-OBS", &FitStatus); fits_write_key(fptr, TFLOAT, "TELAZ ", &telaz, "'ddd.dd. LBT mount azimuth at detector center at MJD-OBS", &FitStatus); fits_write_key(fptr, TLOGICAL,"TRAKSTAT ", &boolValue, "Tracking status", &FitStatus); fits_write_key(fptr, TFLOAT, "TELTKRA ", &floatValue, "'0.0' Tracking rate from sidereal in RA [arcsec]", &FitStatus); fits_write_key(fptr, TFLOAT, "TELTKDEC ", &floatValue, "'0.0' Tracking rate in DEC [arcsec]", &FitStatus); fits_write_key(fptr, TSTRING, "HA ", strValue, "'+hh:mm:ss' hour angle at start of observation MJD-OBS", &FitStatus); fits_write_key(fptr, TFLOAT, "ZD ", &floatValue, "'dd.dd' zenith distance of LBT mount at MJD-OBS [deg]. Complement of TELALT", &FitStatus); fits_write_key(fptr, TFLOAT, "MOONANGL ", &floatValue, "'ddd.ddd' Moon angle at start [deg]", &FitStatus); fits_write_key(fptr, TFLOAT, "SUNANGLE ", &floatValue, "'ddd.ddd' Sun angle at start [deg]", &FitStatus); fits_write_key(fptr, TFLOAT, "PARANGLE ", &floatValue, "'ddd.d' Parallactic angle at start [deg]", &FitStatus); fits_write_key(fptr, TFLOAT, "POSANGLE ", &floatValue, "'ddd.d' Telescope position angle [deg]", &FitStatus); fits_write_key(fptr, TFLOAT, "ROTANGLE ", &floatValue, "'dd.d' Telescope rotator angle [deg]", &FitStatus); fits_write_key(fptr, TSTRING, "ROTASTAT ", (char *)"OFF", "Rotator status. LBT rotator is always OFF when using SHARK-NIR", &FitStatus); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); fits_write_key(fptr, TSTRING, "TEL MODE", su::get_char_star(m_TcsPreset.telescope_mode), "Telescope Mode", &FitStatus); fits_write_key(fptr, TSTRING, "TEL AOMODE", su::get_char_star(m_TcsPreset.ao_mode), "Adaptive Optics Mode", &FitStatus); fits_write_key(fptr, TSTRING, "TEL OBJECTNAME ", su::get_char_star(m_TcsPreset.object_name), "Target Object's name", &FitStatus); fits_write_key(fptr, TSTRING, "TEL COORDINATE SYSTEM ", su::get_char_star(m_TcsPreset.target_coordsys), "Target Coordinate system", &FitStatus); fits_write_key(fptr, TSTRING, "TEL OBJEQUIN ", su::get_char_star(m_TcsPreset.equinox), "Target Coordinate System Equinox", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL EPOCH", &m_TcsPreset.epoch, "Epoch", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL OBJRA ", &m_TcsPreset.objra, "Target RA", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL OBJDEC ", &m_TcsPreset.objdec, "Target DEC", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL OBJMAG ", &m_TcsPreset.objmag, "Target Magnitude", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL PMRA ", &m_TcsPreset.pmra, "Target RA Proper Motion", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL PMDEC ", &m_TcsPreset.pmdec, "Target DEC Porper Motion", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL AORA ", &m_TcsPreset.aora, "Adaptive Optics in RA", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL AODEC ", &m_TcsPreset.aodec, "Adaptive Optics in DEC", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL AOMAG ", &m_TcsPreset.aomag, "Ref star Magnitude", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL PMAORA", &m_TcsPreset.pmaora, "Proper motion of AO in RA", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL PMAODEC", &m_TcsPreset.pmaodec, "Proper motion of AO in DEC", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL GSRA", &m_TcsPreset.gsra, "Guide Star RA", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL GSDEC", &m_TcsPreset.gsdec, "Guide Star in DEC", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL GSMAG", &m_TcsPreset.gsmag, "Guide Star Magnitude", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL PMGSRA", &m_TcsPreset.pmgsra, "Guide Star proper motion in RA", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL PMGSDEC", &m_TcsPreset.pmgsdec, "Guide Star proper motion in DEC", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL DECOFFSET", &tenv.target_decoffset, "Pointing Offset X", &FitStatus); fits_write_key(fptr, TFLOAT, "TEL RAOFFSET", &tenv.target_raoffset, "Pointing Offset Y", &FitStatus); // TEL OBJECTNAME Name of Target Object OBJECTNAME // TEL COORDINATE SYSTEM Target Coordinate System CoordinateSystem // TEL OBJRA Target RA OBJRA // TEL OBJDEC Target DEC OBJDEC // TEL OBJQUIN Target Coordinate System Equinox OBJEQUIN // TEL PMRA Target RA Proper Motion PMRA // TEL PMDEC Target DEC Proper Motion PMDEC // TEL AORA Adaptive Optics in RA AORA // TEL AODEC Adaptive Optics in DEC AODEC // TEL PMAORA Proper Motion of AO in RA PMAORA // TEL PMAODEC Proper Motion of AO in DEC PMAODEC // TEL GSRA Guide Star RA GSRA // TEL GSDEC Guide Star DEC GSDEC // TEL PMGSRA Guide Star RA Proper Motion PMGSRA // TEL PMGSDEC Guide Star DEC Proper Motion PMGSDEC // TEL AOMode Adaptive Optics Mode AOMODE // TEL OFFSET Offset // MISSING // "Epoch":"2022.5", // "Equinox": "j2000", // "BinocularFlag":"OFF", // "TelescopeMode": "ADAPTIVEACE_TRACK", // "TelescopeSide": "LEFT", // fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); // fits_write_key(fptr, TFLOAT, "M1-X ", &floatValue, "X position of primary mirror [mm]", &FitStatus); // fits_write_key(fptr, TFLOAT, "M1-Y ", &floatValue, "Y position of primary mirror [mm]", &FitStatus); // fits_write_key(fptr, TFLOAT, "M1-Z ", &floatValue, "Focus of primary mirror [mm]", &FitStatus); // fits_write_key(fptr, TFLOAT, "M1-RX ", &floatValue, "Tilt of primary across X axis [arcsecs]", &FitStatus); // fits_write_key(fptr, TFLOAT, "M1-RY ", &floatValue, "Tilt of primary across X axis [arcsecs]", &FitStatus); // fits_write_key(fptr, TFLOAT, "M1-RZ ", &floatValue, "Rotation of primary about Z axis [arcsecs]", &FitStatus); // fits_write_key(fptr, TFLOAT, "M2-X ", &floatValue, "X position of secondary mirror [mm]", &FitStatus); // fits_write_key(fptr, TFLOAT, "M2-Y ", &floatValue, "Y position of secondary mirror [mm]", &FitStatus); // fits_write_key(fptr, TFLOAT, "M2-Z ", &floatValue, "Focus of secondary mirror [mm]", &FitStatus); // fits_write_key(fptr, TFLOAT, "M2-RX ", &floatValue, "Tilt of secondary across X axis [arcsecs]", &FitStatus); // fits_write_key(fptr, TFLOAT, "M2-RY ", &floatValue, "Tilt of secondary across X axis [arcsecs]", &FitStatus); // fits_write_key(fptr, TFLOAT, "M2-RZ ", &floatValue, "Rotation of secondary about Z axis [arcsecs]", &FitStatus); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); fits_write_key(fptr, TFLOAT, "DIMMSEEING", &tenv.dimm_seeing, "DIMM seeing, [arcsecs]", &FitStatus); fits_write_key(fptr, TFLOAT, "DIMMMEANFLUX", &floatValue, "DIMM mean centroid flux", &FitStatus); fits_write_key(fptr, TLOGICAL, "LBTWEATHERALIVE", &tenv.lbt_weather_alive, "Weather Station Link State", &FitStatus); fits_write_key(fptr, TFLOAT, "LBTPRESSURE", &tenv.lbt_pressure, "Ambient Pressure [hPa]", &FitStatus); fits_write_key(fptr, TFLOAT, "LBTTEMP", &tenv.lbt_temp, "Ambient Temperature [deg C]", &FitStatus); fits_write_key(fptr, TFLOAT, "LBTHUMIDITY", &tenv.lbt_humidity, "LBT Relative Humidity [percent]", &FitStatus); fits_write_key(fptr, TFLOAT, "LBTDEWPOINT", &tenv.lbt_dewpoint, "LBT Dew Point [deg C]", &FitStatus); fits_write_key(fptr, TFLOAT, "SOULX", &tenv.ao_offsetx, "value for X axis of SOUL stage", &FitStatus); fits_write_key(fptr, TFLOAT, "SOULY", &tenv.ao_offsety, "value ofr Y axis of SOUL stage", &FitStatus); fits_write_key(fptr, TFLOAT, "SOULZ", &tenv.ao_offsetz, "value ofr Z axis of SOUL stage", &FitStatus); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); fits_write_key(fptr, TSTRING, "TELCONF ", strValue, "Telescope configuration", &FitStatus); fits_write_key(fptr, TFLOAT, "FOCSCALE ", &floatValue, "Scale at focal plane [arcsec]", &FitStatus); fits_write_key(fptr, TSTRING, "INSMODE ", strValue, "Mode of use of instrument", &FitStatus); fits_write_key(fptr, TSTRING, "INSTHWV ", strValue, "Instrument hardware version", &FitStatus); fits_write_key(fptr, TSTRING, "INSTSWV ", strValue, "Instrument software version", &FitStatus); // fits_write_key(fptr, TFLOAT, "INSFOCUS ", &floatValue, "Instrument focus [mm]", &FitStatus); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); // Table 11 Detector specific keywords fits_write_key(fptr, TSTRING, "DETECTOR ", strValue, "Detector designation", &FitStatus); fits_write_key(fptr, TSTRING, "DETNAME ", strValue, "Same as DETECTOR DETSIZE '[1:2048,1:2048]' Unbinned size of detector full array", &FitStatus); int nccds = 1; fits_write_key(fptr, TINT, "NCCDS ", &nccds, "Number of CCDs in the detector", &FitStatus); fits_write_key(fptr, TINT, "NAMPS ", &intValue, "Number of amplifiers in the detector", &FitStatus); fits_write_key(fptr, TINT, "PIXSCAL1 ", &intValue, "Projected unbinned pixel scale along axis 1", &FitStatus); fits_write_key(fptr, TINT, "PIXSCAL2 ", &intValue, "Projected unbinned pixel scale along axis 2", &FitStatus); int pixsize = 18; fits_write_key(fptr, TINT, "PIXSIZE1 ", &pixsize, "Unbinned det pix size [microns] along Axis 1", &FitStatus); fits_write_key(fptr, TINT, "PIXSIZE2 ", &pixsize, "Unbinned det pix size [microns] along Axis 2", &FitStatus); // fits_write_key(fptr, TSTRING, "DET HWV ", (char *)"0.0.0", "Detector Hardware Version", &FitStatus); // fits_write_key(fptr, TSTRING, "DET SWV ", (char *)"0.0.0", "Detector Software Version", &FitStatus); // fits_write_key(fptr, TSTRING, "DET STAT ", strValue, "Detector status", &FitStatus); // fits_write_key(fptr, TSTRING, "DEWAR ", strValue, "Dewar identification", &FitStatus); // fits_write_key(fptr, TSTRING, "DEWHWV ", strValue, "Dewar hardware version", &FitStatus); // fits_write_key(fptr, TSTRING, "DEWSWV ", strValue, "Dewar software version", &FitStatus); // fits_write_key(fptr, TSTRING, "DEWSTAT ", strValue, "Dewar status", &FitStatus); // fits_write_key(fptr, TFLOAT, "DEWTEM1 ", &floatValue, "Dewar temperature", &FitStatus); fits_write_key(fptr, TSTRING, "DETSIZE", (char *)"[1:2048, 1:2048]", "Unbinned size of detector full array", &FitStatus); // fits_write_key(fptr, TSTRING, "PIXCAL1", (char *)"", "Projected unbinnned pixel scale along axis 1", &FitStatus); // fits_write_key(fptr, TSTRING, "PIXCAL2", (char *)"", "Projected unbinned pixel scale along axis 2", &FitStatus); SInstrumentHeader & ih = m_instrumentHeader; fits_write_key(fptr, TFLOAT, "CCDTEM ", &ih.temperature_start, "Detector Temperature", &FitStatus); // fits_write_key(fptr, TSTRING, "UDEWTEM ", strValue, "Units for Dewar temperatures", &FitStatus); fits_write_key(fptr, TSTRING, "UCCDTEM ", strValue, "Units for CCD temperature", &FitStatus); // fits_write_key(fptr, TSTRING, "CCDNAME ", strValue, "Name of individual CCD (serial #)", &FitStatus); fits_write_key(fptr, TSTRING, "CCDID ", strValue, "Detector serial number (=ccdname)", &FitStatus); // fits_write_key(fptr, TSTRING, "AMPNAME ", strValue, "Amplifier name", &FitStatus); // fits_write_key(fptr, TSTRING, "CCDHW ", strValue, "Same as DETHWV if NCCDS = 1", &FitStatus); // fits_write_key(fptr, TSTRING, "CCDSW ", strValue, "Same as DETSWV if NCCDS = 1", &FitStatus); // fits_write_key(fptr, TSTRING, "CCDGAIN ", strValue, "CCD gain state", &FitStatus); fits_write_key(fptr, TFLOAT, "GAIN ", &floatValue, "Detector gain in e-/ADU", &FitStatus); fits_write_key(fptr, TFLOAT, "RDNOISE ", &floatValue, "Detector readout noise in e-", &FitStatus); fits_write_key(fptr, TINT, "SATURATE ", &intValue, "Saturation value in ADU", &FitStatus); // fits_write_key(fptr, TSTRING, "BPM ", strValue, "Name of bad pixel mask", &FitStatus); fits_write_key(fptr, TSTRING, "CCDSIZE ", strValue, "'[x1:x2,y1:y2]' Same as DETSIZE", &FitStatus); fits_write_key(fptr, TSTRING, "CCDPSIZE ", strValue, "'[x1:x2,y1:y2]' Same as CCDSIZE except for drift scanning", &FitStatus); fits_write_key(fptr, TINT, "CCDSUM ", &intValue, "CCD on-chip summing (binning)", &FitStatus); fits_write_key(fptr, TSTRING, "AMPSIZE ", strValue, "'[x1:x2,y1:y2]' Unbinned amplifier readout size", &FitStatus); fits_write_key(fptr, TSTRING, "DATASEC ", strValue, "'[x1:x2,y1:y2]' Image data section", &FitStatus); fits_write_key(fptr, TSTRING, "CCDSEC ", strValue, "'[x1:x2,y1:y2]' Region of the CCD read", &FitStatus); fits_write_key(fptr, TSTRING, "DETSEC ", strValue, "'[x1:x2,y1:y2]' Detector section", &FitStatus); fits_write_key(fptr, TSTRING, "BIASSEC ", strValue, "'[x1:x2,y1:y2]' Bias section", &FitStatus); fits_write_key(fptr, TSTRING, "TRIMSEC ", strValue, "'[x1:x2,y1:y2]' Section of useful data", &FitStatus); fits_write_key(fptr, TSTRING, "AMPSEC ", strValue, "'[x1:x2,y1:y2]' Mapping of CCD section to amplifier coordinates", &FitStatus); fits_write_key(fptr, TINT, "CCDNAMPS ", &intValue, "Number of amplifiers to readout the CCD", &FitStatus); fits_write_key(fptr, TFLOAT, "PREFLASH ", &floatValue, "CCD preflash time [ms]", &FitStatus); // fits_write_key(fptr, TFLOAT, "ITIME ", &floatValue, "Exposure time[s] per coadd", &FitStatus); // fits_write_key(fptr, TINT, "NCOADDS ", &intValue, "Number of coadds (result is sum)", &FitStatus); fits_write_key(fptr, TINT, "ACOAVGS ", &intValue, "Number of co-avgs (if individual exps are averaged and not summed –sum & NCOADDS preferred)", &FitStatus); fits_write_key(fptr, TFLOAT, "DETTIME ", &floatValue, "Total exposure time in seconds: NCOADDS x ITIME", &FitStatus); // fits_write_key(fptr, TSTRING, "READMODE ", strValue, "Readout mode", &FitStatus); // fits_write_key(fptr, TINT, "NREADS ", &intValue, "# reads at beg, end or during ITIME", &FitStatus); // Possible values are // - FLUX when the image is produced by SHARKNIR-CAL-SCI-02 // - WAFFLE when the image is produced by SHARKNIR-CAL-SCI-08 // - OBJECT in all other cases fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT DPR TYPE", su::get_char_star(m_obContext.dpr_type), "Data Product Type", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS MECH1 NAME", su::get_char_star(ih.inbeam_dep.nameid), "", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS MECH1 ID", &ih.inbeam_dep.mechanical_id, "General mechanical device unique ID", &FitStatus); // fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS MECH1 ST", &ih.inbeam_dep.status, "T Deployed F Non Deployed", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS MECH1 POS", &ih.inbeam_dep.position1, "Position axis [um]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS MECH1 ENC", &ih.inbeam_dep.encoder1, "Position axis [enc]", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS MIRR1 NAME", su::get_char_star(ih.inbeam_tt.nameid), "", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS MIRR1 POS1", &ih.inbeam_tt.position1, "Position of axis 1 [mm]", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS MIRR1 POS2", &ih.inbeam_tt.position2, "Position of axis 2 [mm]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS MIRR1 ENC1", &ih.inbeam_tt.encoder1, "Position of axis 1 [enc]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS MIRR1 ENC2", &ih.inbeam_tt.encoder2, "Position of axis 2 [enc]", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS SHUT1 NAME", su::get_char_star(ih.shutter.nameid), "", &FitStatus); // fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS SHUT1 ST", &ih.shutter.status, "T Shutter open", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS SHUT1 POS", &ih.shutter.position1, "Position of axis [um]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS SHUT1 ENC", &ih.shutter.encoder1, "Position of axis [enc]", &FitStatus); // fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS MIRR3 NAME", su::get_char_star(ih.cal_mirror_dep.nameid), "Name of optical element", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS MIRR3 ID", &ih.cal_mirror_dep.mechanical_id, "ID of the element", &FitStatus); // fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS MIRR3 ST", &ih.cal_mirror_dep.status, "Status of deployable mirror", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS MIRR3 POS", &ih.cal_mirror_dep.position1, "Position of axis [mm]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS MIRR3 ENC", &ih.cal_mirror_dep.encoder1, "Position of axis [enc]", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI4 NAME", su::get_char_star(ih.cal_filter_dep.nameid), "Name of optical element ", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI4 TYPE", su::get_char_star(ih.cal_filter_dep.type), "Named Position if any", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI4 NP", su::get_char_star(ih.cal_filter_dep.type), "Named Position if any", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI4 ID", &ih.cal_filter_dep.mechanical_id, "ID of the element", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS OPTI4 POS", &ih.cal_filter_dep.position1, "Position of axis [mm]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI4 ENC", &ih.cal_filter_dep.encoder1, "Position of axis [enc]", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI5 NAME", su::get_char_star(ih.cal_fiber_dep.nameid), "Name of optical element ", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI5 TYPE", su::get_char_star(ih.cal_fiber_dep.type), "Named Position if any", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI5 NP", su::get_char_star(ih.cal_fiber_dep.type), "Named Position if any", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI5 ID", &ih.cal_fiber_dep.mechanical_id, "ID of the element", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS OPTI5 POS", &ih.cal_fiber_dep.position1, "Position of axis [mm]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI5 ENC", &ih.cal_fiber_dep.encoder1, "Position of axis [enc]", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI6 NAME", su::get_char_star(ih.cal_flat_field_lamp.nameid), "common name for flat field lamp", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI6 ID", &ih.cal_flat_field_lamp.mechanical_id, "Sensor ID for OPTI6 ", &FitStatus); // fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS OPTI6 VAL", &ih.cal_flat_field_lamp.status, "T for ON, F for OFF ", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI7 NAME", su::get_char_star(ih.cal_fiber_focus_lamp.nameid), "common name for focus lamp", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI7 ID", &ih.cal_fiber_focus_lamp.mechanical_id, "Sensor ID for OPTI7 ", &FitStatus); // fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS OPTI7 VAL", &ih.cal_fiber_focus_lamp.status, "T for ON, F for OFF ", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI8 NAME", su::get_char_star(ih.cal_fiber_defocus_lamp.nameid), "common name for defocus lamp", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI8 ID", &ih.cal_fiber_defocus_lamp.mechanical_id, "Sensor ID for OPTI8 ", &FitStatus); // fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS OPTI8 VAL", &ih.cal_fiber_defocus_lamp.status, "T for ON, F for OFF ", &FitStatus); // fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS FILT1 NAME", su::get_char_star(ih.nd_filt_w.nameid), "Name of optical element", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS FILT1 NP", su::get_char_star(ih.nd_filt_w.type), "Named position if any", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT1 NO", &ih.nd_filt_w.intValue, "Position of wheel used", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT1 ID", &ih.nd_filt_w.mechanical_id, "ID of the element", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS FILT1 POS", &ih.nd_filt_w.position1, "Position of axis [deg]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT1 ENC", &ih.nd_filt_w.encoder1, "Position of axis [enc]", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI1 NAME", su::get_char_star(ih.apodizer_w.nameid), "Name of optical element", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI1 NP", su::get_char_star(ih.apodizer_w.type), "Named position if any", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI1 NO", &ih.apodizer_w.intValue, "Position of wheel used", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI1 ID", &ih.apodizer_w.mechanical_id, "ID of the element", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS OPTI1 POS", &ih.apodizer_w.position1, "Position of axis [deg]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI1 ENC", &ih.apodizer_w.encoder1, "Position of axis [enc]", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI2 NAME", su::get_char_star(ih.coro_slit_w.nameid), "Name of optical element", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI2 NP", su::get_char_star(ih.coro_slit_w.type), "Named position if any", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI2 NO", &ih.coro_slit_w.intValue, "Position of wheel used", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI2 ID", &ih.coro_slit_w.mechanical_id, "ID of the element", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS OPTI2 POS", &ih.coro_slit_w.position1, "Position of axis [deg]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI2 ENC", &ih.coro_slit_w.encoder1, "Position of axis [enc]", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI3 NAME", su::get_char_star(ih.lyot_grism_w.nameid), "Name of optical element", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI3 NP", su::get_char_star(ih.lyot_grism_w.type), "Named position if any", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI3 NO", &ih.lyot_grism_w.intValue, "Position of wheel used", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI3 ID", &ih.lyot_grism_w.mechanical_id, "ID of the element", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS OPTI3 POS", &ih.lyot_grism_w.position1, "Position of axis [deg]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI3 ENC", &ih.lyot_grism_w.encoder1, "Position of axis [enc]", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS FILT2 NAME", su::get_char_star(ih.sci_filt_w1.nameid), "Name of optical element", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS FILT2 NP", su::get_char_star(ih.sci_filt_w1.type), "Named Position if any", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT2 NO", &ih.sci_filt_w1.status, "Position of wheel used", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT2 ID", &ih.sci_filt_w1.mechanical_id, "ID of the element", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS FILT2 POS", &ih.sci_filt_w1.position1, "Position of axis [deg]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT2 ENC", &ih.sci_filt_w1.encoder1, "Position of axis [enc]", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS FILT3 NAME", su::get_char_star(ih.sci_filt_w2.nameid), "Name of optical element", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS FILT3 NP", su::get_char_star(ih.sci_filt_w2.type), "Named position if any", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT3 NO", &ih.sci_filt_w2.intValue, "Position of wheel used", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT3 ID", &ih.sci_filt_w2.mechanical_id, "ID of the element", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS FILT3 POS", &ih.sci_filt_w2.position1, "Position of axis [deg]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT3 ENC", &ih.sci_filt_w2.encoder1, "Position of axis [enc]", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS MECH2 NAME", su::get_char_star(ih.pupil_lens_dep.nameid), "Name of the optical element", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS MECH2 ID", &ih.pupil_lens_dep.mechanical_id, "General mechanical device unique ID", &FitStatus); // fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS MECH2 ST", &ih.pupil_lens_dep.status, "T deployed; F not deployed", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS MECH2 POS", &ih.pupil_lens_dep.position1, "Position axis [um]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS MECH2 ENC", &ih.pupil_lens_dep.encoder1, "Position axis [enc]", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS FILT4 NAME", su::get_char_star(ih.db_filt_w.nameid), "Name of optical element", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS FILT4 NP", su::get_char_star(ih.db_filt_w.type), "Named position if any", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT4 NO", &ih.db_filt_w.intValue, "Position of wheel used", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT4 ID", &ih.db_filt_w.mechanical_id, "ID of the element", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS FILT4 POS", &ih.db_filt_w.position1, "Position of axis [deg]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT4 ENC", &ih.db_filt_w.encoder1, "Position of axis [enc]", &FitStatus); // fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS DROT NAME", su::get_char_star(ih.derotator.nameid), "", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS DROT ID", &ih.derotator.mechanical_id, "General mechanical device unique ID", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS DROT MODE", su::get_char_star(ih.derotator.type), "Instrument derotator mode", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS DROT POS", &ih.derotator.position1, "Position axis [deg]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS DROT ENC", &ih.derotator.encoder1, "Position axis [enc]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS DROT ABSENC",&ih.derotator.encoder2, "Position axis [absenc]", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS DROT BEGIN", &ih.derotator.position2, "Physical position at start [deg]", &FitStatus); // fits_write_key(fptr, TSTRING, "HIERARCH LBT INS ADC NAME", su::get_char_star(su::left(ih.adc.nameid, 3)), "", &FitStatus); // fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS ADC ST", &ih.adc.status, "T when the (sub)system is on, F when off", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS ADC1 POS", &ih.adc.position1, "Position of axis 1 [deg]", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS ADC2 POS", &ih.adc.position2, "Position of axis 2 [deg]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS ADC1 ENC", &ih.adc.encoder1, "Position of axis 1 [enc]", &FitStatus); // fits_write_key(fptr, TINT, "HIERARCH LBT INS ADC2 ENC", &ih.adc.encoder2, "Position of axis 2 [enc]", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS TEMP1 VAL BEGIN", &ih.temperature_start, "Cryo-vacuum T [K] at observation start ", &FitStatus); // fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS TEMP1 VAL END ", &ih.temperature_end, "Cryo-vacuum T [K] at end of observation", &FitStatus); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); // Table 10 Instrument setup keyword fits_write_key(fptr, TSTRING, "INS INSTRUMENT MODE", su::get_char_star(m_sashaSetup[suc::instrument_mode]), "Instrument Mode", &FitStatus); fits_write_key(fptr, TSTRING, "INS MASKCOMBO", su::get_char_star(ih.mask_comb.type), "Mask Combination", &FitStatus); fits_write_key(fptr, TSTRING, "INS SHUTTER", su::get_char_star(ih.shutter.type), "Shutter Deployer", &FitStatus); fits_write_key(fptr, TSTRING, "INS INBEAM_DEP", su::get_char_star(ih.inbeam_dep.type), "Input Beam Deployer", &FitStatus); fits_write_key(fptr, TSTRING, "INS INBEAM_TT", su::get_char_star(ih.inbeam_tt.type), "Input Beam TipTilt Mirror", &FitStatus); fits_write_key(fptr, TSTRING, "INS APODIZER_W", su::get_char_star(ih.apodizer_w.type), "Apodizer Wheel", &FitStatus); fits_write_key(fptr, TSTRING, "INS ND_FILT_W", su::get_char_star(ih.nd_filt_w.type), "Neutral Density Filter Wheel", &FitStatus); fits_write_key(fptr, TSTRING, "INS CORO_SLIT_W", su::get_char_star(ih.coro_slit_w.type), "Coronagraphic Filter Wheel", &FitStatus); fits_write_key(fptr, TSTRING, "INS LYOT_GRISM_W", su::get_char_star(ih.lyot_grism_w.type), "Lyot Grism Wheel", &FitStatus); fits_write_key(fptr, TSTRING, "INS DB_FILT_W", su::get_char_star(ih.db_filt_w.type), "Dual Band Filter Wheel", &FitStatus); fits_write_key(fptr, TSTRING, "INS SCI_FILT_W1", su::get_char_star(ih.sci_filt_w1.type), "Scientific Filter Wheel 1", &FitStatus); fits_write_key(fptr, TSTRING, "INS SCI_FILT_W2", su::get_char_star(ih.sci_filt_w2.type), "Scientific Filter Wheel 2", &FitStatus); fits_write_key(fptr, TSTRING, "INS PUPIL_LENS_DEP", su::get_char_star(ih.pupil_lens_dep.type), "Pupil Lens Deployer", &FitStatus); fits_write_key(fptr, TSTRING, "INS CAL_FIBER_FOCUS_LAMP", su::get_char_star(ih.cal_fiber_focus_lamp.type), "Calibration Fiber Focus Lamp", &FitStatus); fits_write_key(fptr, TSTRING, "INS CAL_FIBER_DEFOCUS_LAMP", su::get_char_star(ih.cal_fiber_defocus_lamp.type), "Calibration Fiber Defocus Lamp", &FitStatus); fits_write_key(fptr, TSTRING, "INS CAL_FF_LAMP", su::get_char_star(ih.cal_flat_field_lamp.type), "Calibration Flat Field Lamp", &FitStatus); fits_write_key(fptr, TSTRING, "INS CAL_FIBER_DEP", su::get_char_star(ih.cal_fiber_dep.type), "Calibration Fiber Deployer", &FitStatus); fits_write_key(fptr, TSTRING, "INS CAL_FILTER_DEP", su::get_char_star(ih.cal_filter_dep.type), "Calibration Filter Deployer", &FitStatus); fits_write_key(fptr, TSTRING, "INS CAL_MIRROR_DEP", su::get_char_star(ih.cal_mirror_dep.type), "Calibratio Mirror Deployer", &FitStatus); fits_write_key(fptr, TSTRING, "INS ADC_MODE", su::get_char_star(ih.adc_mode.type), "Atmospheric Dispersion Corrector Mode", &FitStatus); fits_write_key(fptr, TSTRING, "INS DROT_MODE", su::get_char_star(ih.drot_mode.type), "Derotator Mode", &FitStatus); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); // Table 11 Detector Setup keywords floatValue = 0.f; // su::getValue(m_sashaSetup["DIT"], floatValue); // fits_write_key(fptr, TFLOAT, "DET DIT", &floatValue, "Detector Integration Time", &FitStatus); // intValue = su::convertStringToType(sashaNumReads["value"].getValue()); // fits_write_key(fptr, TINT, "DET NREADS", &intValue, "Number of Reads", &FitStatus); // intValue = su::convertStringToType(sashaNumDrops["value"].getValue()); // fits_write_key(fptr, TINT, "DET NDROPS", &intValue, "Number of Drops", &FitStatus); // intValue = su::convertStringToType(sashaNumGroups["value"].getValue()); // fits_write_key(fptr, TINT, "DET NGROUPS", &intValue, "Number of Groups", &FitStatus); // intValue = su::convertStringToType(sashaNumCoadds["value"].getValue()); // fits_write_key(fptr, TINT, "DET NCOADDS", &intValue, "Number of Coadditions", &FitStatus); // intValue = su::convertStringToType(sashaNumSeqs["value"].getValue()); // fits_write_key(fptr, TINT, "DET NDIT", &intValue, "Number of DITs", &FitStatus); fits_write_key(fptr, TSTRING, "DET READOUT", su::get_char_star(sashaReadout["value"].getValue()), "Readout Mode", &FitStatus); intValue = su::convertStringToType(sashaSeqNum["value"].getValue()); fits_write_key(fptr, TINT, "DET CEXP", &intValue, "Current exposure", &FitStatus); int xmin, xmax, ymin, ymax; GetReadoutRegion(xmin, xmax, ymin, ymax); fits_write_key(fptr, TINT, "DET XMIN", &xmin, "Minimum of X-axis", &FitStatus); fits_write_key(fptr, TINT, "DET XMAX", &xmax, "Maximum of X-axis", &FitStatus); fits_write_key(fptr, TINT, "DET YMIN", &ymin, "Minimum of Y-axis", &FitStatus); fits_write_key(fptr, TINT, "DET YMAX", &ymax, "Maximum of Y-axis", &FitStatus); // fits_write_key(fptr, TLOGICAL,"DET NEXTASBG", &intValue, "Next", &FitStatus); // fits_write_key(fptr, TLOGICAL,"DET PREVASBG", &intValue, "Previous", &FitStatus); intValue = sashaSave["value"].getSwitchState() == IElement::On; fits_write_key(fptr, TLOGICAL,"DET SAVE", &intValue, "Number of images save", &FitStatus); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); // Table 12 RTC Setup Keywords fits_write_key(fptr, TINT, "TTWINCOORDX", &intValue, "", &FitStatus); fits_write_key(fptr, TINT, "TTWINCOORDY", &intValue, "", &FitStatus); fits_write_key(fptr, TFLOAT, "RTCTTCAMTINT", &floatValue, "Value of Y Ref. pixel", &FitStatus); fits_write_key(fptr, TINT, "RTCTTWINROWS", &intValue, "", &FitStatus); fits_write_key(fptr, TINT, "RTCTTWINCOLS", &intValue, "", &FitStatus); fits_write_key(fptr, TINT, "TTFRAMERATE", &intValue, "", &FitStatus); fits_write_key(fptr, TLOGICAL,"RTCTTLOOPENABLED", &intValue, "Number of images save", &FitStatus); fits_write_key(fptr, TLOGICAL,"RTCTTHISTORYENABLED", &intValue, "Number of images save", &FitStatus); fits_write_key(fptr, TSTRING, "TTTIMEHISTORYFILE", (char *)"", "Time History Filename", &FitStatus); fits_write_key(fptr, TINT, "TTTIMEHISTLEN", &intValue, "Value of Y Ref. pixel", &FitStatus); fits_write_key(fptr, TFLOAT, "TTDMMAXPOWER", &floatValue, "Value of Y Ref. pixel", &FitStatus); fits_write_key(fptr, TSTRING, "TTBIASFILE", su::get_char_star(m_rtcKeywords["TTBIASFILE"]), "Value of Y Ref. pixel", &FitStatus); fits_write_key(fptr, TSTRING, "TTDMFLATFILE", su::get_char_star(m_rtcKeywords["TTDMFLATFILE"]), "Value of Y Ref. pixel", &FitStatus); fits_write_key(fptr, TFLOAT, "TTCENTROIDGAINX", &floatValue, "Value of Y Ref. pixel", &FitStatus); fits_write_key(fptr, TFLOAT, "TTCENTROIDGAINY", &floatValue, "Value of Y Ref. pixel", &FitStatus); fits_write_key(fptr, TFLOAT, "TTCENTROIDORIGINX", &floatValue, "Value of Y Ref. pixel", &FitStatus); fits_write_key(fptr, TFLOAT, "TTCENTROIDORIGINY", &floatValue, "Value of Y Ref. pixel", &FitStatus); fits_write_key(fptr, TINT, "TTDMMODESNUM", &intValue, "", &FitStatus); fits_write_key(fptr, TSTRING, "TTPIXELGAINFILE", strValue, "Pixel coordinate system", &FitStatus); fits_write_key(fptr, TLOGICAL,"RTCTTPIXELENABLED", &intValue, "Number of images save", &FitStatus); fits_write_key(fptr, TINT, "RTCTTPIXELDECIMATION", &intValue, "", &FitStatus); fits_write_key(fptr, TLOGICAL,"RTCTTDIAGENABLED", &intValue, "Number of images save", &FitStatus); fits_write_key(fptr, TINT, "RTCTTDIAGDECIMATION", &intValue, "", &FitStatus); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); int WCSAXES = 2; fits_write_key(fptr, TINT, "WCSAXES ", &WCSAXES, "Dimensionality of WCS: 2 for image, 3 for spectrum", &FitStatus); if(WCSAXES == 2) { fits_write_key(fptr, TSTRING, "CTYPE1 ", (char *)"RA---TAN", "Pixel coordinate system", &FitStatus); fits_write_key(fptr, TSTRING, "CTYPE2 ", (char *)"DEC--TAN", "Pixel coordinate system", &FitStatus); fits_write_key(fptr, TSTRING, "RADESYS ", (char *)"ICRS", "reference system", &FitStatus); fits_write_key(fptr, TSTRING, "CUNIT1 ", (char *)"deg", "Unit of coordinate transformation", &FitStatus); fits_write_key(fptr, TSTRING, "CUNIT2 ", (char *)"deg", "Unit of coordinate transformation", &FitStatus); floatValue2 = 0.0000040277777777777; fits_write_key(fptr, TFLOAT, "CDELT1 ", &floatValue2,"Increment along axis 1 as [CUNIT1]/pxl", &FitStatus); fits_write_key(fptr, TFLOAT, "CDELT2 ", &floatValue2,"Increment along axis 2 as [CUNIT2]/pxl", &FitStatus); float ra_tel = 0.f, ra_point_offset = 0.f, ra_guide_offset = 0.f, ra_shark = 0.f; float dec_tel = 0.f, dec_point_offset = 0.f, dec_guide_offset = 0.f, dec_shark = 0.f; floatValue = ra_tel + ra_point_offset + ra_guide_offset + ra_shark; fits_write_key(fptr, TFLOAT, "CRVAL1 ", &floatValue, "RA at CRPIX1 in units CUNIT1", &FitStatus); floatValue = dec_tel + dec_point_offset + dec_guide_offset + dec_shark; fits_write_key(fptr, TFLOAT, "CRVAL2 ", &floatValue, "DEC at CRPIX2 in units CUNIT2", &FitStatus); floatValue = 58.1f + 885.f - xmin; fits_write_key(fptr, TFLOAT, "CRPIX1 ", &floatValue, "Value of X Ref. pixel", &FitStatus); floatValue = 51.5f + 1020.f - ymin; fits_write_key(fptr, TFLOAT, "CRPIX2 ", &floatValue, "Value of Y Ref. pixel", &FitStatus); floatValue = std::cos(ih.derotator.position1 - gDrotRef); fits_write_key(fptr, TFLOAT, "PC1_1 ", &floatValue, "Scale in [CUNIT1]/pixel", &FitStatus); int flip = -1; floatValue *= flip; fits_write_key(fptr, TFLOAT, "PC2_2 ", &floatValue, "Scale in [CUNIT2]/pixel", &FitStatus); floatValue = std::sin(ih.derotator.position1 - gDrotRef); fits_write_key(fptr, TFLOAT, "PC1_2 ", &floatValue, "Rotation and skew", &FitStatus); fits_write_key(fptr, TFLOAT, "PC2_1 ", &floatValue, "Rotation and skew", &FitStatus); } else if(WCSAXES == 3) { fits_write_key(fptr, TSTRING, "CTYPE1 ", (char *)"WAVE", "Pixel coordinate system", &FitStatus); fits_write_key(fptr, TSTRING, "CTYPE2 ", strValue, "Pixel coordinate system", &FitStatus); fits_write_key(fptr, TSTRING, "CTYPE3 ", strValue, "Pixel coordinate system", &FitStatus); fits_write_key(fptr, TSTRING, "CUNIT1 ", strValue, "Unit of coordinate transformation", &FitStatus); fits_write_key(fptr, TSTRING, "CUNIT2 ", strValue, "Unit of coordinate transformation", &FitStatus); fits_write_key(fptr, TSTRING, "CUNIT3 ", strValue, "Unit of coordinate transformation", &FitStatus); fits_write_key(fptr, TFLOAT, "CRVAL1 ", &floatValue, "Wavelength at CRPIX1", &FitStatus); fits_write_key(fptr, TFLOAT, "CRVAL2 ", &floatValue, "RA at CRPIX1 in units CUNIT1", &FitStatus); fits_write_key(fptr, TFLOAT, "CRVAL3 ", &floatValue, "DEC at CRPIX2 in units CUNIT2", &FitStatus); fits_write_key(fptr, TFLOAT, "CD1_1 ", &floatValue, "Increment for CTYPE1", &FitStatus); fits_write_key(fptr, TFLOAT, "CD2_2 ", &floatValue, "Increment for CTYPE2", &FitStatus); fits_write_key(fptr, TFLOAT, "CD3_3 ", &floatValue, "Increment for CTYPE3", &FitStatus); fits_write_key(fptr, TINT, "DISPAXIS ", &intValue, "Dispersion axis (1=rows; 2=columns)", &FitStatus); fits_write_key(fptr, TSTRING, "DISPUNIT ", strValue, "Units for coordinate along DISPAXIS", &FitStatus); fits_write_key(fptr, TSTRING, "DISPWC ", strValue, "Approximate central dispersion coordinate on detector [DISPAXIS]", &FitStatus); fits_write_key(fptr, TSTRING, "DISPDW ", strValue, "Approximate central dispersion per pixel on the detector", &FitStatus); } // TODO : Table 15 Enclosure, environment, and weather specific keywords fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); fits_write_key(fptr, TFLOAT, "DOMEPAN ", &floatValue, "Dome position angle [degrees E of N]", &FitStatus); fits_write_key(fptr, TFLOAT, "DOMTEM ", &floatValue, "Dome temperature [degrees C]", &FitStatus); fits_write_key(fptr, TFLOAT, "DOMHUM ", &floatValue, "Dome relative humidity [%]", &FitStatus); fits_write_key(fptr, TFLOAT, "DOMDEWPT ", &floatValue, "Dome dew point [degrees C]", &FitStatus); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); fits_write_key(fptr, TFLOAT, "ENVTEM ", &floatValue, "Outside temperature, C, at MJD-OBS", &FitStatus); fits_write_key(fptr, TFLOAT, "ENVPRE ", &floatValue, "Atmospheric pressure [mbar]", &FitStatus); fits_write_key(fptr, TFLOAT, "ENVWIN ", &floatValue, "Outside wind speed (m/s) at MJD-OBS", &FitStatus); fits_write_key(fptr, TFLOAT, "ENVDIR ", &floatValue, "(degrees) Direction of wind: E from N", &FitStatus); fits_write_key(fptr, TFLOAT, "ENVHUM ", &floatValue, "Outside relative humidity % at MJD-OBS", &FitStatus); fits_write_key(fptr, TFLOAT, "ENVDEWPT ", &floatValue, "Outside dew point (degrees C) at MJD-OBS", &FitStatus); fits_write_key(fptr, TFLOAT, "ENVTAU ", &floatValue, "Opacity at 225 GHz, from SMT", &FitStatus); fits_write_key(fptr, TSTRING, "WEATHER ", strValue, "Comment by telescope operator or observer", &FitStatus); fits_write_key(fptr, TFLOAT, "SEEING ", &floatValue, "Seeing estimate from S-H WFS", &FitStatus); fits_write_key(fptr, TFLOAT, "SEEWAV ", &floatValue, "Wavelength for seeing estimate", &FitStatus); fits_write_key(fptr, TFLOAT, "SEECAL ", &floatValue, "Seeing: S-H to seeing calibration curve", &FitStatus); U8_LLOG(""); return FitStatus; } void SeqDataMgr::getTelescopeEnv(STelescopeEnv & env) { // DIMMFWHM DIMM seeing, [arcsecs] DIMMSeeing (DIMMSeeingZenith, DIMMSeeingElevation) // DIMMFLUX DIMM mean centroid flux DIMMMeanFlux // LBTWLINK Weather Station Link State LBTWeatherAlive (LBTWeatherAliveFront) // LBTPRES Ambient Pressure [hPa] LBTPressure // LBTTEMP Ambient Temperature [deg C] LBTTemp // LBTHUM LBT Relative Humidity [percent] LBTHumidity // LBTDWPT LBT Dew Point [deg C] LBTDewPoint lbto::result res; lbto::DDstruct ddt; lbto::SeqDD dd; ddt.DDname = "DIMMSeeing"; dd.push_back(ddt); ddt.DDname = "DIMMMeanFlux"; dd.push_back(ddt); ddt.DDname = "LBTWeatherAlive"; dd.push_back(ddt); ddt.DDname = "LBTPressure"; dd.push_back(ddt); ddt.DDname = "LBTTemp"; dd.push_back(ddt); ddt.DDname = "LBTHumidity"; dd.push_back(ddt); ddt.DDname = "LBTDewPoint"; dd.push_back(ddt); ddt.DDname = "ELPosition"; dd.push_back(ddt); ddt.DDname = "AZPosition"; dd.push_back(ddt); ddt.DDname = "SMTTemp"; dd.push_back(ddt); ddt.DDname = "L_AOOffsetX"; dd.push_back(ddt); ddt.DDname = "L_AOOffsetY"; dd.push_back(ddt); ddt.DDname = "L_AOOffsetZ"; dd.push_back(ddt); ddt.DDname = "L_DECOffset"; dd.push_back(ddt); ddt.DDname = "L_RAOffset"; dd.push_back(ddt); res = m_iif->iifGetParameter(dd); if(res.rescode == EXIT_SUCCESS) { double temp; env.dimm_seeing = atof(res.resmsg[1].c_str()); env.dimm_mean_flux = atof(res.resmsg[2].c_str()); env.lbt_weather_alive = (bool)atoi(res.resmsg[3].c_str()); env.lbt_pressure = atof(res.resmsg[4].c_str()); env.lbt_temp = atof(res.resmsg[5].c_str()); env.lbt_humidity = atof(res.resmsg[6].c_str()); env.lbt_dewpoint = atof(res.resmsg[7].c_str()); env.mcs_elevation = atof(res.resmsg[8].c_str())/3600; env.mcs_azimuth = atof(res.resmsg[9].c_str())/3600; env.smt_temp = atof(res.resmsg[10].c_str()); env.ao_offsetx = atof(res.resmsg[11].c_str()); env.ao_offsety = atof(res.resmsg[12].c_str()); env.ao_offsetz = atof(res.resmsg[13].c_str()); env.target_decoffset = atof(res.resmsg[14].c_str()); env.target_raoffset = atof(res.resmsg[15].c_str()); } else { for(unsigned int i = 0; i < res.resmsg.size(); i++) { U9_LLOG(res.resmsg[i]); } } } void SeqDataMgr::GetReadoutRegion(int & xmin, int & xmax, int & ymin, int & ymax) { xmin = xmax = ymin = ymax = 0; std::map::const_iterator itRegion; const std::map & elements = sashaReadoutRegion.getElements(); itRegion = elements.find("x1"); if(itRegion != elements.end()) { if(!su::getValue(itRegion->second.get(), xmin)){ W_LLOG("Could not get readout region XMIN value");} } else { W_LLOG("Could not find readout region XMIN value");} itRegion = elements.find("x2"); if(itRegion != elements.end()) { if(!su::getValue(itRegion->second.get(), xmax)){ W_LLOG("Could not get readout region XMAX value");} } else { W_LLOG("Could not find readout region XMAX value");} itRegion = elements.find("y1"); if(itRegion != elements.end()) { if(!su::getValue(itRegion->second.get(), ymin)){ W_LLOG("Could not get readout region YMIN value");} } else { W_LLOG("Could not find readout region YMIN value");} itRegion = elements.find("y2"); if(itRegion != elements.end()) { if(!su::getValue(itRegion->second.get(), ymax)){ W_LLOG("Could not get readout region YMAX value");} } else { W_LLOG("Could not find readout region YMAX value");} } int SeqDataMgr::sashaEnableSave(const std::map & _dSashaSetup) { // To be Implemented U6_LLOG(__FUNCTION__ << " ~ DEPRECATED"); Ice::Int status = EXIT_SUCCESS; #ifdef UNDEFINED IProperty sashaSave(IProperty::Switch), recvProp; std::map::const_iterator itFind; itFind = _dSashaSetup.find("SAVE"); // m_ptrIc->connect(); // NOTE while alive, indiserver does not close the connection to the client. // U1_LLOG("Command sasha to save to file"); U1_LLOG("Command sasha to save to file"); sashaSave.setDevice("sasha_save"); sashaSave.setName("enable_save"); sashaSave.setPerm(IProperty::ReadWrite); sashaSave.setState(IProperty::Busy); sashaSave.add(IElement("value")); // Switch properties can have value On or Off sashaSave["value"].setSwitchState(IElement::Off); U1_LLOG(sashaSave.getType()); if(!(itFind == _dSashaSetup.end())) { if((su::str_tolower(itFind->second) == "true") || (itFind->second == "1")) { sashaSave["value"].setSwitchState(IElement::On); } } // m_ptrIc2->send_new_property_wait2(sashaSave, recvProp); #endif // status = m_ptrIc->close(); U8_LLOG(__FUNCTION__); return status; } int SeqDataMgr::sashaGetFitsFile(const std::map & _dSashaSetup, const std::string & _instMode, std::string & _outFilename) { U6_LLOG(__FUNCTION__ << " ~ DEPRECATED"); int status = EXIT_FAILURE; #ifdef UNDEFINED std::string strObjname = "test"; Ice::CommunicatorPtr dataMgrIC; // std::ostringstream streamRsync; // std::ostringstream streamFileNum; // std::ostringstream streamFileName; std::ofstream fout; // --Ice.Config=$INSROOT/etc/data_mgr/data_mgr-ice.cfg // char* argvDataMgr[] = { "SequencerI::sashaGetFITSFile", // "--Ice.Config=/opt/tan/etc/data_mgr/data_mgr-ice.cfg" }; // int argcDataMgr = 2; // CFITSIO related // // Saving file to disk // filename format is SHARKNIR.YYYY-MM-DDThh:mm:ss.ssssssZ.<_instMode>.fits // this is passed to data manager for future use in mearging headers // and saved in output parameter // // get date of file creation by INDI in ISO8601 format dateISO8601 = recvProp.getTimeStamp().getFormattedIso8601Str(); filenameSASHA = "SHARKNIR." + dateISO8601 + "." + _instMode + ".SASHA.fits"; filenameSHINS = "SHARKNIR." + dateISO8601 + "." + _instMode + ".fits"; /* what follows is most likely old code to be erased at this moment dataMgr will take care of ingesting file to LBT archive mount point // setting filenameSASHA as filename of acquired FITS file to data_mgr for its reference // NOTE: may not be necessary dataMgrIC = Ice::initialize(argcDataMgr, argvDataMgr); Ice::ObjectPrx base = dataMgrIC->stringToProxy("dataManagerAdapter:default -p 10501"); sd::fitsFilePrx archiver = sd::fitsFilePrx::checkedCast(base); if(!archiver) throw("Invalid Proxy"); // setting name of SASHA produced FITS in data manager component status = archiver->setCurrentFilenameSASHA(filenameSASHA); U4_LLOG(archiver->getCurrentFilenameSASHA()); // creating fits file with no data and with complete+populated header. status = archiver->createEmptyAndPopulateHeader(filnameSHINS, bitpix, naxis, vecNaxes); status = archiver->mergeHeadersAndCopyData(filenameSHINS, filenameSASHA); */ } } } } } if(dataMgrIC)dataMgrIC->destroy(); // creating standard vectors with keywords values and comments for SHINS part of header. // These vectors will be passed to data manager which will merge them to SASHA header // by creating in place a FITS header and merging it to SASHA header, without creating // a second file on disk // create header only fits file to fill with SHINS values for keywords // try // { // dataMgrIC = Ice::initialize(argcDataMgr, argvDataMgr); // Ice::ObjectPrx base = dataMgrIC->stringToProxy("dataManagerAdapter:default -p 10501"); // sd::fitsFilePrx archiver = sd::fitsFilePrx::checkedCast(base); // if(!archiver) // throw("Invalid Proxy"); // status = archiver->saveSASHABLOB(toBitsBlob, counter); // status = archiver->setCurrentFilenameSASHA(_outFilenameSASHA); // } // catch(const Ice::Exception& ex) // catch(const char* msg) // if(dataMgrIC)dataMgrIC->destroy(); // timeOut = su::convertStringToType(itDit->second)* // su::convertStringToType(itNDit->second)*std::pow(10,6); // time out have to be in micro seconds // U1_LLOG("time out = " << timeOut*2 << " micro seconds"); // IndiProperty sashaSaveFileNum(IndiProperty::Text); // IndiProperty sharknirUTCDate(IndiProperty::Number); // the method shouhld check on remote INDI property for info on exposure status // alredy done by sashaExpose, but to control twice is better // _outFilenameSASHA = "No Filename Retrieved"; // boost::thread fits_notify_thread(inotifierInstance.start, _remotePathToWatch, // boost::ref(_outFilenameSASHA), // timeOut*6); // create and start thread // fits_notify_thread.join(); // Wait for thread to finish // check on _outFilenameSASHA // fits_notify_thread should have timeout parameter for INotifier::start itFind = _dSashaSetup.find("OBJECTNAME"); if(!(itFind == _dSashaSetup.end()))strObjname = itFind->second; // sashaSaveFileNum = init_indi_property("sasha_save", "largest_filenum", IndiProperty::Text, std::vector(1, "value")); // vecElemNames.push_back("JD"); // vecElemNames.push_back("UTC"); // vecElemNames.push_back("UTCDate"); // vecElemNames.push_back("LT"); // vecElemNames.push_back("LST"); // vecElemNames.push_back("MoonAz"); // vecElemNames.push_back("MoonAlt"); // vecElemNames.push_back("MoonElong"); // vecElemNames.push_back("MoonLit"); // vecElemNames.push_back("SunAz"); // vecElemNames.push_back("SunAlt"); // sharknirUTCDate = init_indi_property("sharknir_time", "Now", // IndiProperty::Number, // vecElemNames); // // NOTE while alive, indiserver does not close the connection to the client. // U1_LLOG("Asking INDI for file number ..."); // m_ptrIc2->send_get_property_wait(sashaSaveFileNum, recvProp); // streamFileNum << std::setfill('0') << std::setw(6) // << recvProp["value"].getValue() << std::setfill(' '); // recvProp.clear(); // U1_LLOG("Asking INDI for UTC date ... "); // m_ptrIc2->send_get_property_wait(sharknirUTCDate, recvProp); // strUTCDate = recvProp["UTCDate"].getValue().substr(2,recvProp["UTCDate"].getValue().size()-2); // U1_LLOG("Got " << recvProp["UTCDate"].getValue()); // U1_LLOG("Extracted " << strUTCDate); // streamRsync << "rsync -avzh " << su::get_LLOGin() << "@sashaws::fits/" << strUTCDate // << "/sa_" << strUTCDate << "_" << streamFileNum.str() // << ".fits " << dataDir // << "SHARKNIR_" << strObjname << "_" << recvProp["UTCDate"].getValue() // << "_" << streamFileNum.str() << ".fits"; // streamFileName << "SHARKNIR_" << strObjname << "_" << recvProp["UTCDate"].getValue() // << "_" << streamFileNum.str() << ".fits"; // status = std::system(streamRsync.str().c_str()); } #endif U8_LLOG(""); return status; } // Patch to get rid of the timeout problem of sasha driver. NREAD is sent whenever NDIT changes and no other parameters are sent int SeqDataMgr::sashaEndSetup(std::map & _dTimeoutSetup, bool ndit_changed) { U6_LLOG(__FUNCTION__); int status = EXIT_SUCCESS; if(ndit_changed && _dTimeoutSetup.empty()) { IProperty & prop = m_sashaProps.find("NREADS")->second; const std::map elements = prop.getElements(); if(elements.find("value") != elements.end()) { _dTimeoutSetup["NREADS"] = prop["value"].getValue(); } else { std::stringstream log_msg; log_msg << "Error : IProperty \"" << prop.getDevice() << "." << prop.getName() << "\" from INDI Server has changed"; E_LLOG(log_msg.str()); throw(std::runtime_error(log_msg.str())); } } std::map::iterator itSetup; int num_properties = _dTimeoutSetup.size(); int counter = 0, sent_properties = 0; try { for(itSetup = _dTimeoutSetup.begin(); itSetup != _dTimeoutSetup.end(); itSetup++) { if(m_getFitsAbortFlag)break; counter++; IProperty & prop = m_sashaProps.find(itSetup->first)->second; const std::map elements = prop.getElements(); bool bPropError = false, bSetProperty = false; if(elements.find("value") != elements.end()) { if(itSetup->second != prop["value"].getValue()) { prop["value"].setValue(su::convertStringToType(itSetup->second)); bSetProperty = true; } } else bPropError = true; if(bPropError) { std::stringstream log_msg; log_msg << "Error : IProperty \"" << prop.getDevice() << "." << prop.getName() << "\" from INDI Server has changed"; E_LLOG(log_msg.str()); throw(std::runtime_error(log_msg.str())); } else if(bSetProperty || (sent_properties == 0 && counter == num_properties)) { m_sashaPropsSet[itSetup->first] = false; SendNewProperty(prop); sent_properties++; } } bool wait_result = false; wait_result = WaitSetMessages(60000000); if(!wait_result)status = EXIT_FAILURE; } catch(...) { E_LLOG(__FUNCTION__); U8_LLOG(""); throw; } U8_LLOG(""); return status; } int SeqDataMgr::sashaSetup(const std::map & _dSashaExpose) { U6_LLOG(__FUNCTION__); int status = EXIT_SUCCESS; m_exposeMutex.lock(); try { std::map::iterator itSashaSetup; for(itSashaSetup = m_sashaSetup.begin(); itSashaSetup != m_sashaSetup.end(); itSashaSetup++) { if(itSashaSetup->first == suc::instrument_mode) itSashaSetup->second = "UNDEF"; else itSashaSetup->second.clear(); } std::map::const_iterator itSetup; for(itSetup = _dSashaExpose.begin(); itSetup != _dSashaExpose.end(); itSetup++) { U9_LLOG("Keyword : " << itSetup->first << "; Value : " << itSetup->second); if(m_sashaSetup.find(itSetup->first) == m_sashaSetup.end()) { std::stringstream log_msg; log_msg << "Keyword not allowed in sashaExpose : " << itSetup->first; E_LLOG(log_msg.str()); throw(std::invalid_argument(log_msg.str())); } m_sashaSetup[itSetup->first] = itSetup->second; } bool bForceTimeoutRefresh = false; bool ndit_changed = false; std::map incomingSetup = _dSashaExpose; std::map timeoutSetup; timeoutSetup = su::extract_setup(m_timeoutSetup, incomingSetup); for(itSetup = incomingSetup.begin(); itSetup != incomingSetup.end(); itSetup++) { if(m_getFitsAbortFlag)break; if(itSetup->first == "DIT" || itSetup->first == "InstrumentMode") { } else { // U9_LLOG("setup : " << itSetup->first << ":" << itSetup->second); IProperty & prop = m_sashaProps.find(itSetup->first)->second; const std::map elements = prop.getElements(); bool bPropError = false, bSetProperty = false; if(itSetup->first == "SAVE") { bool bSave = true; su::get_bool_from_setup(_dSashaExpose, "SAVE", bSave); std::map::const_iterator itEl; if(elements.find("value") != elements.end()) { indi::IElement::SwitchStateType switch_state = (bSave ? IElement::On : IElement::Off); if(prop["value"].getSwitchState() != switch_state) { prop["value"].setSwitchState(switch_state); // U9_LLOG("Setting : " << "value" << " to " << bSave); bSetProperty = true; } } else bPropError = true; } else if(itSetup->first == "OBJECTNAME") { if(elements.find("value") != elements.end()) { std::string current_name = prop["value"].getValue(); if(current_name != itSetup->second) { prop["value"].setValue(itSetup->second); bSetProperty = true; } } else bPropError = true; } // else if(itSetup->first == "NCOADDS") // { // if(elements.find("num_coadds") != elements.end()) // prop["num_coadds"].setValue(su::convertStringToType(itSetup->second)); // else // bPropError = true; // } else if(itSetup->first == "READOUT") { if(elements.find("value") != elements.end()) { if(prop["value"].getValue() != itSetup->second) { prop["value"].setValue(itSetup->second); bSetProperty = true; } } else bPropError = true; } else { if(elements.find("value") != elements.end()) { // int value = su::convertStringToType(prop["value"].getValue()); if(itSetup->second != prop["value"].getValue()) { if(itSetup->first == "NDIT")ndit_changed = true; prop["value"].setValue(su::convertStringToType(itSetup->second)); bSetProperty = true; } } else bPropError = true; } if(bPropError) { std::stringstream log_msg; log_msg << "Error : IProperty \"" << prop.getDevice() << "." << prop.getName() << "\" from INDI Server has changed"; E_LLOG(log_msg.str()); throw(std::runtime_error(log_msg.str())); } else if(bSetProperty) { m_sashaPropsSet[itSetup->first] = false; SendNewProperty(prop); } } } bool wait_result = false; wait_result = WaitSetMessages(60000000); if(!wait_result)status = EXIT_FAILURE; int status2 = sashaEndSetup(timeoutSetup, ndit_changed); if(status == EXIT_FAILURE || status2 == EXIT_FAILURE)status = EXIT_FAILURE; } catch(...) { m_exposeMutex.unlock(); U8_LLOG(""); throw; } m_exposeMutex.unlock(); U8_LLOG(__FUNCTION__ << " exiting"); return status; } int SeqDataMgr::sashaSetFrequency(const std::map & _dSashaExpose) { U6_LLOG(__FUNCTION__); int status = EXIT_SUCCESS; m_exposeMutex.lock(); try { std::map::const_iterator itSetup; itSetup = _dSashaExpose.find("FREQUENCY"); if(itSetup != _dSashaExpose.end()) { IProperty & prop = m_sashaProps.find(itSetup->first)->second; const std::map elements = prop.getElements(); if(elements.find("value") != elements.end()) { if(prop["value"].getValue() != itSetup->second) { prop["value"].setValue(itSetup->second); m_sashaPropsSet[itSetup->first] = false; SendNewProperty(prop); //camera reinitializes and readout region is reset m_sashaPropsSet["READOUT"] = false; WaitSetMessages(60000000); } } else { U9_LLOG("Error: frequency property from INDI server has changed"); } } } catch(...) { m_exposeMutex.unlock(); U8_LLOG(""); throw; } m_exposeMutex.unlock(); U8_LLOG(__FUNCTION__ << " exiting"); return status; } int SeqDataMgr::sashaExpose2(std::vector & out_files) { U6_LLOG(__FUNCTION__); int status = EXIT_SUCCESS; m_exposeMutex.lock(); m_getFitsAbortFlag = 0; try { m_last_generated_files.clear(); if(m_bSaveOnlyExposedFiles && !m_getFitsAbortFlag) { sashaBlob.setBLOBEnable(IProperty::Also); SendNewProperty(sashaBlob); } bool wait_result = false; wait_result = WaitSetMessages(60000000); if(!m_getFitsAbortFlag) { m_sashaPropsSet["EXPOSE"] = false; sashaExposeProp["value"].setSwitchState(IElement::On); SendNewProperty(sashaExposeProp); m_ExpectedBlobs = su::convertStringToType(sashaNumSeqs["value"].getValue()); m_bInstrumentSetupUpdated = false; updateInstrumentHeader(); wait_result = WaitSetMessages(30000000); } if(!m_getFitsAbortFlag) { wait_result = WaitStartAcquireOff(ExtimateTiming() + 20000); m_bBlobArrived = false; } if(m_bSaveOnlyExposedFiles) { if(m_ExpectedBlobs > 0)WaitBLOB(20000); sashaBlob.setBLOBEnable(IProperty::Never); SendNewProperty(sashaBlob); } if(!wait_result)status = EXIT_FAILURE; if(m_getFitsAbortFlag) { throw(std::runtime_error("Error acquisition aborted by user")); } } catch(...) { m_exposeMutex.unlock(); if(m_getFitsAbortFlag)m_getFitsAbortFlag--; U8_LLOG(""); throw; } if(m_getFitsAbortFlag)m_getFitsAbortFlag--; m_exposeMutex.unlock(); out_files = m_last_generated_files; m_last_generated_file = ""; m_last_generated_files.clear(); U8_LLOG(__FUNCTION__ << " exiting"); return status; } void SeqDataMgr::abortExposure() { m_getFitsAbortFlag = 1; SendNewProperty(sashaStop); } bool SeqDataMgr::WaitSetMessages(int timeout) { bool wait_sets = true; int waited_time = 0; int sleep_time = 1000; std::stringstream log_msg; while(wait_sets) { usleep(sleep_time); waited_time += sleep_time; sleep_time = 49000*(waited_time == 1000) + 50000*(waited_time > 1000); std::map::iterator itSet; for(itSet = m_sashaPropsSet.begin(); itSet != m_sashaPropsSet.end(); itSet++) { if(!itSet->second)break; } wait_sets = itSet != m_sashaPropsSet.end(); if(waited_time >= timeout) { log_msg << __FUNCTION__ << " ~ Timed Out waiting for : "; for(itSet = m_sashaPropsSet.begin(); itSet != m_sashaPropsSet.end(); itSet++) { if(!itSet->second) log_msg << itSet->first << " ~ "; } break; } if(m_bReceivedEof) { U6_LLOG(__FUNCTION__); E_LLOG("Received EOF"); U8_LLOG(""); throw(std::runtime_error("Indi Server signaled EoF")); } if(m_getFitsAbortFlag)break; } if(waited_time > 1000) { U6_LLOG(__FUNCTION__); if(!log_msg.str().empty()){E_LLOG(log_msg.str());}; U8_LLOG(__FUNCTION__ << " ~ Exiting; waited " << waited_time/1000.f << "ms"); } return !wait_sets; } bool SeqDataMgr::WaitStartAcquireOff(unsigned int timeout) { U6_LLOG(__FUNCTION__); bool wait_result = true; unsigned int waited_time = 0; while(wait_result) { usleep(200000); waited_time += 200; wait_result = !(sashaExposeProp["value"].getSwitchState() == IElement::Off); if(waited_time >= timeout) { E_LLOG(__FUNCTION__ << " ~ Timed Out"); break; } if((waited_time % 300000) == 0) { U9_LLOG(__FUNCTION__ << " ~ Waiting " << waited_time/1000.f << "/" << timeout/1000.f << "s"); } if(m_getFitsAbortFlag)break; if(m_bReceivedEof) { E_LLOG("Received EOF"); U8_LLOG(""); throw(std::runtime_error("Indi Server signaled EoF")); } } U8_LLOG(__FUNCTION__ << " ~ Exiting; waited " << waited_time << "ms"); return !wait_result; } bool SeqDataMgr::WaitBLOB(unsigned int timeout) { U6_LLOG(__FUNCTION__); bool wait_result = true; unsigned int waited_time = 0; while(wait_result) { usleep(200000); waited_time += 200; wait_result = !(m_bBlobArrived == true); if(wait_result && waited_time >= timeout) { E_LLOG(__FUNCTION__ << " ~ Timed Out"); break; } if((waited_time % 300000) == 0) { U9_LLOG(__FUNCTION__ << " ~ Waiting " << waited_time/1000.f << "/" << timeout/1000.f << "s"); } if(m_getFitsAbortFlag)break; if(m_bReceivedEof) { E_LLOG("Received EOF"); U8_LLOG(""); throw(std::runtime_error("Indi Server signaled EoF")); } } U8_LLOG(__FUNCTION__ << " ~ Exiting; waited " << waited_time << "ms"); return !wait_result; } // I_LOG("Asking for temperature to sensor"); // IProperty sharknirTemp(IProperty::Text), recvProp; // sharknirTemp.setDevice("sharknir_temp"); // sharknirTemp.setName("sensor"); // sharknirTemp.add(IElement("enable_alarm")); // sharknirTemp.add(IElement("enable_collection")); // sharknirTemp.add(IElement("identifie")); // sharknirTemp.add(IElement("is_connected")); // sharknirTemp.add(IElement("max_value")); // sharknirTemp.add(IElement("min_value")); // sharknirTemp.add(IElement("notify_email_file")); // sharknirTemp.add(IElement("notify_email_list")); // sharknirTemp.add(IElement("tag")); // sharknirTemp.add(IElement("units")); // sharknirTemp.add(IElement("value")); // heater /* IProperty sharknirTempHeater(IndiProperty::Text); sharknirTempHeater.setDevice("sharknir_sensors"); sharknirTempHeater.setName("Heater"); sharknirTempHeater.setPerm(IndiProperty::ReadOnly); sharknirTempHeater.setState(IndiProperty::Busy); sharknirTempHeater.add(IndiElement("command")); sharknirTempHeater.add(IndiElement("enable_collection")); sharknirTempHeater.add(IndiElement("hardware_num")); sharknirTempHeater.add(IndiElement("identifier")); sharknirTempHeater.add(IndiElement("max_power")); sharknirTempHeater.add(IndiElement("power")); sharknirTempHeater.add(IndiElement("last_alarm")); sharknirTempHeater.add(IndiElement("max_value")); sharknirTempHeater.add(IndiElement("min_value")); sharknirTempHeater.add(IndiElement("resp_prefix_size")); sharknirTempHeater.add(IndiElement("setpoint")); sharknirTempHeater.add(IndiElement("simulation_value")); sharknirTempHeater.add(IndiElement("time")); sharknirTempHeater.add(IndiElement("units")); sharknirTempHeater.add(IndiElement("value")); */ void * SeqDataMgr::indi_client_thread(void * pMe) { //usleep(15000000); while(System::isTimeToQuit() == false) { SeqDataMgr & Me = *((SeqDataMgr *)pMe); Me.m_bReceivedEof = false; try { IBase::setupSocketFd(gIndiPort, gIndiAddress); U9_LLOG("Connected to INDI Server"); std::map::iterator itProp; for(itProp = Me.m_sashaProps.begin(); itProp != Me.m_sashaProps.end(); itProp++) { itProp->second.clear(); } std::string id = "identifier"; Me.sharknirTemperatureDetector.add(IElement(id)); Me.sharknirTemperatureDetector[id].setValue("A"); Me.sharknirTemperatureColdFinger.add(IElement(id)); Me.sharknirTemperatureColdFinger[id].setValue("B"); Me.sharknirTemperatureInnerVessel.add(IElement(id)); Me.sharknirTemperatureInnerVessel[id].setValue("C"); Me.sharknirTemperatureOuterVessel.add(IElement(id)); Me.sharknirTemperatureOuterVessel[id].setValue("D"); Me.sashaBlob.setBLOBEnable(IProperty::Never); Me.sashaNumCoadds.add(IElement("value")); Me.sashaNumCoadds["value"].setValue(1); } catch(...) { std::string what = boost::current_exception_diagnostic_information(); std::string toErase = "std::exception::what :"; size_t pos = what.find(toErase); if(pos != std::string::npos)what.erase(pos, toErase.length()); what.erase(std::remove(what.begin(), what.end(), '\n'), what.end()); std::stringstream log_msg; log_msg << "Error trying connection to INDI server : " << what; W_LLOG(log_msg.str()); usleep(300000000); continue; } std::map::iterator itProp; for(itProp = Me.m_sashaProps.begin(); itProp != Me.m_sashaProps.end(); itProp++) { // U9_LLOG("Getting : " << it->second.getDevice() << "." << it->second.getName()); IOut(IMessage::Get) << itProp->second << std::endl; } IIn indiIn; IMessage indiMsgReceive; IProperty ipRecv; std::vector::iterator itVec; while(Me.m_bReceivedEof == false) { if(Me.m_bFlagChanged) { Me.m_bFlagChanged = false; if(Me.m_bSaveOnlyExposedFiles) Me.sashaBlob.setBLOBEnable(IProperty::Never); else Me.sashaBlob.setBLOBEnable(IProperty::Also); IOut(IMessage::EnB) << Me.sashaBlob << std::endl; } if(!Me.m_newProperties.empty()) { Me.m_newPropMutex.lock(); while(!Me.m_newProperties.empty()) { itVec = Me.m_newProperties.begin(); if(itVec->getDevice() == "sasha_save" && itVec->getName() == "save_image") { U9_LLOG("save_image ~ BLOB Enable set to \"" << IProperty::getBLOBEnableString(itVec->getBLOBEnable()) << "\""); IOut(IMessage::EnB) << *itVec << std::endl; } else { IOut(IMessage::New) << *itVec << std::endl; } Me.m_newProperties.erase(itVec); } Me.m_newPropMutex.unlock(); } if(indiIn.isReady(200) == true) { indiIn >> indiMsgReceive; IProperty propReceive = indiMsgReceive.getProperty(); switch(indiMsgReceive.getType()) { case IMessage::Unknown : U9_LLOG(__FUNCTION__ << " ~ Received an Unknown for : \"" << Me.full_property_string(propReceive) << "\""); break; case IMessage::Def : // U9_LLOG(__FUNCTION__ << " ~ Received a DEF for : \"" << Me.full_property_string(propReceive) << "\""); Me.CheckUpdateProperty(propReceive); break; case IMessage::Del : U9_LLOG(__FUNCTION__ << " ~ Received a DEL for : \"" << Me.full_property_string(propReceive) << "\""); break; case IMessage::EnB : U9_LLOG(__FUNCTION__ << " ~ Received a ENB for : \"" << Me.full_property_string(propReceive) << "\""); break; case IMessage::Eof : U9_LLOG(__FUNCTION__ << " ~ Received an EOF for : \"" << Me.full_property_string(propReceive) << "\""); Me.m_bReceivedEof = true; break; case IMessage::Get : U9_LLOG(__FUNCTION__ << " ~ Received a Get for : \"" << Me.full_property_string(propReceive) << "\""); break; case IMessage::Msg : U9_LLOG(__FUNCTION__ << " ~ Received a Msg for : \"" << Me.full_property_string(propReceive) << "\""); break; case IMessage::New : // U9_LLOG(__FUNCTION__ << " ~ Received a NEW for : \"" << Me.full_property_string(propReceive) << "\""); break; case IMessage::Set : if(propReceive.getDevice() != "sharknir_temp" && propReceive.getName() != "sensor") { // U9_LLOG(__FUNCTION__ << " ~ Received a SET for : \"" << Me.full_property_string(propReceive) << "\""); } Me.UpdateProperty(propReceive); break; default: E_LLOG(__FUNCTION__ << " ~ Unexpected INDI message (" << indiMsgReceive.getType() << ") : \"" << Me.full_property_string(propReceive) << "\""); break; } } } usleep(60000000); } W_LLOG(__FUNCTION__ << " ~ Exiting"); return NULL; } unsigned int SeqDataMgr::ExtimateTiming() { int nreads, ngroups, ndrops, ncoadds, nresets, ndit; std::string readout = sashaReadout["value"].getValue(); double frame_time = 4.5f; if(m_sashaTiming.find(readout) != m_sashaTiming.end()) frame_time = m_sashaTiming[readout]; nreads = su::convertStringToType(sashaNumReads["value"].getValue()); ngroups = su::convertStringToType(sashaNumGroups["value"].getValue()); ndrops = su::convertStringToType(sashaNumDrops["value"].getValue()); nresets = su::convertStringToType(sashaNumResets["value"].getValue()); ncoadds = su::convertStringToType(sashaNumCoadds["value"].getValue()); ndit = su::convertStringToType(sashaNumSeqs["value"].getValue()); unsigned int result = 1000*frame_time*ndit*(ngroups*(nreads + ndrops)*ncoadds - ndrops*ncoadds + nresets); // U9_LLOG("ndit : " << ndit << "; nreads : " << nreads << "; ngroups : " << ngroups << "; ndrops : " << ndrops << "; ncoadds : " << ncoadds << "; nresets : " << nresets << "; frame time : " << frame_time << "; result = " << result); return result; } void SeqDataMgr::SendNewProperty(IProperty & prop) { U6_LLOG(__FUNCTION__ << " ~ " << full_property_string(prop)); m_newPropMutex.lock(); // prop.setState(IProperty::Ok); m_newProperties.push_back(prop); m_newPropMutex.unlock(); U8_LLOG(""); } void SeqDataMgr::UpdateProperty(const IProperty & prop) { std::string device = prop.getDevice(); std::string name = prop.getName(); bool prop_updated = false; std::map::iterator it; if(device == "sasha_save" && name == "save_image") { m_bBlobArrived = true; SaveIncomingFile(prop); } else { for(it = m_sashaProps.begin(); it != m_sashaProps.end(); it++) { if(device == it->second.getDevice()) { if(name == it->second.getName()) { prop_updated = true; if(prop.getDevice() == "sharknir_temp" && prop.getName() == "sensor") { std::string id = "identifier"; if(prop.getElements().find(id) != prop.getElements().end()) { if(prop[id].get() == it->second[id].get()) { it->second = prop; // U9_LLOG("Property SET : " << prop.getDevice() << "." << prop.getName() << "." << prop[id].get()); } continue; } } it->second = prop; m_sashaPropsSet[it->first] = true; // We do not log temperatures and pressure // if(prop.getDevice() != "sharknir_temp" && prop.getName() != "sensor" && prop.getDevice() != "sharknir_pres1" && prop.getName() != "sensor") { // U9_LLOG("Property SET : " << prop.getDevice() << "." << prop.getName()); } break; } } } if(!prop_updated) { U9_LLOG("Unrecognized property " << prop.getDevice() << "." << prop.getName() << " received"); } } } void SeqDataMgr::CheckUpdateProperty(const IProperty & prop)// DEF { bool prop_updated = false; std::map::iterator it; for(it = m_sashaProps.begin(); it != m_sashaProps.end(); it++) { if(prop.getDevice() == it->second.getDevice()) { if(prop.getName() == it->second.getName()) { if(prop.getDevice() == "sharknir_temp" && prop.getName() == "sensor") { if(it->second.getElements().size()) { // U9_LLOG(full_property_string(it->second)); // U9_LLOG(full_property_string(prop)); } std::string id = "identifier"; if(prop.getElements().find(id) != prop.getElements().end()) { if(prop[id].get() == it->second[id].get()) { prop_updated = true; if(it->second.getElements().size() == 1) { it->second = prop; U9_LLOG("Property Initialized : " << prop.getDevice() << "." << prop.getName() << "." << prop[id].get()); break; } } else { // U9_LLOG(full_property_string(prop)); continue; } } else { U9_LLOG("Property NOT Initialized : " << full_property_string(prop)); continue; } } else { prop_updated = true; if(it->second.getElements().empty()) { it->second = prop; // it->second.setState(IProperty::Ok); U9_LLOG("Property Initialized : " << full_property_string(prop)); } break; } } } } if(!prop_updated) { U9_LLOG("Unrecognized property \"" << full_property_string(prop) << "\" received"); } } std::string SeqDataMgr::full_property_string(const IProperty &prop) { std::stringstream log_message; log_message << prop.createUniqueKey(); log_message << " : "; std::map::const_iterator it; const std::map & elements = prop.getElements(); switch(prop.getType()) { case IProperty::Text: case IProperty::Number: if(prop.getType() == IProperty::Text) log_message << "IProperty::Text -> "; else log_message << "IProperty::Number -> "; for(it = elements.begin(); it != elements.end(); it++) { if(it->first != "file") { log_message << "Element: '" << it->first << "'; Value : " << it->second.get() << "; "; } else { log_message << "Element: '" << it->first << "'"; } } break; case IProperty::Switch: log_message << "IProperty::Switch -> "; for(it = elements.begin(); it != elements.end(); it++) { if(it->first == "value") { bool isOn = it->second.getSwitchState() == IElement::On; log_message << "Element: '" << it->first << "'; Value : IElement::" << (isOn ? "On" : "Off") << "; "; } else { log_message << "Element: '" << it->first << "'; Value : " << it->second.get() << "; "; } } break; case IProperty::Unknown: log_message << "IProperty::Unknown -> "; for(it = elements.begin(); it != elements.end(); it++) { log_message << "Element: '" << it->first << "'; Value : " << it->second.get() << "; "; } break; case IProperty::Light: log_message << "IProperty::Light -> "; for(it = elements.begin(); it != elements.end(); it++) { log_message << "Ligth Type - Element: \"" << it->first << "\"; Value : \"" << it->second.get() << "\"; "; } break; case IProperty::BLOB: log_message << "IProperty::BLOB -> "; for(it = elements.begin(); it != elements.end(); it++) { log_message << "BLOB Type size : " << prop["file"].getSize() << "; "; } break; } // else { // log_message << "EOF Message"; } return log_message.str(); } void * SeqDataMgr::fit_mem_realloc(void * old_pointer, size_t new_size) { void * pNew = NULL; pNew = realloc(old_pointer, new_size); U9_LLOG(__FUNCTION__ << " ~ " << old_pointer << " -> " << pNew << " ~ " << new_size/2880.f); return pNew; } int SeqDataMgr::UpdateFitFile(fitsfile * pInFit, fitsfile * ptrFits) { char simple_test[84]; *(simple_test + 80) = 0; char string_value[32]; int ref_fit_status = 0; int update_fit_status = 0; int int_value; float float_value; fits_read_key(pInFit, TFLOAT, "BZERO", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == KEY_NO_EXIST || ref_fit_status) { if(ref_fit_status != KEY_NO_EXIST) { U9_LLOG("ref_fit_status = " << ref_fit_status); } ref_fit_status = 0; } else { fits_update_key(ptrFits, TFLOAT, "BZERO ", &float_value, simple_test, &update_fit_status); } fits_read_key(pInFit, TFLOAT, "BSCALE", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == KEY_NO_EXIST) { ref_fit_status = 0; } else { fits_update_key(ptrFits, TFLOAT, "BSCALE ", &float_value, simple_test, &update_fit_status); } fits_read_key(pInFit, TSTRING, "CAMERA", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "CAMERA", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "CAPCOMP", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "CAPCOMP", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "DATE-OBS", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "DTEOBSM", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "DETECTOR", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "DETECTOM", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "EXPMODE", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "EXPMODE", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "EXPTIME", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "EXPTIME", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "FILENAME", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "FILENAME", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "FILTPOLE", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "FILTPOLE", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "FRAME", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "FRAME", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "GAIN", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "GAINM", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "ITIME", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "ITIME", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "NCOADDS", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "NCOADDS", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "NCOADDS", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "NDROPS", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "NDROPS", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "NGROUPS", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "NGROUPS", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "NOUTPUTS", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "NOUTPUTS", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "NRAMPS", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "NRAMPS", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "NREADS", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "NREADS", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "NREADS", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "NRESETS", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "NRESETS", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "OBJNAME", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "OBJNAME", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "RAMPTIM", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "RAMPTIM", &float_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "SUBSECNM", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECNM", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "SUBSECH ", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECH ", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "SUBSECW ", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECW ", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "SUBSECX1 ", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECX1 ", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "SUBSECX2 ", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECX2 ", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "SUBSECY1 ", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECY1 ", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "SUBSECY2 ", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECY2 ", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "SYSSWVER", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SYSSWVER", &string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "TIME-END", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "TIME-END", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TSTRING, "TIME-OBS", string_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "TIME-OBS", string_value, simple_test, &update_fit_status); else ref_fit_status = 0; fits_read_key(pInFit, TFLOAT, "USEREXP", &float_value, simple_test, &ref_fit_status); if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT, "USEREXP", &float_value, simple_test, &update_fit_status); if(update_fit_status) { U9_LLOG("Update Fit Status : " << update_fit_status); LogCfitsioStack(5); } return update_fit_status; } void SeqDataMgr::LogCfitsioStack(int n) { char simple_test[84]; *(simple_test + 80) = 0; for(int i = 0; i < 7; i++) { fits_read_errmsg(simple_test); U9_LLOG(simple_test); } } void SeqDataMgr::SaveIncomingFile(const IProperty & prop) { U6_LLOG(__FUNCTION__); std::string filenameSASHA, filenameSHINS, dateISO8601; if(m_ExpectedBlobs > 0)m_ExpectedBlobs--; fitsfile * ptrFitsFileSASHA = NULL; fitsfile * ptrFitsFileSHINS = NULL; int FitsStatusShins = 0, FitsStatusSasha = 0; // std::vector vecNaxes(4, 0); long naxes[4] = { 36, 40, 1, 1 }; int bitpix = 16, naxis = 2; long naxesSasha[4] = { 36, 40, 1, 1 }; int bitpixSasha = 16, naxisSasha = 4; char simple_test[84]; *(simple_test + 80) = 0; if(prop.find("file")) { if(prop["file"].getSize() > 0.0) { const char * fitsBytes = prop["file"].get().c_str(); size_t blobSize = prop["file"].getSize(); void * pBlobIncoming = malloc(blobSize); if(pBlobIncoming) { int blobLength = from64tobits((char *)pBlobIncoming, fitsBytes); if(blobLength < 0) { free(pBlobIncoming); A_LLOG("Bad base 64 FITS file WILL NOT BE SAVED"); } else { dateISO8601 = prop.getTimeStamp().getFormattedIso8601Str(); su::SetTimeWorkingDirectory(dateISO8601); filenameSHINS = "SHARKNIR." + dateISO8601 + "." + m_sashaSetup[suc::instrument_mode] + ".fits"; filenameSASHA = "SHARKNIR." + dateISO8601 + "." + m_sashaSetup[suc::instrument_mode] + ".SASHA.fits"; if(m_bSaveIncomingBlob) su::debug_save_memory_block((char *)pBlobIncoming, blobSize, filenameSASHA.c_str()); fits_open_memfile(&ptrFitsFileSASHA, "", READONLY, &pBlobIncoming, &blobSize, 0, NULL, &FitsStatusSasha); fits_get_img_param(ptrFitsFileSASHA, 4, &bitpixSasha, &naxisSasha, naxesSasha, &FitsStatusSasha); if(FitsStatusSasha)LogCfitsioStack(5); fits_create_file(&ptrFitsFileSHINS, filenameSHINS.c_str(), &FitsStatusShins); fits_create_img(ptrFitsFileSHINS, bitpix, naxis, naxes, &FitsStatusShins); FitsStatusShins = SetFitsValues(ptrFitsFileSHINS); FitsStatusShins = UpdateFitFile(ptrFitsFileSASHA, ptrFitsFileSHINS); fits_resize_img(ptrFitsFileSHINS, bitpixSasha, naxisSasha, naxesSasha, &FitsStatusShins); fits_copy_data(ptrFitsFileSASHA, ptrFitsFileSHINS, &FitsStatusShins); fits_write_chksum(ptrFitsFileSHINS, &FitsStatusShins); fits_flush_file(ptrFitsFileSHINS, &FitsStatusShins); if(FitsStatusShins)LogCfitsioStack(5); FitsStatusShins = 0; fits_close_file(ptrFitsFileSHINS, &FitsStatusShins); if(FitsStatusShins)LogCfitsioStack(5); fits_close_file(ptrFitsFileSASHA, &FitsStatusSasha); U9_LLOG("Saved fits file " << filenameSHINS); m_last_generated_files.push_back(filenameSHINS); free(pBlobIncoming); } } else { std::stringstream log_msg; log_msg << "Error : could not allocate memory for incoming blob"; E_LLOG(log_msg.str()); U8_LLOG(""); throw std::runtime_error(log_msg.str()); } } } U8_LLOG(""); } void SeqDataMgr::updateInstrumentHeader() { U6_LLOG(__FUNCTION__); SInstrumentHeader & ih = m_instrumentHeader; if(ih.init) { ih.init = false; ih.adc.nameid = suc::ADC1; ih.adc.mechanical_id = 0; ih.apodizer_w.nameid = suc::APODIZER_W; ih.apodizer_w.mechanical_id = 0; ih.cal_fiber_defocus_lamp.nameid = suc::CAL_FIBER_DEFOCUS_LAMP; ih.cal_fiber_defocus_lamp.mechanical_id = 0; ih.cal_fiber_dep.nameid = suc::CAL_FIBER_DEP; ih.cal_fiber_dep.mechanical_id = 0; ih.cal_fiber_focus_lamp.nameid = suc::CAL_FIBER_FOCUS_LAMP; ih.cal_fiber_focus_lamp.mechanical_id = 0; ih.cal_filter_dep.nameid = suc::CAL_FILTER_DEP; ih.cal_filter_dep.mechanical_id = 0; ih.cal_flat_field_lamp.nameid = suc::CAL_FF_LAMP; ih.cal_flat_field_lamp.mechanical_id = 0; ih.cal_mirror_dep.nameid = suc::CAL_MIRROR_DEP; ih.cal_mirror_dep.mechanical_id = 0; ih.coro_slit_w.nameid = suc::CORO_SLIT_W; ih.coro_slit_w.mechanical_id = 0; ih.db_filt_w.nameid = suc::DB_FILT_W; ih.db_filt_w.mechanical_id = 0; ih.derotator.nameid = suc::DEROT; ih.derotator.mechanical_id = 0; ih.inbeam_dep.nameid = suc::INBEAM_DEP; ih.inbeam_dep.mechanical_id = 0; ih.inbeam_tt.nameid = suc::INBEAM_TT; ih.inbeam_tt.mechanical_id = 0; ih.lyot_grism_w.nameid = suc::LYOT_GRISM_W; ih.lyot_grism_w.mechanical_id = 0; ih.nd_filt_w.nameid = suc::ND_FILT_W; ih.nd_filt_w.mechanical_id = 0; ih.pupil_lens_dep.nameid = suc::PUPIL_LENS_DEP; ih.pupil_lens_dep.mechanical_id = 0; ih.sci_filt_w1.nameid = suc::SCI_FILT_W1; ih.sci_filt_w1.mechanical_id = 0; ih.sci_filt_w2.nameid = suc::SCI_FILT_W2; ih.sci_filt_w2.mechanical_id = 0; ih.shutter.nameid = suc::SHUTTER; ih.shutter.mechanical_id = 0; ih.adc_mode.nameid = suc::ADCMode; ih.drot_mode.nameid = suc::DROTMode; ih.mask_comb.nameid = suc::mask_comb; ih.temperature_start = ih.temperature_end = 0.0f; } ih.temperature_end = ih.temperature_start; ih.temperature_start = getMeanTemperature(); const std::map & elementsA = sharknirTemperatureDetector.getElements(); float valueA = 0.f; bool bValueA = false; if(elementsA.find("value") != elementsA.end()) { valueA = elementsA.find("value")->second.get(); bValueA = true; } ih.temperature_start = valueA; if(m_pGetMotorStatus) { m_pGetMotorStatus(ih.apodizer_w); m_pGetMotorStatus(ih.coro_slit_w); m_pGetMotorStatus(ih.lyot_grism_w); m_pGetMotorStatus(ih.nd_filt_w); m_pGetMotorStatus(ih.db_filt_w); m_pGetMotorStatus(ih.sci_filt_w1); m_pGetMotorStatus(ih.sci_filt_w2); m_pGetMotorStatus(ih.inbeam_dep); m_pGetMotorStatus(ih.pupil_lens_dep); ih.pupil_lens_dep.status = ih.pupil_lens_dep.type == "IN"; m_pGetMotorStatus(ih.shutter); ih.shutter.status = ih.shutter.type == "OUT"; m_pGetMotorStatus(ih.inbeam_tt); m_pGetMotorStatus(ih.cal_fiber_dep); m_pGetMotorStatus(ih.cal_mirror_dep); ih.cal_mirror_dep.status = ih.cal_mirror_dep.type == "IN"; m_pGetMotorStatus(ih.cal_filter_dep); m_pGetMotorStatus(ih.derotator); m_pGetMotorStatus(ih.adc); m_pGetMotorStatus(ih.drot_mode); m_pGetMotorStatus(ih.adc_mode); m_pGetMotorStatus(ih.mask_comb); } ih.cal_flat_field_lamp.status = m_obContext.flat_field_lamp == "ON"; ih.cal_flat_field_lamp.type = m_obContext.flat_field_lamp; ih.cal_fiber_focus_lamp.status = m_obContext.focus_lamp == "ON"; ih.cal_fiber_focus_lamp.type = m_obContext.focus_lamp; ih.cal_fiber_defocus_lamp.status = m_obContext.defocus_lamp == "ON"; ih.cal_fiber_defocus_lamp.type = m_obContext.defocus_lamp; if(m_pGetRtcStatus) { for(std::map::iterator itRtc = m_rtcKeywords.begin(); itRtc != m_rtcKeywords.end(); itRtc++) { itRtc->second = m_pGetRtcStatus(itRtc->first); } } if(m_pGetTcsPreset) { m_TcsPreset = m_pGetTcsPreset(); } m_bInstrumentSetupUpdated = true; U8_LLOG(""); } float SeqDataMgr::getMeanTemperature() { const std::map & elementsA = sharknirTemperatureDetector.getElements(); float valueA = 0.f, valueB = 0.f; bool bValueA = false, bValueB = false; if(elementsA.find("value") != elementsA.end()) { valueA = elementsA.find("value")->second.get(); bValueA = true; } const std::map & elementsB = sharknirTemperatureColdFinger.getElements(); if(elementsB.find("value") != elementsB.end()) { valueB = elementsB.find("value")->second.get(); bValueB = true; } float meanTemperature = 0.f; if(bValueA)meanTemperature += valueA; if(bValueB)meanTemperature += valueB; if(bValueA && bValueB)meanTemperature /= 2.f; return meanTemperature; } void dummy() { }