Skip to content
seqIDataMgr.cpp 159 KiB
Newer Older
    while(wait_result)
    {
        usleep(200000);
        waited_time += 200;
        wait_result = !(m_bBlobArrived == true);
        if(wait_result && waited_time >= timeout)
        {
            E_LLOG(__FUNCTION__ << " ~ Timed Out");
            break;
        }
        if((waited_time % 300000) == 0)
        {
            U9_LLOG(__FUNCTION__ << " ~ Waiting " << waited_time/1000.f << "/" << timeout/1000.f << "s");
        }
        if(m_getFitsAbortFlag)break;
        if(m_bReceivedEof)
        {
            E_LLOG("Received EOF");
            U8_LLOG("");
            throw(std::runtime_error("Indi Server signaled EoF"));
        }
    }
    U8_LLOG(__FUNCTION__ << " ~ Exiting; waited " << waited_time << "ms");
    return !wait_result;
}
  // I_LOG("Asking for temperature to sensor");
  // IProperty sharknirTemp(IProperty::Text), recvProp;
  // sharknirTemp.setDevice("sharknir_temp");
  // sharknirTemp.setName("sensor");
  // sharknirTemp.add(IElement("enable_alarm"));
  // sharknirTemp.add(IElement("enable_collection"));
  // sharknirTemp.add(IElement("identifie"));
  // sharknirTemp.add(IElement("is_connected"));
  // sharknirTemp.add(IElement("max_value"));
  // sharknirTemp.add(IElement("min_value"));
  // sharknirTemp.add(IElement("notify_email_file"));
  // sharknirTemp.add(IElement("notify_email_list"));
  // sharknirTemp.add(IElement("tag"));
  // sharknirTemp.add(IElement("units"));
  // sharknirTemp.add(IElement("value"));
  // heater
  /*
  IProperty sharknirTempHeater(IndiProperty::Text);
  sharknirTempHeater.setDevice("sharknir_sensors");
  sharknirTempHeater.setName("Heater");
  sharknirTempHeater.setPerm(IndiProperty::ReadOnly);
  sharknirTempHeater.setState(IndiProperty::Busy);
  sharknirTempHeater.add(IndiElement("command"));
  sharknirTempHeater.add(IndiElement("enable_collection"));
  sharknirTempHeater.add(IndiElement("hardware_num"));
  sharknirTempHeater.add(IndiElement("identifier"));
  sharknirTempHeater.add(IndiElement("max_power"));
  sharknirTempHeater.add(IndiElement("power"));
  sharknirTempHeater.add(IndiElement("last_alarm"));
  sharknirTempHeater.add(IndiElement("max_value"));
  sharknirTempHeater.add(IndiElement("min_value"));
  sharknirTempHeater.add(IndiElement("resp_prefix_size"));
  sharknirTempHeater.add(IndiElement("setpoint"));
  sharknirTempHeater.add(IndiElement("simulation_value"));
  sharknirTempHeater.add(IndiElement("time"));
  sharknirTempHeater.add(IndiElement("units"));
  sharknirTempHeater.add(IndiElement("value"));
  */


void * SeqDataMgr::indi_client_thread(void * pMe)
{
    //usleep(15000000);
    while(System::isTimeToQuit() == false)
    {
        SeqDataMgr & Me = *((SeqDataMgr *)pMe);
            IBase::setupSocketFd(gIndiPort, gIndiAddress);
            U9_LLOG("Connected to INDI Server");
            std::map<std::string, IProperty &>::iterator itProp;
            for(itProp = Me.m_sashaProps.begin(); itProp != Me.m_sashaProps.end(); itProp++)
            {
                itProp->second.clear();
            }
            std::string id = "identifier";
            Me.sharknirTemperatureDetector.add(IElement(id));
            Me.sharknirTemperatureDetector[id].setValue<std::string>("A");
            Me.sharknirTemperatureColdFinger.add(IElement(id));
            Me.sharknirTemperatureColdFinger[id].setValue<std::string>("B");
            Me.sharknirTemperatureInnerVessel.add(IElement(id));
            Me.sharknirTemperatureInnerVessel[id].setValue<std::string>("C");
            Me.sharknirTemperatureOuterVessel.add(IElement(id));
            Me.sharknirTemperatureOuterVessel[id].setValue<std::string>("D");
            Me.sashaBlob.setBLOBEnable(IProperty::Never);
            Me.sashaNumCoadds.add(IElement("value"));
            Me.sashaNumCoadds["value"].setValue<int>(1);
Fulvio Laudisio's avatar
Fulvio Laudisio committed
            Me.m_bFlagChanged = true;
        }
        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());
