Newer
Older
* seqIDataMgr.cpp
*
* Created on: Mar 18, 2022
* Author: Fulvio Laudisio
*/
#include <pthread.h>
#include <ctime>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#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"),
sashaIntegrationTime(IProperty::Text, "sasha", "int_time"),
sashaExposureTime(IProperty::Text, "sasha", "exp_time"),
sashaEnableCont(IProperty::Switch, "sasha" , "enable_cont" )
{
U6_LLOG(__FUNCTION__);
m_iif = _iif;
SeqDataMgr::m_pSeqDataMgr = this;
su::getValue<double>(m_props->getProperty("Shins.Tracking.Adc.DrotRefAngle"), gDrotRef);
gIndiAddress = m_props->getProperty("Shins.SashaWs.IP");
su::getValue<int>(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<int>(1);
m_sashaProps.insert(std::pair<std::string, IProperty & >("NDIT", sashaNumSeqs));
m_sashaProps.insert(std::pair<std::string, IProperty & >("NDITINDEX", sashaSeqNum));
m_sashaProps.insert(std::pair<std::string, IProperty & >("READOUT", sashaReadout));
m_sashaProps.insert(std::pair<std::string, IProperty & >("READOUTREGION", sashaReadoutRegion));
m_sashaProps.insert(std::pair<std::string, IProperty & >("SAVE", sashaSave));
m_sashaProps.insert(std::pair<std::string, IProperty & >("OBJECTNAME", sashaObjName));
m_sashaProps.insert(std::pair<std::string, IProperty & >("NCOADDS", sashaNumCoadds));
m_sashaProps.insert(std::pair<std::string, IProperty & >("NDROPS", sashaNumDrops));
m_sashaProps.insert(std::pair<std::string, IProperty & >("NGROUPS", sashaNumGroups));
m_sashaProps.insert(std::pair<std::string, IProperty & >("NREADS", sashaNumReads));
m_sashaProps.insert(std::pair<std::string, IProperty & >("NRESETS", sashaNumResets));
m_sashaProps.insert(std::pair<std::string, IProperty & >("EXPOSE", sashaExposeProp));
m_sashaProps.insert(std::pair<std::string, IProperty & >("STOP", sashaStop));
m_sashaProps.insert(std::pair<std::string, IProperty & >("FREQUENCY", sashaFrequencyMode));
m_sashaProps.insert(std::pair<std::string, IProperty & >("CONTINUOUS", sashaEnableCont));
m_sashaProps.insert(std::pair<std::string, IProperty & >("EXPTIME", sashaExposureTime));
m_sashaProps.insert(std::pair<std::string, IProperty & >("INTTIME", sashaIntegrationTime));
m_sashaProps.insert(std::pair<std::string, IProperty & >("LARGESTFILENUM", sashaLargestFileNumber));
m_sashaProps.insert(std::pair<std::string, IProperty & >("SENSORTEMPDET", sharknirTemperatureDetector));
m_sashaProps.insert(std::pair<std::string, IProperty & >("SENSORTEMPCF", sharknirTemperatureColdFinger));
m_sashaProps.insert(std::pair<std::string, IProperty & >("SENSORTEMPIV", sharknirTemperatureInnerVessel));
m_sashaProps.insert(std::pair<std::string, IProperty & >("SENSORTEMPOV", sharknirTemperatureOuterVessel));
m_sashaProps.insert(std::pair<std::string, IProperty & >("SENSORPRES1", sashaPressure));
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_sashaPropsSet["STOP"] = true;
m_sashaPropsSet["CONTINUOUS"] = true;
m_sashaPropsSet["INTTIME"] = true;
m_sashaPropsSet["EXPTIME"] = true;
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;
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("NREADS");
m_timeoutSetup.push_back("NDROPS");
m_timeoutSetup.push_back("NCOADDS");
m_timeoutSetup.push_back("NRESETS");
m_rtcKeywords["TTBIASFILE"] = "";
m_rtcKeywords["TTDMFLATFILE"] = "";
m_rtcKeywords["TTSENSORTEMP"] = "-1000.";
m_rtcKeywords["TTWINCOORDX"] = "";
m_rtcKeywords["TTWINCOORDY"] = "";
m_rtcKeywords["TTWINROWS"] = "";
m_rtcKeywords["TTWINCOLS"] = "";
m_rtcKeywords["TTDMMAXPOWER"] = "";
m_rtcKeywords["TTCENTROIDGAINX"] = "";
m_rtcKeywords["TTCENTROIDGAINY"] = "";
m_rtcKeywords["TTCENTROIDORIGX"] = "";
m_rtcKeywords["TTCENTROIDORIGY"] = "";
m_rtcKeywords["TTDMMODESNUM"] = "";
m_rtcKeywords["TTPIXELGAINFILE"] = "";
m_rtcKeywords["TTPIXELENABLED"] = "";
m_rtcKeywords["TTPIXELDECIMATION"] = "";
m_rtcKeywords["TTDIAGENABLED"] = "";
m_rtcKeywords["TTDIAGDECIMATION"] = "";
pcf::TimeStamp timestamp = pcf::TimeStamp::now();
su::SetTimeWorkingDirectory(timestamp.getFormattedIso8601Str());
}
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;
{
groups = 1;
reads = (int) r;
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)))
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
{
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<std::string, std::string> & _osLampsStatus)
std::map<std::string, std::string>::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());
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());
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());
throw(std::runtime_error(log_msg.str()));
}
}
}
int SeqDataMgr::setContext(const std::map<std::string, std::string> & _osContext)
{
U6_LLOG(__FUNCTION__);
std::map<std::string, std::string>::const_iterator itContext;
bool bOB = false, bTPLID = false, bTPLSCRIPT = false, bTPL = false, bDPR = false;
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;
itContext = _osContext.find("DPR_TYPE");
if(itContext != _osContext.end())
{
m_obContext.dpr_type = itContext->second;
bDPR = true;
}
{
std::stringstream log_msg;
log_msg << "Error : Missing at least one of the mandatory parameters {OB TPL TPLID TPLSCRIPT}";
E_LLOG(log_msg.str());
throw(std::runtime_error(log_msg.str()));
U8_LLOG("");
return EXIT_SUCCESS;
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
}
int SeqDataMgr::sashaExpose(const std::map<std::string, std::string> & _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<std::string> vecFitsKey;
std::vector<std::string> 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<double>(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);
// for(unsigned int i = 1; i<res.resmsg.size(); i++)
// {
// status = datamgrPrintFITS(//vecFitsKey[i-1], res.resmsg[i], vecFitsComment[i-1], IceUtil::None, _c);
// }
// }
#endif
U8_LLOG(__FUNCTION__ << " exiting");
return status;
}
int SeqDataMgr::SetFitsValues(fitsfile *fptr)
{
/* here keywords should be added to SHINS FITS file header.
Copy from ICD document and dtype from
https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node127.html */
char TBD[] = "TBD";
char * strValue = TBD;
int intValue = 0;
float floatValue = 0.f;
float floatValue2 = 1.f;
double lat_d = +32.701309;
double lon_d = -109.889064;
int elevatio = 3221;
char time_string[24];
time_t rawtime;
time(&rawtime);
strftime(time_string, 24, "%Y-%m-%dT%H:%M:%S.000", localtime(&rawtime));
float bzero = 32768.f;
float bscale = 1.f;
int waitUpdateCounter = 0;
while(m_bInstrumentSetupUpdated == false)
{
usleep(20000);
waitUpdateCounter++;
}
U9_LLOG("Waited for instrument update for " << waitUpdateCounter/50.f << " seconds");
intValue = 0;
fits_write_key(fptr, TINT, "NEXTED ", &intValue, "No extension are required", &FitStatus);
fits_write_comment(fptr, "Original MACIE file keys ---------------------------------------------", &FitStatus);
fits_write_key(fptr, TFLOAT, "BZERO ", &bzero, "offset data range to that of unsigned short", &FitStatus);
fits_write_key(fptr, TFLOAT, "BSCALE ", &bscale, "default scaling factor", &FitStatus);
fits_write_key(fptr, TSTRING, "CAMERA ", TBD, "Instrument name", &FitStatus);
fits_write_key(fptr, TFLOAT, "CAPCOMP ", &floatValue, "PreAmp Compensation capacitor (0-63 counts)", &FitStatus);
fits_write_key(fptr, TSTRING, "DTEOBSM", time_string, "Date at end of observation CCYY-MM-DD (UTC)", &FitStatus);
fits_write_key(fptr, TSTRING, "DETECTOM", TBD, "H1RG / H2RG / H4RG", &FitStatus);
fits_write_key(fptr, TSTRING, "EXPMODE ", TBD, "SLOW / FAST", &FitStatus);
fits_write_key(fptr, TFLOAT, "EXPTIME ", &floatValue, "Total Exposure Time, millisec", &FitStatus);
fits_write_key(fptr, TSTRING, "FILENAME ", TBD, "File name", &FitStatus);
fits_write_key(fptr, TFLOAT, "FILTPOLE ", &floatValue, "PreAmp Low Pass filter (0-15 counts)", &FitStatus);
fits_write_key(fptr, TFLOAT, "FRAME ", &floatValue, "One frame time, millisec", &FitStatus);
fits_write_key(fptr, TFLOAT, "GAINM ", &floatValue, "ASIC Preamplifier Gain in db from -3 to 27 in s", &FitStatus);
fits_write_key(fptr, TFLOAT, "ITIME ", &floatValue, "Integration tim, millisecs", &FitStatus);
fits_write_key(fptr, TFLOAT, "NCOADDS ", &floatValue, "Num Coadds", &FitStatus);
fits_write_key(fptr, TFLOAT, "NDROPS ", &floatValue, "Num of Drops per Ramp", &FitStatus);
fits_write_key(fptr, TFLOAT, "NGROUPS ", &floatValue, "Num of Groups per Ramp", &FitStatus);
fits_write_key(fptr, TFLOAT, "NOUTPUTS ", &floatValue, "1,2,4,16,32 for H2G, Number of outputs used for", &FitStatus);
fits_write_key(fptr, TFLOAT, "NRAMPS ", &floatValue, "Num of Ramps to cycle through", &FitStatus);
fits_write_key(fptr, TFLOAT, "NREADS ", &floatValue, "Num of Read frames in each Group of ramp", &FitStatus);
fits_write_key(fptr, TFLOAT, "NRESETS ", &floatValue, "Num of Reset Frames at the beginning of Ramp", &FitStatus);
fits_write_key(fptr, TSTRING, "OBJNAME ", TBD, "Target name", &FitStatus);
fits_write_key(fptr, TFLOAT, "RAMPTIM ", &floatValue, "Ramp time, millisecs", &FitStatus);
fits_write_key(fptr, TSTRING, "SUBSECNM ", TBD, "Readout region name", &FitStatus);
fits_write_key(fptr, TSTRING, "SUBSECH ", TBD, "Readout region height, FITS", &FitStatus);
fits_write_key(fptr, TSTRING, "SUBSECW ", TBD, "Readout region width, FITS", &FitStatus);
fits_write_key(fptr, TSTRING, "SUBSECX1 ", TBD, "Readout region X1, FITS", &FitStatus);
fits_write_key(fptr, TSTRING, "SUBSECX2 ", TBD, "Readout region X2, FITS", &FitStatus);
fits_write_key(fptr, TSTRING, "SUBSECY1 ", TBD, "Readout region Y1, FITS", &FitStatus);
fits_write_key(fptr, TSTRING, "SUBSECY2 ", TBD, "Readout region Y2, FITS", &FitStatus);
fits_write_key(fptr, TSTRING, "SYSSWVER ", TBD, "Software version number", &FitStatus);
fits_write_key(fptr, TSTRING, "TIME-END ", TBD, "Time at end of observation HH:MM:SS:UUU (UTC)", &FitStatus);
fits_write_key(fptr, TSTRING, "TIME-OBS ", TBD, "Time at start of observation HH:MM:SS:UUU (UTC)", &FitStatus);
fits_write_key(fptr, TFLOAT, "USEREXP ", &floatValue, "Requested Exposure Time, millisec", &FitStatus);
fits_write_comment(fptr, "End MACIE file keys --------------------------------------------------", &FitStatus);
// fits_write_history(fptr, "History and comments will be continued over multiple keyword if longer than 70 characters", &FitStatus);
// fits_write_key(fptr, TSTRING, "COMMENT ", strValue, "-----------------", &FitStatus);
fits_write_key(fptr, TSTRING, "TPLNAME ", su::get_char_star(m_obContext.template_name), "Template Name", &FitStatus);
fits_write_key(fptr, TSTRING, "TPLID ", su::get_char_star(m_obContext.template_id), "Template ID", &FitStatus);
fits_write_key(fptr, TSTRING, "TPLSCRIPT", su::get_char_star(m_obContext.template_script), "Template Script", &FitStatus);
fits_write_key(fptr, TSTRING, "OBID ", su::get_char_star(m_obContext.observation_block), "Observation Block Identifier", &FitStatus);
fits_write_key(fptr, TSTRING, "BUNIT ", (char *)"ADU", "Physical Unit of array values, should be ADU", &FitStatus);
// fits_write_key(fptr, TINT, "BLANK ", &blank, "Value used for NULL pixels", &FitStatus);
fits_write_key(fptr, TSTRING, "ORIGIN ", (char *)"MGIO-LBT", "Observatory", &FitStatus);
fits_write_key(fptr, TDOUBLE, "LATITUDE ", &lat_d, "North latitude of LBT (deg; +=North)", &FitStatus);
fits_write_key(fptr, TDOUBLE, "LONGITUD ", &lon_d, "Longitude of LBT (deg; +=East)", &FitStatus);
fits_write_key(fptr, TINT, "ELEVATIO ", &elevatio, "Elevation of LBT above sea level (m)", &FitStatus);
fits_write_key(fptr, TSTRING, "TELESCOP ", (char *)"LBT-SX", "Telescope used", &FitStatus);
fits_write_key(fptr, TLOGICAL,"MASTER ", &boolValue, "Is telescope acting as master", &FitStatus);
fits_write_key(fptr, TSTRING, "INSTRUME ", (char *)"SHARK-NIR", "Instrument used", &FitStatus);
fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus);
fits_write_key(fptr, TSTRING, "OBJECT ", strValue, "Observation title given by observer", &FitStatus);
// fits_write_key(fptr, TSTRING, "OBJNAME ", strValue, "Standard (IAU) object name", &FitStatus);
fits_write_key(fptr, TSTRING, "COMMENT ", strValue, "Observer's comments", &FitStatus);
fits_write_key(fptr, TSTRING, "IMAGETYP ", strValue, "See Table 17 in RD6", &FitStatus);
// fits_write_key(fptr, TFLOAT, "EXPTIME ", &floatValue, "Total integration time (seconds)", &FitStatus);
// su::getValue<float>(m_sashaSetup["DIT"], floatValue);
// fits_write_key(fptr, TFLOAT, "DIT ", &floatValue, "Detector Integration Time (ms)", &FitStatus);
floatValue = 0.f;
su::getValue<float>(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, "<instrume>.<yyyymmdd>.<nnnnn>.[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);
Nice::Date t1 = Nice::Date::now();
U9_LLOG("TCS RA = " << tenv.tcs_ra << " ; TCS DEC = " << tenv.tcs_dec << "; TCS_ALT = " << tenv.mcs_elevation << "; TCS_AZ = " << tenv.mcs_azimuth << "; MCS_EL = " << tenv.mcs_elevation << "; MCS_AZ = " << tenv.mcs_azimuth << "; DeltaT = " << t1 - t0);
fits_write_key(fptr, TSTRING, "RA ", su::get_char_star(tenv.tcs_ra), "'hh:mm:ss.ss' Right ascension (same as TELRA)", &FitStatus);
fits_write_key(fptr, TSTRING, "DEC ", su::get_char_star(tenv.tcs_dec), "'dd:mm:ss.s' Declination (same as DECRA)", &FitStatus);
fits_write_key(fptr, TFLOAT, "AIRMASS ", &tenv.air_mass, "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(tenv.tcs_ra), "'hh:mm:ss.ss' RA at detector center at MJD-OBS", &FitStatus);
fits_write_key(fptr, TSTRING, "TELDEC ", su::get_char_star(tenv.tcs_dec), "'dd:mm:ss.s' DEC at detector center at MJD-OBS", &FitStatus);
fits_write_key(fptr, TFLOAT, "TELALT ", &tenv.mcs_elevation, "'dd.dd' LBT mount altitude at detector center at MJD-OBS", &FitStatus);
fits_write_key(fptr, TFLOAT, "TELAZ ", &tenv.mcs_azimuth, "'ddd.dd. LBT mount azimuth at detector center at MJD-OBS", &FitStatus);
fits_write_key(fptr, TSTRING, "AZTRKSTAT", su::get_char_star(tenv.az_tracking_state), "AZ Tracking status", &FitStatus);
fits_write_key(fptr, TSTRING, "ELTRKSTAT", su::get_char_star(tenv.el_tracking_state), "EL 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 ", &tenv.parallactic_angle, "'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, "HIERARCH TEL MODE", su::get_char_star(m_TcsPreset.telescope_mode), "Telescope Mode", &FitStatus);
fits_write_key(fptr, TSTRING, "HIERARCH TEL AOMODE", su::get_char_star(m_TcsPreset.ao_mode), "Adaptive Optics Mode", &FitStatus);
fits_write_key(fptr, TSTRING, "HIERARCH TEL OBJECTNAME", su::get_char_star(m_TcsPreset.object_name), "Target Object's name", &FitStatus);
fits_write_key(fptr, TSTRING, "HIERARCH TEL COORDINATE SYSTEM",su::get_char_star(m_TcsPreset.target_coordsys), "Target Coordinate system", &FitStatus);
fits_write_key(fptr, TSTRING, "HIERARCH TEL OBJEQUIN", su::get_char_star(m_TcsPreset.equinox), "Target Coordinate System Equinox", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL EPOCH", &m_TcsPreset.epoch, "Epoch", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL OBJRA ", &m_TcsPreset.objra, "Target RA", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL OBJDEC", &m_TcsPreset.objdec, "Target DEC", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL OBJMAG", &m_TcsPreset.objmag, "Target Magnitude", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL PMRA", &m_TcsPreset.pmra, "Target RA Proper Motion", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL PMDEC", &m_TcsPreset.pmdec, "Target DEC Porper Motion", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL AORA", &m_TcsPreset.aora, "Adaptive Optics in RA", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL AODEC", &m_TcsPreset.aodec, "Adaptive Optics in DEC", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL AOMAG", &m_TcsPreset.aomag, "Ref star Magnitude", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL PMAORA", &m_TcsPreset.pmaora, "Proper motion of AO in RA", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL PMAODEC", &m_TcsPreset.pmaodec, "Proper motion of AO in DEC", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL GSRA", &m_TcsPreset.gsra, "Guide Star RA", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL GSDEC", &m_TcsPreset.gsdec, "Guide Star in DEC", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL GSMAG", &m_TcsPreset.gsmag, "Guide Star Magnitude", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL PMGSRA", &m_TcsPreset.pmgsra, "Guide Star proper motion in RA", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL PMGSDEC", &m_TcsPreset.pmgsdec, "Guide Star proper motion in DEC", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL DECOFFSET", &tenv.target_decoffset, "Pointing Offset X", &FitStatus);
fits_write_key(fptr, TFLOAT, "HIERARCH TEL RAOFFSET", &tenv.target_raoffset, "Pointing Offset Y", &FitStatus);
// 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 ", &namps, "Number of amplifiers in the detector", &FitStatus);
fits_write_key(fptr, TFLOAT, "PIXSCAL1 ", &pixscale, "Projected unbinned pixel scale along axis 1", &FitStatus);
fits_write_key(fptr, TFLOAT, "PIXSCAL2 ", &pixscale, "Projected unbinned pixel scale along axis 2", &FitStatus);
fits_write_key(fptr, TFLOAT, "PIXSIZE1 ", &pixsize, "Unbinned det pix size [microns] along Axis 1", &FitStatus);
fits_write_key(fptr, TFLOAT, "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);
std::string u_tem = "deg K";
fits_write_key(fptr, TSTRING, "UCCDTEM ", su::get_char_star(u_tem), "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);
float gain = 1.97;
fits_write_key(fptr, TFLOAT, "GAIN ", &gain, "Detector gain in e-/ADU, erroe = +- 0.02", &FitStatus);
float rdnoise = 181.2;
fits_write_key(fptr, TFLOAT, "RDNOISE ", &rdnoise, "Detector readout noise in e-", &FitStatus);
int saturate = 65535;
fits_write_key(fptr, TINT, "SATURATE ", &saturate, "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);
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
// 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
// su::getValue<float>(m_sashaSetup["DIT"], floatValue);
// fits_write_key(fptr, TFLOAT, "DET DIT", &floatValue, "Detector Integration Time", &FitStatus);
// intValue = su::convertStringToType<int>(sashaNumReads["value"].getValue());
// fits_write_key(fptr, TINT, "DET NREADS", &intValue, "Number of Reads", &FitStatus);
// intValue = su::convertStringToType<int>(sashaNumDrops["value"].getValue());
// fits_write_key(fptr, TINT, "DET NDROPS", &intValue, "Number of Drops", &FitStatus);
// intValue = su::convertStringToType<int>(sashaNumGroups["value"].getValue());
// fits_write_key(fptr, TINT, "DET NGROUPS", &intValue, "Number of Groups", &FitStatus);
// intValue = su::convertStringToType<int>(sashaNumCoadds["value"].getValue());
// fits_write_key(fptr, TINT, "DET NCOADDS", &intValue, "Number of Coadditions", &FitStatus);
// intValue = su::convertStringToType<int>(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<int>(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, "Save Flag on SASHA", &FitStatus);
fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus);
// Table 12 RTC Setup Keywords
intValue = su::convertStringToType<int>(m_rtcKeywords["TTWINCOORDX"]);
fits_write_key(fptr, TINT, "TTWINCOORDX", &intValue, "Distance in rows from px in full frame", &FitStatus);
intValue = su::convertStringToType<int>(m_rtcKeywords["TTWINCOORDY"]);
fits_write_key(fptr, TINT, "TTWINCOORDY", &intValue, "Distance in cols from px in full frame", &FitStatus);
intValue = su::convertStringToType<int>(m_rtcKeywords["TTWINROWS"]);
fits_write_key(fptr, TINT, "TTWINROWS", &intValue, "Tiptilt Window Rows", &FitStatus);
intValue = su::convertStringToType<int>(m_rtcKeywords["TTWINCOLS"]);
fits_write_key(fptr, TINT, "TTWINCOLS", &intValue, "Tiptilt Window Columns", &FitStatus);
intValue = su::convertStringToType<int>(m_rtcKeywords["TTFRAMERATE"]);
fits_write_key(fptr, TINT, "TTFRAMERATE", &intValue, "TipTilt frame rate", &FitStatus);
floatValue = su::convertStringToType<float>(m_rtcKeywords["TTCAMTINT"]);
fits_write_key(fptr, TFLOAT, "TTCAMTINT", &floatValue, "TipTilt Camera integration time", &FitStatus);
// if(m_pGetRtcStatus){ intValue = su::convertStringToType<int>(m_pGetRtcStatus("TTLOOPENABLED"));}
intValue = su::convertStringToType<int>(m_rtcKeywords["TTLOOPENABLED"]);
fits_write_key(fptr, TLOGICAL,"TTLOOPENABLED", &intValue, "Flag indicating fast tip/tilt loop status", &FitStatus);
// fits_write_key(fptr, TLOGICAL,"TTHISTORYENABLED", &intValue, "Number of images save", &FitStatus);
// fits_write_key(fptr, TSTRING, "TTTIMEHISTORYFILE", (char *)"", "Time History Filename", &FitStatus);
// fits_write_key(fptr, TINT, "TTTIMEHISTLEN", &intValue, "Number of history lines if history is enabled", &FitStatus);
floatValue = su::convertStringToType<float>(m_rtcKeywords["TTDMMAXPOWER"]);
fits_write_key(fptr, TFLOAT, "TTDMMAXPOWER", &floatValue, "Max Power allowed to DM", &FitStatus);
fits_write_key(fptr, TSTRING, "TTBIASFILE", su::get_char_star(m_rtcKeywords["TTBIASFILE"]), "Bias File", &FitStatus);
fits_write_key(fptr, TSTRING, "TTDMFLATFILE", su::get_char_star(m_rtcKeywords["TTDMFLATFILE"]), "Flat File", &FitStatus);
if(m_pGetRtcStatus){m_rtcKeywords["TTSENSORTEMP"] = m_pGetRtcStatus("TTSENSORTEMP");}
floatValue = su::convertStringToType<float>(m_rtcKeywords["TTSENSORTEMP"]);
fits_write_key(fptr, TFLOAT, "TTSENSORTEMP", &floatValue, "sensor temperature in degree C", &FitStatus);
floatValue = su::convertStringToType<float>(m_rtcKeywords["TTCENTROIDGAINX"]);
fits_write_key(fptr, TFLOAT, "TTCENTROIDGAINX", &floatValue, "TipTilt gain on centroid X", &FitStatus);
floatValue = su::convertStringToType<float>(m_rtcKeywords["TTCENTROIDGAINY"]);
fits_write_key(fptr, TFLOAT, "TTCENTROIDGAINY", &floatValue, "TipTilt gain on centroid Y", &FitStatus);
floatValue = su::convertStringToType<float>(m_rtcKeywords["TTCENTROIDORIGX"]);
fits_write_key(fptr, TFLOAT, "TTCENTROIDORIGX", &floatValue, "X Origin position in [-1,1] coordinates", &FitStatus);
floatValue = su::convertStringToType<float>(m_rtcKeywords["TTCENTROIDORIGY"]);
fits_write_key(fptr, TFLOAT, "TTCENTROIDORIGY", &floatValue, "Y Origin position in [-1,1] coordinates", &FitStatus);
intValue = su::convertStringToType<int>(m_rtcKeywords["TTDMMODESNUM"]);
fits_write_key(fptr, TINT, "TTDMMODESNUM", &intValue, "number of modes in zonal influence matrix", &FitStatus);
fits_write_key(fptr, TSTRING, "TTPIXELGAINFILE", su::get_char_star(m_rtcKeywords["TTPIXELGAINFILE"]), "Gain factor for each pixel in which the centroid is calculated", &FitStatus);
intValue = su::convertStringToType<int>(m_rtcKeywords["TTPIXELENABLED"]);
fits_write_key(fptr, TLOGICAL,"TTPIXELENABLED", &intValue, "Enable saving frames on memory", &FitStatus);
intValue = su::convertStringToType<int>(m_rtcKeywords["TTPIXELDECIMATION"]);
fits_write_key(fptr, TINT, "TTPIXELDECIMATION", &intValue, "Frame saving decimation factor", &FitStatus);
intValue = su::convertStringToType<int>(m_rtcKeywords["TTDIAGENABLED"]);
fits_write_key(fptr, TLOGICAL,"TTDIAGENABLED", &intValue, "Diagnostic enabled", &FitStatus);
intValue = su::convertStringToType<int>(m_rtcKeywords["TTDIAGDECIMATION"]);
fits_write_key(fptr, TINT, "TTDIAGDECIMATION", &intValue, "TipTilt diagnostic decimation factor", &FitStatus);
fits_write_record(fptr, " ------------------------------------------------------------------------", &FitStatus);