/* * 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; SeqDataMgr::SeqDataMgr(Ltcs::IifServiceWorkerInterfacePtr &_iif): 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"), sashaBlob(IProperty::Unknown, "sasha_save", "save_image"), sashaLargestFileNumber(IProperty::Number, "sasha_save", "largest_filenum"), sashaExposeProp(IProperty::Switch, "sasha", "start_acquire"), sharknirTemperatureA(IProperty::Unknown, "sharknir_temp", "sensor"), sharknirTemperatureB(IProperty::Unknown, "sharknir_temp", "sensor"), sashaStop(IProperty::Switch, "sasha", "stop"), sashaFrequencyMode(IProperty::Text, "sasha", "def_mode_name"), sashaEnableCont(IProperty::Switch, "sasha" , "enable_cont" ) { U6_LLOG(__FUNCTION__); // m_ptrIc = boost::shared_ptr(new indiClient(*_ptrIoService, m_ptrSharedQueue, "127.0.0.1", "7624")); // m_ptrIc2 = boost::shared_ptr(new indiClient2(_ptrIoService, "193.206.241.72", "7624")); // TODO : UNHARDCODE sashaws IP and get it from obs_ctrl-ice.cfg // m_ptrIc2 = boost::shared_ptr(new indiClient2(_ptrIoService, _callback_register, "127.0.0.1", "7624")); // D_LLOG("created pointer to indiClient2 object"); m_iif = _iif; m_ExpectedBlobs = 0; SeqDataMgr::m_pSeqDataMgr = this; // 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("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("SENSORTEMPA", sharknirTemperatureA)); m_sashaProps.insert(std::pair("SENSORTEMPB", sharknirTemperatureB)); m_sashaPropsSet["NDIT"] = true; m_sashaPropsSet["NDITINDEX"] = true; m_sashaPropsSet["READOUT"] = 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; 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_getFitsAbortFlag = 0; m_bReceivingFitsFile = false; m_curInstMode = "GEN"; StartIndiClientThread(); //Flags m_bFlagChanged = true; m_bSaveOnlyExposedFiles = true; m_bSaveIncomingBlob = false; U8_LLOG(""); } 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_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::sashaSetup(const std::map & _dSashaSetup) { U6_LLOG(__FUNCTION__ << " ~ DEPRECATED"); Ice::Int status = EXIT_FAILURE; U8_LLOG(""); return status; } 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...[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(); U9_LLOG("TCS RA = " << tcs_ra << " ; TCS DEC = " << tcs_dec << "; TCS_ALT = " << telalt << "; TCS_AZ = " << telaz); 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); /// TODO : INCLUDE TCS PRESET // 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); 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); res = m_iif->iifGetParameter(dd); float dimm_seeing, dimm_mean_flux, lbt_pressure, lbt_temp, lbt_humidity, lbt_dewpoint; bool lbt_weather_alive; if(res.rescode == EXIT_SUCCESS) { double temp; dimm_seeing = atof(res.resmsg[1].c_str()); dimm_mean_flux = atof(res.resmsg[2].c_str()); lbt_weather_alive = (bool)atoi(res.resmsg[3].c_str()); lbt_pressure = atof(res.resmsg[4].c_str()); lbt_temp = atof(res.resmsg[5].c_str()); lbt_humidity = atof(res.resmsg[6].c_str()); lbt_dewpoint = atof(res.resmsg[7].c_str()); } else { for(unsigned int i = 0; i < res.resmsg.size(); i++) { U9_LLOG(res.resmsg[i]); } } // 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 fits_write_key(fptr, TFLOAT, "DIMMSEEING", &dimm_seeing, "DIMM seeing, [arcsecs]", &FitStatus); fits_write_key(fptr, TFLOAT, "DIMMMEANFLUX", &floatValue, "DIMM mean centroid flux", &FitStatus); fits_write_key(fptr, TLOGICAL, "LBTWEATHERALIVE", &lbt_weather_alive, "Weather Station Link State", &FitStatus); fits_write_key(fptr, TFLOAT, "LBTPRESSURE", &lbt_pressure, "Ambient Pressure [hPa]", &FitStatus); fits_write_key(fptr, TFLOAT, "LBTTEMP", &lbt_temp, "Ambient Temperature [deg C]", &FitStatus); fits_write_key(fptr, TFLOAT, "LBTHUMIDITY", &lbt_humidity, "LBT Relative Humidity [percent]", &FitStatus); fits_write_key(fptr, TFLOAT, "LBTDEWPOINT", &lbt_dewpoint, "LBT Dew Point [deg C]", &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_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, "DETHWV ", strValue, "Detector hardware version", &FitStatus); fits_write_key(fptr, TSTRING, "DETSWV ", strValue, "Detector software version", &FitStatus); fits_write_key(fptr, TSTRING, "DETSTAT ", 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_record(fptr, " ------------------------------------------------------------------------", &FitStatus); fits_write_key(fptr, TFLOAT, "CCDTEM ", &floatValue, "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); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); fits_write_key(fptr, TSTRING, "SPCTYPE1 ", (char*) "WAVE", "Pixel coordinate system ", &FitStatus); fits_write_key(fptr, TSTRING, "SPCTYPE2 ", strValue, "", &FitStatus); fits_write_key(fptr, TSTRING, "SPCTYPE3 ", strValue, "", &FitStatus); fits_write_key(fptr, TSTRING, "SPCUNIT1 ", strValue, "Unit of coordinate transformation", &FitStatus); fits_write_key(fptr, TSTRING, "SPCUNIT2 ", strValue, "Unit of coordinate transformation", &FitStatus); fits_write_key(fptr, TSTRING, "SPCUNIT3 ", strValue, "Unit of coordinate transformation", &FitStatus); fits_write_key(fptr, TFLOAT, "SPCRVAL1 ", &floatValue, "Wavelength at CRPIX1", &FitStatus); fits_write_key(fptr, TFLOAT, "SPCRVAL2 ", &floatValue, "RA at CRPIX1 in units CUNIT1", &FitStatus); fits_write_key(fptr, TFLOAT, "SPCRVAL3 ", &floatValue, "DEC at CRPIX2 in units CUNIT2", &FitStatus); fits_write_key(fptr, TFLOAT, "SPCD1_1 ", &floatValue, "Increment for CTYPE1", &FitStatus); fits_write_key(fptr, TFLOAT, "SPCD2_2 ", &floatValue, "Increment for CTYPE2", &FitStatus); fits_write_key(fptr, TFLOAT, "SPCD3_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 [DISPAXIS/pxl]", &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", strValue, "", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS MECH1 NAME", (char*) "INBEAM_DEP", "", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS MECH1 ID", &intValue, "General mechanical device unique ID", &FitStatus); fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS MECH1 ST", &boolValue, "", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS MECH1 POS", &floatValue, "Position axis [um]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS MECH1 ENC", &intValue, "Position axis [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS MIRR1 NAME", (char*) "INBEAM_TT", "", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS MIRR1 POS1", &floatValue, "Position of axis 1 [um]", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS MIRR1 POS2", &floatValue, "Position of axis 2 [um]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS MIRR1 ENC1", &intValue, "Position of axis 1 [enc]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS MIRR1 ENC2", &intValue, "Position of axis 2 [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS SHUT1 NAME", (char*) "SHUTTER", "", &FitStatus); fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS SHUT1 ST", &boolValue, "T Shutter open", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS SHUT1 POS", &floatValue, "Position of axis [um]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS SHUT1 ENC", &intValue, "Position of axis [enc]", &FitStatus); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS MIRR3 NAME", (char*) "CAL_MIRROR_DEP", "Name of optical element", &FitStatus); fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS MIRR3 ST", &boolValue, "Status of deployable mirror", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS MIRR3 POS", &floatValue, "Position of axis [um]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS MIRR3 ENC", &intValue, "Position of axis [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI4 NAME", (char*) "CAL_FILTER_DEP", "Name of optical element ", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI4 TYPE", (char*) "FILTER", "Name of optical element ", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI4 ID", &intValue, "ID of the element", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS OPTI4 POS", &floatValue, "Position of axis [deg]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI4 ENC", &intValue, "Position of axis [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI5 NAME", (char*) "CAL_FIBER_DEP", "Name of optical element ", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI5 TYPE", (char*) "FIBER", "Name of optical element ", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI5 ID", &intValue, "ID of the element", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS OPTI5 POS", &floatValue, "Position of axis [deg]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI5 ENC", &intValue, "Position of axis [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS SENS1 NAME", (char*) "CAL_FF_LAMP", "Sensor common name for flat field lamp ", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS SENS1 ID", &intValue, "Sensor ID for OPTI5 ", &FitStatus); fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS SENS1 VAL", &boolValue, "T for ON, F for OFF ", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS SENS2 NAME", (char*) "CAL_FIBER_FOCUS_LAMP", "Sensor common name for fiber lamp ", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS SENS2 ID", &intValue, "Sensor ID for OPTI6 ", &FitStatus); fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS SENS2 VAL", &boolValue, "T for ON, F for OFF ", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS SENS3 NAME", (char*) "CAL_FIBER_DEFOCUS_LAMP", "Sensor common name for fiber lamp ", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS SENS3 ID", &intValue, "Sensor ID for OPTI6 ", &FitStatus); fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS SENS3 VAL", &boolValue, "T for ON, F for OFF ", &FitStatus); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS FILT1 NAME", (char*) "ND_FILTER_W", "Name of optical element", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT1 NO", &intValue, "Position of wheel used", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT1 ID", &intValue, "ID of the element", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS FILT1 POS", &floatValue, "Position of axis [deg]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT1 ENC", &intValue, "Position of axis [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS MIRR2 NAME", (char*) "PUPIL_TT", "", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS MIRR2 POS1", &floatValue, "Position of axis 1 [um]", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS MIRR2 POS2", &floatValue, "Position of axis 2 [um]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS MIRR2 ENC1", &intValue, "Position of axis 1 [enc]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS MIRR2 ENC2", &intValue, "Position of axis 2 [enc]", &FitStatus); fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI1 NAME", (char*) "APODIZER_W", "Name of optical element", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI1 TYPE", strValue, "MASK or FREE all elements in OPTI1 are masks", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI1 NO", &intValue, "Position of wheel used", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI1 ID", &intValue, "ID of the element", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS OPTI1 POS", &floatValue, "Position of axis [deg]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI1 ENC", &intValue, "Position of axis [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS ADC NAME", (char*) "ADC", "", &FitStatus); fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS ADC ST", &boolValue, "T when the (sub)system is on, F when off", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS ADC1 POS", &floatValue, "Position of axis 1 [deg]", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS ADC2 POS", &floatValue, "Position of axis 2 [deg]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS ADC1 ENC", &intValue, "Position of axis 1 [enc]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS ADC2 ENC", &intValue, "Position of axis 2 [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI2 NAME", (char*) "CORO_SLIT_W", "Name of optical element", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI2 TYPE", strValue, "MASK or SLIT OR FREE", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI2 NO", &intValue, "Position of wheel used", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI2 ID", &intValue, "ID of the element", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS OPTI2 POS", &floatValue, "Position of axis [deg]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI2 ENC", &intValue, "Position of axis [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI3 NAME", (char*) "LYOT_GRISM_W", "Name of optical element", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS OPTI3 TYPE", strValue, "MASK, SLIT, WOLLASTON, FREE", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI3 NO", &intValue, "Position of wheel used", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI3 ID", &intValue, "ID of the element", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS OPTI3 POS", &floatValue, "Position of axis [deg]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS OPTI3 ENC", &intValue, "Position of axis [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS FILT2 NAME", (char*) "SCI_FILT_W1", "Name of optical element", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT2 NO", &intValue, "Position of wheel used", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT2 ID", &intValue, "ID of the element", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS FILT2 POS", &floatValue, "Position of axis [deg]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT2 ENC", &intValue, "Position of axis [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS FILT3 NAME", (char*) "SCI_FILT_W2", "Name of optical element", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT3 NO", &intValue, "Position of wheel used", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT3 ID", &intValue, "ID of the element", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS FILT3 POS", &floatValue, "Position of axis [deg]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT3 ENC", &intValue, "Position of axis [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS MECH2 NAME", (char*) "PUPIL_LENS_DEP", "", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS MECH2 ID", &intValue, "General mechanical device unique ID", &FitStatus); fits_write_key(fptr, TLOGICAL,"HIERARCH LBT INS MECH2 ST", &boolValue, "", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS MECH2 POS", &floatValue, "Position axis [um]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS MECH2 ENC", &intValue, "Position axis [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS FILT4 NAME", (char*) "DB_FILT_W", "Name of optical element", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT4 NO", &intValue, "Position of wheel used", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT4 ID", &intValue, "ID of the element", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS FILT4 POS", &floatValue, "Position of axis [deg]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS FILT4 ENC", &intValue, "Position of axis [enc]", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS DROT NAME", (char*) "DEROT", "", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS DROT ID", &intValue, "General mechanical device unique ID", &FitStatus); fits_write_key(fptr, TSTRING, "HIERARCH LBT INS DROT MODE", strValue, "Instrument derotator mode", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS DROT POS", &floatValue, "Position axis [deg]", &FitStatus); fits_write_key(fptr, TINT, "HIERARCH LBT INS DROT ENC", &intValue, "Position axis [enc]", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS DROT BEGIN", &floatValue, "Physical position at start [deg]", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS TEMP1 VAL BEGIN", &floatValue, "Cryo-vacuum T [K] at observation start ", &FitStatus); fits_write_key(fptr, TFLOAT, "HIERARCH LBT INS TEMP1 VAL END ", &floatValue, "Cryo-vacuum T [K] at end of observation", &FitStatus); // TODO : Table 10 Instrument setup keyword // TODO : Detector specific keywords // TODO : Table 11 Detector Setup keywords // TODO : Table 12 RTC Setup Keywords fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus); int WCSDIM = 2; fits_write_key(fptr, TINT, "WCSDIM ", &WCSDIM, "Dimensionality of WCS: 2 for image, 3 for spectrum", &FitStatus); if(WCSDIM == 2) { fits_write_key(fptr, TSTRING, "CTYPE1 ", strValue, "Pixel coordinate system", &FitStatus); fits_write_key(fptr, TSTRING, "CTYPE2 ", 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, TFLOAT, "CRPIX1 ", &floatValue, "Value of X Ref. pixel", &FitStatus); fits_write_key(fptr, TFLOAT, "CRPIX2 ", &floatValue, "Value of Y Ref. pixel", &FitStatus); fits_write_key(fptr, TFLOAT, "CRVAL1 ", &floatValue, "RA at CRPIX1 in units CUNIT1", &FitStatus); fits_write_key(fptr, TFLOAT, "CRVAL2 ", &floatValue, "DEC at CRPIX2 in units CUNIT2", &FitStatus); 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); fits_write_key(fptr, TFLOAT, "CD1_1 ", &floatValue, "Scale in [CUNIT1]/pixel", &FitStatus); fits_write_key(fptr, TFLOAT, "CD1_2 ", &floatValue, "Rotation and skew", &FitStatus); fits_write_key(fptr, TFLOAT, "CD2_1 ", &floatValue, "Rotation and skew", &FitStatus); fits_write_key(fptr, TFLOAT, "CD2_2 ", &floatValue, "Scale in [CUNIT2]/pixel", &FitStatus); fits_write_key(fptr, TSTRING, "WAT0_001 ", strValue, "Coordinate system", &FitStatus); fits_write_key(fptr, TSTRING, "WAT1_001 ", strValue, "Coordinate type", &FitStatus); fits_write_key(fptr, TSTRING, "WAT2_001 ", strValue, "Coordinate type", &FitStatus); fits_write_key(fptr, TINT, "WCSSOL ", &intValue, "", &FitStatus); } else if(WCSDIM == 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; } 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; } int SeqDataMgr::sashaSetup2(const std::map & _dSashaExpose) { U6_LLOG(__FUNCTION__); int status = EXIT_SUCCESS; m_exposeMutex.lock(); try { std::vectorallowed_setup; allowed_setup.push_back("InstrumentMode"); allowed_setup.push_back("OBJECTNAME"); allowed_setup.push_back("NGROUPS"); allowed_setup.push_back("NREADS"); allowed_setup.push_back("NDROPS"); allowed_setup.push_back("NCOADDS"); allowed_setup.push_back("NRESETS"); allowed_setup.push_back("NDIT"); allowed_setup.push_back("SAVE"); allowed_setup.push_back("READOUT"); std::map::const_iterator itSetup; for(itSetup = _dSashaExpose.begin(); itSetup != _dSashaExpose.end(); itSetup++) { U9_LLOG("Keyword : " << itSetup->first << "; Value : " << itSetup->second); if(!(std::find(allowed_setup.begin(), allowed_setup.end(), itSetup->first) != allowed_setup.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())); } } for(itSetup = _dSashaExpose.begin(); itSetup != _dSashaExpose.end(); itSetup++) { if(m_getFitsAbortFlag)break; if(itSetup->first == "InstrumentMode") { m_curInstMode = itSetup->second; } 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); 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); 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()) { 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; } 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(); 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()); wait_result = WaitSetMessages(30000000); } if(!m_getFitsAbortFlag) { wait_result = WaitStartAcquireOff(ExtimateTiming() + 20000); m_bBlobArrived = false; } if(m_bSaveOnlyExposedFiles) { if(m_ExpectedBlobs > 0)WaitBLOB(10000); 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) { U6_LLOG(__FUNCTION__); bool wait_sets = true; int waited_time = 0; while(wait_sets) { usleep(200000); waited_time += 200000; 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) { U9_LLOG(__FUNCTION__ << " ~ Timed Out"); break; } if(m_getFitsAbortFlag)break; } 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) { U9_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; } 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) { U9_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; } 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) { bool bReceivedEof = false; SeqDataMgr & Me = *((SeqDataMgr *)pMe); try { IBase::setupSocketFd(7624, "192.168.61.115"); U9_LLOG("Connected to INDI Server"); } 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(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 ~ Enable Sent"); 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) << "\""); 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) { U9_LLOG(__FUNCTION__ << " ~ " << full_property_string(prop)); m_newPropMutex.lock(); // prop.setState(IProperty::Ok); m_newProperties.push_back(prop); m_newPropMutex.unlock(); } 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") { if(prop.getElements().find("identifier") != prop.getElements().end()) { if(prop["identifier"].get() != su::right(it->first, 1))continue; } } it->second = prop; m_sashaPropsSet[it->first] = true; if(prop.getDevice() != "sharknir_temp" && prop.getName() != "sensor") { U9_LLOG("Property SET : " << prop.getDevice() << "." << prop.getName()); } } } } 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()) { prop_updated = true; if(it->second.getElements().empty()) { if(prop.getDevice() == "sharknir_temp" && prop.getName() == "sensor") { if(prop.getElements().find("identifier") != prop.getElements().end()) { if(prop["identifier"].get() != su::right(it->first, 1))continue; } } it->second = prop; // it->second.setState(IProperty::Ok); U9_LLOG("Property Initialized : " << full_property_string(prop)); } } } } if(!prop_updated) { U9_LLOG("Unrecognized property " << prop.getDevice() << "." << prop.getName() << " 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: 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: 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: for(it = elements.begin(); it != elements.end(); it++) { log_message << "Unknown - Element: '" << it->first << "'; Value : " << it->second.get() << "; "; } break; case 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: 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, "EXPTIMEM", &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, "ITIMEM", &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, "NCOADDSM", &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, "NREADSM", &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, "OBJNAMEM", 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_curInstMode + ".fits"; filenameSASHA = "SHARKNIR." + dateISO8601 + "." + m_curInstMode + ".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 dummy() { }