Fulvio Laudisio's avatar
Fulvio Laudisio committed
            usleep(60000000);
            continue;
        }
        std::map<std::string, IProperty &>::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<IProperty>::iterator itVec;
        while(Me.m_bReceivedEof == false)
        {
            if(Me.m_bFlagChanged)
            {
                Me.m_bFlagChanged = false;
                if(Me.m_bSaveOnlyExposedFiles)
                    Me.sashaBlob.setBLOBEnable(IProperty::Never);
                else
                    Me.sashaBlob.setBLOBEnable(IProperty::Also);
                IOut(IMessage::EnB) << Me.sashaBlob << std::endl;

            }
            if(!Me.m_newProperties.empty())
            {
                Me.m_newPropMutex.lock();
                while(!Me.m_newProperties.empty())
                {
                    itVec = Me.m_newProperties.begin();
                    if(itVec->getDevice() == "sasha_save" && itVec->getName() == "save_image")
                    {
Davide Ricci's avatar
Davide Ricci committed
                        U9_LLOG("save_image ~ BLOB  Enable set to \"" << IProperty::getBLOBEnableString(itVec->getBLOBEnable()) << "\"");
                        IOut(IMessage::EnB) << *itVec << std::endl;
                    }
                    else
                    {
                        IOut(IMessage::New) << *itVec << std::endl;
                    }
                    Me.m_newProperties.erase(itVec);
                }
                Me.m_newPropMutex.unlock();
            }
            if(indiIn.isReady(200) == true)
            {
                indiIn >> indiMsgReceive;
                IProperty propReceive = indiMsgReceive.getProperty();
                switch(indiMsgReceive.getType())
                {
                case IMessage::Unknown :
                    U9_LLOG(__FUNCTION__ << " ~ Received an Unknown for : \"" << Me.full_property_string(propReceive) << "\"");
                    break;
                case IMessage::Def :
//                    U9_LLOG(__FUNCTION__ << " ~ Received a DEF for : \"" << Me.full_property_string(propReceive) << "\"");
                    Me.CheckUpdateProperty(propReceive);
                    break;
                case IMessage::Del :
                    U9_LLOG(__FUNCTION__ << " ~ Received a DEL for : \"" << Me.full_property_string(propReceive) << "\"");
                    break;
                case IMessage::EnB :
                    U9_LLOG(__FUNCTION__ << " ~ Received a ENB for : \"" << Me.full_property_string(propReceive) << "\"");
                    break;
                case IMessage::Eof :
                    U9_LLOG(__FUNCTION__ << " ~ Received an EOF for : \"" << Me.full_property_string(propReceive) << "\"");
                    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 :
Davide Ricci's avatar
Davide Ricci committed
//                    U9_LLOG(__FUNCTION__ << " ~ Received a NEW for : \"" << Me.full_property_string(propReceive) << "\"");
                    break;
                case IMessage::Set :
Fulvio Laudisio's avatar
Fulvio Laudisio committed
                    if((propReceive.getDevice() != "sharknir_temp" && propReceive.getName() != "sensor") &&
                        propReceive.getDevice() != "lbto_iif" && propReceive.getName() != "status")
Fulvio Laudisio's avatar
Fulvio Laudisio committed
                        // Enable to echo received properties
Fulvio Laudisio's avatar
Fulvio Laudisio committed
                        if(propReceive.getDevice() == "sasha" && propReceive.getName() == "seq_num")
                        {
                            U9_LLOG(__FUNCTION__ << " ~ Received a SET for : \"" << Me.full_property_string(propReceive) << "\"");
                        }
                        else
                        {
                            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::estimateTiming()
Fulvio Laudisio's avatar
Fulvio Laudisio committed
    int nreads, ngroups, ndrops, ncoadds, nresets, ndit, frame_size, frame_delay;
    std::string readout = sashaReadout["value"].getValue();
Fulvio Laudisio's avatar
Fulvio Laudisio committed
    double frame_time = 4.5f, size;
    if(m_sashaTiming.find(readout) != m_sashaTiming.end())
        frame_time = m_sashaTiming[readout];
Fulvio Laudisio's avatar
Fulvio Laudisio committed
    else
    {
        W_LLOG("Could not find readout reagion " << readout << ". Please Update");
    }
    nreads = su::convertStringToType<int>(sashaNumReads["value"].getValue());
    ngroups = su::convertStringToType<int>(sashaNumGroups["value"].getValue());
    ndrops = su::convertStringToType<int>(sashaNumDrops["value"].getValue());
    nresets = su::convertStringToType<int>(sashaNumResets["value"].getValue());
    ncoadds = su::convertStringToType<int>(sashaNumCoadds["value"].getValue());
    ndit = su::convertStringToType<int>(sashaNumSeqs["value"].getValue());
    int ncoadds2 = su::convertStringToType<int>(sashaAcquire["num_coadds"].getValue());
    if(ncoadds2 != ncoadds)
    {
        W_LLOG("sasha.acquire.num_coadds differs from sasha.num_coadds");
    }
Fulvio Laudisio's avatar
Fulvio Laudisio committed
    if(m_sashaSizes.find(readout) != m_sashaSizes.end())
    {
        frame_size = m_sashaSizes[readout];
    }
    else
    {
        frame_size = 2048*2048*2;
    }
    size = ngroups*nreads*frame_size;
    frame_delay = 30*((int)((size + 999999)/1000000)); // ~ 30 ms per MB
    unsigned int result1 = 1000*frame_time*ndit*(ngroups*(nreads + ndrops)*ncoadds - ndrops*ncoadds + nresets);
    unsigned int result2 = ndit*frame_delay;
    unsigned int result = 1000*frame_time*ndit*(ngroups*(nreads + ndrops)*ncoadds - ndrops*ncoadds + nresets) + ndit*frame_delay + 1000*ndit + 5000;
Fulvio Laudisio's avatar
Fulvio Laudisio committed
    U9_LLOG("ndit : " << ndit << "; nreads : " << nreads << "; ngroups : " << ngroups << "; ndrops : " << ndrops << "; ncoadds : " << ncoadds << "; nresets : " << nresets << "; frame time : " << frame_time << "; frame_size : " << frame_size << "; size : " << size << "; results = {" << result1 << ", " << result2 << ", " << result << "}");
    return m_timoeout_multiplier*result;
unsigned int SeqDataMgr::estimateBlobDelivery()
{
    int nreads, ngroups, ndrops, ncoadds, nresets, ndit, frame_size, frame_delay;
    std::string readout = sashaReadout["value"].getValue();
    double frame_time = 4.5f, size;
    if(m_sashaTiming.find(readout) != m_sashaTiming.end())
        frame_time = m_sashaTiming[readout];
    else
    {
        W_LLOG("Could not find readout reagion " << readout << ". Please Update");
    }
    nreads = su::convertStringToType<int>(sashaNumReads["value"].getValue());
    ngroups = su::convertStringToType<int>(sashaNumGroups["value"].getValue());
    ndrops = su::convertStringToType<int>(sashaNumDrops["value"].getValue());
    nresets = su::convertStringToType<int>(sashaNumResets["value"].getValue());
    ncoadds = su::convertStringToType<int>(sashaNumCoadds["value"].getValue());
    ndit = su::convertStringToType<int>(sashaNumSeqs["value"].getValue());
    int ncoadds2 = su::convertStringToType<int>(sashaAcquire["num_coadds"].getValue());
    if(ncoadds2 != ncoadds)
    {
        // ncoadds = ncoadds2;
        W_LLOG("sasha.acquire.num_coadds differs from sasha.num_coadds");
    }
    if(m_sashaSizes.find(readout) != m_sashaSizes.end())
    {
        frame_size = m_sashaSizes[readout];
    }
    else
    {
        frame_size = 2048*2048*2;
    }
    size = ngroups*nreads*frame_size;
    frame_delay = 5000 + 70*((int)((size + 999999)/1000000)); // ~ 70 ms per MB
    unsigned int result = 1000*frame_time*ndit*(ngroups*(nreads + ndrops)*ncoadds - ndrops*ncoadds + nresets) + ndit*frame_delay + 1000*ndit;
    U9_LLOG("ndit : " << ndit << "; nreads : " << nreads << "; ngroups : " << ngroups << "; ndrops : " << ndrops << "; ncoadds : " << ncoadds << "; nresets : " << nresets << "; frame time : " << frame_time << "; frame_size : " << frame_size << "; size : " << size << "; frame_delay : " << frame_delay);
    return (unsigned int)frame_delay;

}


void SeqDataMgr::SendNewProperty(IProperty & prop)
{
Davide Ricci's avatar
Davide Ricci committed
    U6_LLOG(__FUNCTION__ << " ~ " << full_property_string(prop));
    m_newPropMutex.lock();
//    prop.setState(IProperty::Ok);
    m_newProperties.push_back(prop);
    m_newPropMutex.unlock();
Davide Ricci's avatar
Davide Ricci committed
    U8_LLOG("");
}


void SeqDataMgr::UpdateProperty(const IProperty & prop)
{
    std::string device = prop.getDevice();
    std::string name = prop.getName();
    bool prop_updated = false;
    std::map<std::string, IProperty &>::iterator it;
    if(device == "sasha_save" && name == "save_image")
    {
        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.getDevice() == "sharknir_pres1") && prop.getName() == "sensor")
                        std::string id = "identifier";
                        if(prop.getElements().find(id) != prop.getElements().end())
                            if(prop[id].get() == it->second[id].get())
                            {
                                it->second = prop;
//                                U9_LLOG("Property SET : " << prop.getDevice() << "." << prop.getName() << "." << prop[id].get());
                            }
                            continue;
                    if(prop.getDevice() == "sharknir_pres1" && prop.getName() == "sensor")
                    {
                        std::string id = "value";
                        if(prop.getElements().find(id) != prop.getElements().end())
                        {
                            continue;
                        }
                    }
                    if(prop.getDevice() == "lbto_iif" && prop.getName() == "status")
                    {
                        std::string id = "l_inst_auth";
                        if(prop.getElements().find(id) != prop.getElements().end())
                        {
Fulvio Laudisio's avatar
Fulvio Laudisio committed
                            if(prop[id].get() != it->second[id].get())
                            {
                                it->second = prop;
                                U9_LLOG("Property SET : " << prop.getDevice() << "." << prop.getName() << "." << id << " = " << prop[id].get());
                            }
                            continue;
                        }
                    }
                    it->second = prop;
                    m_sashaPropsSet[it->first] = true;
sharknirws2's avatar
sharknirws2 committed
                    // We do not log temperatures and pressure
Davide Ricci's avatar
Davide Ricci committed
//                    if(prop.getDevice() != "sharknir_temp" && prop.getName() != "sensor" && prop.getDevice() != "sharknir_pres1" && prop.getName() != "sensor")
Davide Ricci's avatar
Davide Ricci committed
//                        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<std::string, IProperty &>::iterator it;
    for(it = m_sashaProps.begin(); it != m_sashaProps.end(); it++)
    {
        if(prop.getDevice() == it->second.getDevice())
        {
            if(prop.getName() == it->second.getName())
            {
                if(prop.getDevice() == "sharknir_temp" && prop.getName() == "sensor")
                    if(it->second.getElements().size())
//                        U9_LLOG(full_property_string(it->second));
//                        U9_LLOG(full_property_string(prop));
                    }
                    std::string id = "identifier";
                    if(prop.getElements().find(id) != prop.getElements().end())
                    {
                        if(prop[id].get() == it->second[id].get())
                        {
                            prop_updated = true;
                            if(it->second.getElements().size() == 1)
                            {
                                it->second = prop;
                                U9_LLOG("Property Initialized : " << prop.getDevice() << "." << prop.getName() << "." << prop[id].get());
                                break;
                            }
                        }
                        else
//                            U9_LLOG(full_property_string(prop));
                            continue;
                    else
                    {
                        U9_LLOG("Property NOT Initialized : " << full_property_string(prop));
                        continue;
                    }
                }
                if(prop.getDevice() == "lbto_iif" && prop.getName() == "status")
                {
                    std::string id = "l_inst_auth";
                    prop_updated = true;
                    if(prop.getElements().find(id) != prop.getElements().end())
                    {
                        if( it->second.getElements().empty() )
                        {
                            it->second = prop;
                            U9_LLOG("Property Initialized : " << prop.getDevice() << "." << prop.getName() << "." << id << " = " << prop[id].get());
                        }
                        continue;
                    }
                }
                else
                {
                    prop_updated = true;
                    if(it->second.getElements().empty())
                    {
                        it->second = prop;
    //                    it->second.setState(IProperty::Ok);
                        U9_LLOG("Property Initialized : " << full_property_string(prop));
                    }
                    break;
        U9_LLOG("Unrecognized property \"" << full_property_string(prop) << "\" received");
    }
}

std::string SeqDataMgr::full_property_string(const IProperty &prop)
{
    std::stringstream log_message;
    log_message << prop.createUniqueKey();
    log_message << " : ";
    std::map<std::string, indi::IElement>::const_iterator it;
    const std::map<std::string, indi::IElement> & elements = prop.getElements();
    switch(prop.getType())
    {
        case IProperty::Text:
        case IProperty::Number:
Davide Ricci's avatar
Davide Ricci committed
            if(prop.getType() == IProperty::Text)
                log_message << "IProperty::Text -> ";
            else
                log_message << "IProperty::Number -> ";
            for(it = elements.begin(); it != elements.end(); it++)
            {
                if(it->first != "file")
                {
                    log_message << "Element: '" << it->first << "'; Value : " << it->second.get() << "; ";
                }
                else
                {
                    log_message << "Element: '" << it->first << "'";
                }
            }
            break;
        case IProperty::Switch:
            log_message << "IProperty::Switch -> ";
            for(it = elements.begin(); it != elements.end(); it++)
            {
                if(it->first == "value")
                {
                    bool isOn = it->second.getSwitchState() == IElement::On;
                    log_message << "Element: '" << it->first << "'; Value : IElement::" << (isOn ?  "On" : "Off") << "; ";
                }
                else
                {
                    log_message << "Element: '" << it->first << "'; Value : " << it->second.get() << "; ";
                }
            }
            break;
        case IProperty::Unknown:
            log_message << "IProperty::Unknown -> ";
            for(it = elements.begin(); it != elements.end(); it++)
            {
                log_message << "Element: '" << it->first << "'; Value : " << it->second.get() << "; ";
            log_message << "IProperty::Light -> ";
            for(it = elements.begin(); it != elements.end(); it++)
            {
                log_message << "Ligth Type - Element: \"" << it->first << "\"; Value : \"" << it->second.get() << "\"; ";
            }
            break;
        case IProperty::BLOB:
            log_message << "IProperty::BLOB -> ";
            for(it = elements.begin(); it != elements.end(); it++)
            {
                log_message << "BLOB Type size : " << prop["file"].getSize<unsigned int>() << "; ";
            }
            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, TSTRING, "LST-OBS", string_value, simple_test, &ref_fit_status);
    // if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "LST-OBS", string_value, simple_test, &update_fit_status);
    // else {W_LLOG("Could not find key " << "LST-OBS" ); ref_fit_status = 0; }
Fulvio Laudisio's avatar
Fulvio Laudisio committed
    fits_read_key(pInFit, TSTRING, "PARAANG", string_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "PARAANG", 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);
Davide Ricci's avatar
Davide Ricci committed
    if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT,  "EXPTIME", &float_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TSTRING, "FILENAME", string_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "FILENAME", string_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TFLOAT,  "FILTPOLE", &float_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT,  "FILTPOLE", &float_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TFLOAT,  "FRAME", &float_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT,  "FRAME", &float_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TFLOAT,  "GAIN", &float_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT,  "GAINM", &float_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TFLOAT,  "ITIME", &float_value, simple_test, &ref_fit_status);
Davide Ricci's avatar
Davide Ricci committed
    if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT,  "ITIME", &float_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TFLOAT,  "NCOADDS", &float_value, simple_test, &ref_fit_status);
Davide Ricci's avatar
Davide Ricci committed
    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);
Davide Ricci's avatar
Davide Ricci committed
    if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT,  "NREADS", &float_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT,  "NREADS", &float_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TFLOAT,  "NRESETS", &float_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT,  "NRESETS", &float_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TSTRING, "OBJNAME", string_value, simple_test, &ref_fit_status);
Davide Ricci's avatar
Davide Ricci committed
    if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "OBJNAME", string_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TFLOAT,  "RAMPTIM", &float_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TFLOAT,  "RAMPTIM", &float_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TSTRING, "SUBSECNM", string_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECNM", string_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TSTRING, "SUBSECH  ", string_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECH  ", string_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TSTRING, "SUBSECW  ", string_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECW  ", string_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TSTRING, "SUBSECX1 ", string_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECX1 ", string_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TSTRING, "SUBSECX2 ", string_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECX2 ", string_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TSTRING, "SUBSECY1 ", string_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECY1 ", string_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TSTRING, "SUBSECY2 ", string_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SUBSECY2 ", string_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TSTRING, "SYSSWVER", string_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "SYSSWVER", &string_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TSTRING, "TIME-END", string_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0)fits_update_key(ptrFits, TSTRING, "TIME-END", string_value, simple_test, &update_fit_status);
    else ref_fit_status = 0;
    fits_read_key(pInFit, TSTRING, "TIME-OBS", string_value, simple_test, &ref_fit_status);
    if(ref_fit_status == 0){
        fits_update_key(ptrFits, TSTRING, "TIME-OBS", string_value, simple_test, &update_fit_status);
        fits_update_key(ptrFits, TSTRING, "UTC-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<long> 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<float>() > 0.0)
        {
            const char * fitsBytes = prop["file"].get().c_str();
            size_t blobSize = prop["file"].getSize<unsigned int>();
            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);
Fulvio Laudisio's avatar
Fulvio Laudisio committed
                    filenameSHINS = "SHARKNIR." + dateISO8601 + "." + m_sashaSetup[suc::InstrumentMode] + ".fits";
Fulvio Laudisio's avatar
Fulvio Laudisio committed
                    m_last_generated_file = filenameSHINS;
Fulvio Laudisio's avatar
Fulvio Laudisio committed
                    filenameSASHA = "SHARKNIR." + dateISO8601 + "." + m_sashaSetup[suc::InstrumentMode] + ".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());
            }
        }
    }
void SeqDataMgr::updateInstrumentHeader()
{
    U6_LLOG(__FUNCTION__);
    SInstrumentHeader & ih = m_instrumentHeader;
Fulvio Laudisio's avatar
Fulvio Laudisio committed
    static Nice::Date lastCall;
    Nice::Date currentCall = Nice::Date::now();
    if(currentCall - lastCall < Nice::Time::seconds(5))return;
    if(ih.init)
    {
        ih.init = false;
        
        ih.adc.nameid = suc::ADC1;
        ih.adc.mechanical_id = 0;

        ih.apodizer_w.nameid = suc::APODIZER_W;
        ih.apodizer_w.mechanical_id = 0;

        ih.cal_fiber_defocus_lamp.nameid = suc::CAL_FIBER_DEFOCUS_LAMP;
        ih.cal_fiber_defocus_lamp.mechanical_id = 0;

        ih.cal_fiber_dep.nameid = suc::CAL_FIBER_DEP;
        ih.cal_fiber_dep.mechanical_id = 0;
        
        ih.cal_fiber_focus_lamp.nameid = suc::CAL_FIBER_FOCUS_LAMP;
        ih.cal_fiber_focus_lamp.mechanical_id = 0;

        ih.cal_filter_dep.nameid = suc::CAL_FILTER_DEP;
        ih.cal_filter_dep.mechanical_id = 0;

        ih.cal_flat_field_lamp.nameid = suc::CAL_FF_LAMP;
        ih.cal_flat_field_lamp.mechanical_id = 0;

        ih.cal_mirror_dep.nameid = suc::CAL_MIRROR_DEP;
        ih.cal_mirror_dep.mechanical_id = 0;

        ih.coro_slit_w.nameid = suc::CORO_SLIT_W;
        ih.coro_slit_w.mechanical_id = 0;

        ih.db_filt_w.nameid = suc::DB_FILT_W;
        ih.db_filt_w.mechanical_id = 0;

Fulvio Laudisio's avatar
Fulvio Laudisio committed
        ih.derotator.nameid = suc::DROT;
        ih.derotator.mechanical_id = 0;
        
        ih.inbeam_dep.nameid = suc::INBEAM_DEP;
        ih.inbeam_dep.mechanical_id = 0;

        ih.inbeam_tt.nameid = suc::INBEAM_TT;
        ih.inbeam_tt.mechanical_id = 0;

        ih.lyot_grism_w.nameid = suc::LYOT_GRISM_W;
        ih.lyot_grism_w.mechanical_id = 0;

        ih.nd_filt_w.nameid = suc::ND_FILT_W;
        ih.nd_filt_w.mechanical_id = 0;

        ih.pupil_lens_dep.nameid = suc::PUPIL_LENS_DEP;
        ih.pupil_lens_dep.mechanical_id = 0;

        ih.sci_filt_w1.nameid = suc::SCI_FILT_W1;
        ih.sci_filt_w1.mechanical_id = 0;
        
        ih.sci_filt_w2.nameid = suc::SCI_FILT_W2;
        ih.sci_filt_w2.mechanical_id = 0;
        
        ih.shutter.nameid = suc::SHUTTER;
        ih.shutter.mechanical_id = 0;
Fulvio Laudisio's avatar
Fulvio Laudisio committed
        ih.adc_mode.nameid = suc::ADC_Mode;
        ih.drot_mode.nameid = suc::DROT_Mode;
        ih.mask_comb.nameid = suc::MaskComb;
        ih.temperature_start = ih.temperature_end = 0.0f;
    }
    ih.temperature_end = ih.temperature_start;
    ih.temperature_start = getMeanTemperature();
    const std::map<std::string, indi::IElement> & elementsA = sharknirTemperatureDetector.getElements();
    float valueA = 0.f;
    bool bValueA = false;
    if(elementsA.find("value") != elementsA.end())
    {
        valueA = elementsA.find("value")->second.get<float>();
        bValueA = true;
    }
    ih.temperature_start = valueA;

    if(m_pGetMotorStatus && !m_bFastSavingMode)
    {
        m_pGetMotorStatus(ih.apodizer_w);
        m_pGetMotorStatus(ih.coro_slit_w);
        m_pGetMotorStatus(ih.lyot_grism_w);
        m_pGetMotorStatus(ih.nd_filt_w);
        m_pGetMotorStatus(ih.db_filt_w);
        m_pGetMotorStatus(ih.sci_filt_w1);
        m_pGetMotorStatus(ih.sci_filt_w2);

        m_pGetMotorStatus(ih.inbeam_dep);
        m_pGetMotorStatus(ih.pupil_lens_dep);
        ih.pupil_lens_dep.status = ih.pupil_lens_dep.type == "IN";
        m_pGetMotorStatus(ih.shutter);
        ih.shutter.status = ih.shutter.type == "OUT";

        m_pGetMotorStatus(ih.inbeam_tt);

        m_pGetMotorStatus(ih.cal_fiber_dep);
        m_pGetMotorStatus(ih.cal_mirror_dep);
        ih.cal_mirror_dep.status = ih.cal_mirror_dep.type == "IN";
        m_pGetMotorStatus(ih.cal_filter_dep);

        m_pGetMotorStatus(ih.derotator);
        m_pGetMotorStatus(ih.adc);
sharknirws2's avatar
sharknirws2 committed

        m_pGetMotorStatus(ih.drot_mode);
        m_pGetMotorStatus(ih.adc_mode);
        m_pGetMotorStatus(ih.mask_comb);

    ih.cal_flat_field_lamp.status = m_obContext.flat_field_lamp == "ON";
    ih.cal_flat_field_lamp.type = m_obContext.flat_field_lamp;
    ih.cal_fiber_focus_lamp.status = m_obContext.focus_lamp == "ON";
    ih.cal_fiber_focus_lamp.type = m_obContext.focus_lamp;
    ih.cal_fiber_defocus_lamp.status = m_obContext.defocus_lamp == "ON";
    ih.cal_fiber_defocus_lamp.type = m_obContext.defocus_lamp;


    if(m_pGetRtcStatus)
    {
Davide Ricci's avatar
Davide Ricci committed
        for(std::map<std::string, std::string>::iterator itRtc = m_rtcKeywords.begin(); itRtc != m_rtcKeywords.end(); itRtc++)
        {
            if(!(m_bFastSavingMode && itRtc->first == "TTSENSORTEMP"))
                itRtc->second = m_pGetRtcStatus(itRtc->first);
    if(m_pGetTcsPreset && !m_bFastSavingMode)
    {
        m_TcsPreset = m_pGetTcsPreset();
    }

    m_bInstrumentSetupUpdated = true;
    U8_LLOG(__FUNCTION__);
float SeqDataMgr::getMeanTemperature()
{
    const std::map<std::string, indi::IElement> & elementsA = sharknirTemperatureDetector.getElements();
    float valueA = 0.f, valueB = 0.f;
    bool bValueA = false, bValueB = false;
    if(elementsA.find("value") != elementsA.end())
    {
        valueA = elementsA.find("value")->second.get<float>();
        bValueA = true;
    }
    const std::map<std::string, indi::IElement> & elementsB = sharknirTemperatureColdFinger.getElements();
    if(elementsB.find("value") != elementsB.end())
    {
        valueB = elementsB.find("value")->second.get<float>();
        bValueB = true;
    }

    float meanTemperature = 0.f;
    if(bValueA)meanTemperature += valueA;
    if(bValueB)meanTemperature += valueB;
    if(bValueA && bValueB)meanTemperature /= 2.f;

    return meanTemperature;
}


int SeqDataMgr::getJsonStatus(std::string & jsonStatus)
{
    int status = EXIT_SUCCESS;
    // GET TEMPERATURE STATUS 
    const std::map<std::string, indi::IElement> & temperatureA_elements = sharknirTemperatureDetector.getElements();
    float valueA = 0.f;
    if(temperatureA_elements.find("value") != temperatureA_elements.end())
        valueA = temperatureA_elements.find("value")->second.get<float>();
    }

    {
        std::stringstream json_alias;
        json_alias << "\"sasha_temp\": { \"name\": \"sasha_temp\", \"value\": \"" << valueA << "\"}";
        jsonStatus += json_alias.str();
        jsonStatus += ", ";
    // GET NUM READS 
    const std::map<std::string, indi::IElement> & nreads_elements = sashaNumReads.getElements();
    int NREADS = 0;
    if(nreads_elements.find("value") != nreads_elements.end())
        NREADS = nreads_elements.find("value")->second.get<int>();
    }

    {
        std::stringstream json_alias;
        json_alias << "\"NREADS\": { \"name\": \"NREADS\", \"value\": \"" << NREADS << "\"}";
        jsonStatus += json_alias.str();
        jsonStatus += ", ";
    }
    // GET NUM COADDS
    const std::map<std::string, indi::IElement> & ncoadds_elements = sashaNumCoadds.getElements();
    int NCOADDS = 0;
    if(ncoadds_elements.find("value") != ncoadds_elements.end())
        NCOADDS = ncoadds_elements.find("value")->second.get<int>();
    }

    {
        std::stringstream json_alias;
        json_alias << "\"NCOADDS\": { \"name\": \"NCOADDS\", \"value\": \"" << NCOADDS << "\"}";
        jsonStatus += json_alias.str();
        jsonStatus += ", ";
    const std::map<std::string, indi::IElement> & ndrops_elements = sashaNumDrops.getElements();
    int NDROPS = 0;
    if(ndrops_elements.find("value") != ndrops_elements.end())
        NDROPS = ndrops_elements.find("value")->second.get<int>();
    }

    {
        std::stringstream json_alias;
        json_alias << "\"NDROPS\": { \"name\": \"NDROPS\", \"value\": \"" << NDROPS << "\"}";
        jsonStatus += json_alias.str();
        jsonStatus += ", ";
    const std::map<std::string, indi::IElement> & ngroups_elements = sashaNumGroups.getElements();
    int NGROUPS = 0;
    if(ngroups_elements.find("value") != ngroups_elements.end())