// $Header: https://oberon.oapd.inaf.it/shins/trunk/shins/src/obs_ctrl/sequencerI.cpp 3989 2022-07-06 16:55:20Z depa $


#include <unistd.h>
#include <boost/exception/diagnostic_information.hpp>

#include "sequencerI.hpp"

void LogBoostDiagnosticInformation(int line)
{
    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 << "Line: " << line << " ~ " << what;
    E_LLOG(log_msg.str());
}


GetFitsFileJob::GetFitsFileJob(const obsControl::AMD_Sequencer_sashaGetFitsFilePtr& _psGF, boost::shared_ptr<SeqDataMgr>  _DataMgrPtr, const dictDetSetup& _dSashaSetup, const std::string& _instMode)
: DataMgrPtr(_DataMgrPtr), psGF(_psGF), dSashaSetup(_dSashaSetup), instMode(_instMode)
{
}

void GetFitsFileJob::execute()
{
    if(!getFitsFile())
    {
        psGF->ice_exception(obsControl::SashaTimeoutException());
        return;
    }
    psGF->ice_response(status, outFileName);
}

bool GetFitsFileJob::getFitsFile()
{
    status = EXIT_FAILURE;
    try
    {
    //    status = DataMgrPtr->sashaGetFitsFile(dSashaSetup, instMode, outFileName);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        return false;
    }
    return false;
}

// BCUInitTask::BCUInitTask(tiptiltCtrlPtr _ptrTipTiltCtrl)
// {
//   m_ptrTipTiltCtrl = tiptiltCtrlPtr(_ptrTipTiltCtrl);
//   // m_ptrTipTiltCtrl = _ptrTipTiltCtrl;
//   m_status = EXIT_FAILURE;
// }
// BCUInitTask::~BCUInitTask()
// {
//   //
// }
//
// void BCUInitTask::setDictionary(const dictTipTiltSetup& _dictSetup)
// {
//   m_ptrDictSetup = boost::make_shared<dictTipTiltSetup>(_dictSetup);
// }
//
// Ice::Int BCUInitTask::getStatus()
// {
//   return m_status;
// }
//
// void BCUInitTask::runTimerTask()
// {
//   //
//   try
//     {
//       m_status = m_ptrTipTiltCtrl->init_bcu(*m_ptrDictSetup);
//     }
//   catch(const Sharknir::BcuServiceException& e)
//   // catch(const Basda::Microgate::BcuInternalCodeExecutionTimeout& e)
//     {
//       m_status = EXIT_FAILURE;
//       W_LLOG(e.what());
//     }
// }

SequencerI::SequencerI(const std::map<std::string, bool> &_mapFlags,
                       boost::shared_ptr<osfsm::OSFsm> &_ptrSM,
                       boost::shared_ptr<boost::asio::io_service> _ptrIoService,
                       Ice::PropertiesPtr props): m_props(props)
{
    m_IceCallCounter = 0;
    LOG_SYSLOG;
    U6_LLOG(__FUNCTION__ << " - using stream operator - Constructor with IIF..");
    m_ptrMonSeq = boost::make_shared<IceUtil::Monitor<IceUtil::Mutex> >();

    tiptiltActive = false;

    U1_LLOG("Creating motion control object ...");
    m_motion = boost::shared_ptr<motionCtrl>(new motionCtrl( _ptrSM, m_props));

    U1_LLOG("Creating calunit control object ...");
    m_calibration = boost::shared_ptr<calunitCtrl>(new calunitCtrl(_ptrSM, m_props));

    U1_LLOG("Creating track control object ...");
    m_track = boost::shared_ptr<trackingCtrl>(new trackingCtrl(_ptrSM, m_props));

    std::map<std::string, bool>::const_iterator itFind;
    itFind = _mapFlags.find(suc::tiptiltCtrl);
    if((itFind != _mapFlags.end()) && (itFind->second == 1))
    {
        U9_LLOG("tiptiltActive was set to true");
        tiptiltActive = true;
    }
    U1_LLOG("Creating tiptilt control object ...");
    try
    {
        m_tiptilt = boost::shared_ptr<tiptiltCtrl>(new tiptiltCtrl(m_props));
    }
    catch(...)
    {
        tiptiltActive = false;
        LogBoostDiagnosticInformation(__LINE__);
    }

    // Start state machine
    m_ptrStateMachine = _ptrSM;
    D_LLOG("Pointer address to state machine " << su::convertTypeToString(m_ptrStateMachine));
    // m_ptrMtxStateMachine = boost::make_shared<IceUtil::Mutex>(_mtxSm);
    D_LLOG("State Machine state: " << su::convertTypeToString(*(m_ptrStateMachine->current_state())) << " before starting");
    m_ptrStateMachine->start();
    D_LLOG("State Machine state: " << su::convertTypeToString(*(m_ptrStateMachine->current_state())) << " should correspond to INIT");
    // state change to STANDBY:
    // NOTE a check on subsystems states should be performed first
    // NOTE add methods to get state from subsystems
    m_ptrStateMachine->process_event(osfsm::init_standby(true));
    D_LLOG("State Machine state: " << su::convertTypeToString(*(m_ptrStateMachine->current_state())) << " should correspond to STANDBY");
    // state change to ONLINE
    // NOTE same as above
    m_ptrStateMachine->process_event(osfsm::standby_online(true, false));
    D_LLOG("State Machine state: " << su::convertTypeToString(*(m_ptrStateMachine->current_state())) << " should correspond to ONLINE");
    m_ptrIoService = _ptrIoService;
    D_LLOG("copied io_service");


    m_insroot = su::get_env("INSROOT");
    U9_LLOG("m_insroot = " << m_insroot);
    //m_mapFitsKeywords = std::map<std::string, std::string>(); 
    //m_mapFitsKeywordsComments = std::map<std::string, std::string>();
    m_seqTcs = boost::shared_ptr<SeqTcs>(new SeqTcs(m_props));
    m_seqSnmp = boost::shared_ptr<SeqSnmp>(new SeqSnmp(m_props));
    m_seqDataMgr = boost::shared_ptr<SeqDataMgr>(new SeqDataMgr(m_seqTcs->getIifInterface(), props));
    m_seqSetup = boost::shared_ptr<SeqSetup>(new SeqSetup(m_props, m_motion, m_calibration, m_track, m_tiptilt, m_seqTcs, m_seqDataMgr, m_seqSnmp));
    m_seqDataMgr->SetMotorStatusCallback(m_seqSetup->getMotorStatus);
    m_seqDataMgr->SetRtcStatusCallback(m_tiptilt->getRtcStatus);
    m_seqSetup->SetGetObContextCallback(m_seqDataMgr->GetObContext);
    m_seqDataMgr->SetTcsPresetCallback(m_seqTcs->GetPresetInformation);
    U8_LLOG(__FUNCTION__ << " DONE");
}


SequencerI::~SequencerI()
{
    U6_LLOG(__FUNCTION__);
    //m_msgCount = NULL;
    //
    U8_LLOG("");
}
IceCallCounter::IceCallCounter(IceUtil::Mutex & seq_mutex, int & counter)
: seqMutex(seq_mutex), seqCounter(counter)
{
    seqMutex.lock();
    seqCounter++;
    callCounter = seqCounter;
    seqMutex.unlock();
}
IceCallCounter::~IceCallCounter()
{
    seqMutex.lock();
    seqCounter--;
    seqMutex.unlock();
}

Ice::Int SequencerI::getPosition(const IceUtil::Optional<std::string> &_unit,
                                 const sharknir::dictSetupPos &_inDictPosition,
                                 sharknir::dictSetupPos &_outDictPosition,
                                 const Ice::Current &_current)
{
//    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
//    U6_LLOG(__FUNCTION__ << " ~ " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    _outDictPosition = _inDictPosition;

    if(!_unit)
    {
        status = m_motion->getPosition(_outDictPosition);
        status = m_track->getPositionDict(_outDictPosition);
        status = m_calibration->getPosition(_outDictPosition);
    }
    else
    {
        status = m_motion->getPosition(_outDictPosition, _unit.get());
        status = m_track->getPositionDict(_outDictPosition, _unit.get());
        status = m_calibration->getPosition(_outDictPosition, _unit.get());
    }
//    U8_LLOG("");
    return status;
}

Ice::Int SequencerI::getStatus(const sharknir::dictStatus & inDictStatus, sharknir::dictStatus & outDictStatus, const Ice::Current & _c)
{
    Ice::Int status = EXIT_SUCCESS;

    return status;
}


Ice::Int SequencerI::getJsonStatus(std::string & jsonStatus, const Ice::Current & _c)
{
//    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
//    U6_LLOG(__FUNCTION__ << " ~ " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqSetup->getJsonStatus(jsonStatus, false);
    }
    catch(...)
    {
//        U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
        U6_LLOG(__FUNCTION__);
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
//    U8_LLOG(__FUNCTION__);
    return status;
}

Ice::Int SequencerI::getInternalSeqFloatVariable(const std::string & var, sharknir::SeqFloat & result, const Ice::Current & _c)
{
//    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    Ice::Int status = EXIT_FAILURE;
    std::string head = su::left(var, 3);
    if(!m_tiptilt->CheckConnection(false))return status;
    if(head == "Rtc")
    {
        try
        {
            CheckTipTilt();
            if(var == "RtcDmFlat" && m_tiptilt->m_ptrDm)
            {
                result = m_tiptilt->m_ptrDm->get_flat();
                status = EXIT_SUCCESS;
            }
            else if(var == "RtcPixelGain" && m_tiptilt->m_ptrSlopeComputer)
            {
                result = m_tiptilt->m_ptrSlopeComputer->get_pixel_gain();
                status = EXIT_SUCCESS;
            }
            else if(var == "RtcPixelBias" && m_tiptilt->m_ptrDetector)
            {
                Nice::SeqInt bias = m_tiptilt->m_ptrDetector->get_pixel_bias();
                std::vector<int>::iterator it;
                result.resize(bias.size());
                std::vector<float>::iterator itRes = result.begin();
                for(it = bias.begin(); it < bias.end(); it++)
                {
                    *itRes = *it;
                    itRes++;
                }
                status = EXIT_SUCCESS;
            }
            else if(var == "RtcCentroidOrigin" && m_tiptilt->m_ptrSlopeComputer)
            {
                result = m_tiptilt->m_ptrSlopeComputer->get_centroid_origin();
                status = EXIT_SUCCESS;
            }
            else if(var == "RtcAppliedMode" && m_tiptilt->m_ptrSlopeComputer)
            {
                result = m_tiptilt->m_ptrSlopeComputer->get_mode_vector();
                status = EXIT_SUCCESS;
            }
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
        }
        if(status == EXIT_SUCCESS)
            return status;
    }

    {
        std::stringstream log_msg;
        log_msg << "Unrecognized variable " << var << " error.";
        E_LLOG(log_msg.str());
        throw(std::runtime_error(log_msg.str()));
    }
    return status;
}


Ice::Int SequencerI::osLogBanner(const std::string & _banner, const Ice::Current & _c)
{
//    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    su::os_log_banner(_banner);

    return EXIT_SUCCESS;
}


Ice::Int SequencerI::changeState(const std::string &_state, const IceUtil::Optional<sharknir::SeqString> &_vecDevAlias, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    Basda::ServiceState _basdaState;
    std::string standby = "STANDBY";

    std::cout << "****" << _state << "****" << _state.compare("STANDBY") << std::endl;

    if(_state == "ONLINE")
        _basdaState = Basda::ONLINE;
    else if(_state == "STANDBY")
        _basdaState = Basda::STANDBY;
    else if(_state == "WORKING")
        _basdaState = Basda::WORKING;
    else if(_state == "OFFLINE")
        _basdaState = Basda::OFFLINE;
    else if(_state == "ERROR")
        _basdaState = Basda::ERROR;
    else if(_state == "SHUTDOWN")
        _basdaState = Basda::SHUTDOWN;
    else
    {
        E_LLOG(_state << " is a wrong state value");
        throw(std::runtime_error("Wrong state value"));
    }
    if(_vecDevAlias)
    {
        m_calibration->changeState(_basdaState, _vecDevAlias.get());
        m_motion->changeState(_basdaState, _vecDevAlias.get());
        m_track->changeState(_basdaState, _vecDevAlias.get());
    }
    else
    {
        m_calibration->changeState(_basdaState);
        m_motion->changeState(_basdaState);
        m_track->changeState(_basdaState);
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::setupMotionDict(const dictSetupPos &_mapSetup, const Ice::Current &_c)
{
    // Ice::LoggerPtr logger = _c.adapter->getCommunicator()->getLogger();
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    E_LLOG(__FUNCTION__ << " called");
    Ice::Int status = EXIT_FAILURE;
//    U8_LLOG("");
//    return status;
//    if(_mapSetup.empty())
//    // raise error, LOG a warning
//    {
//        E_LLOG(std::string(__FUNCTION__) + ":Invalid input parameter for setup motion");
//        U8_LLOG("");
//        throw std::invalid_argument("Invalid input parameter for setup motion");
//    }
//    else
//    {
//        std::map<std::string, double> m = _mapSetup;
//        std::map<std::string, double>::const_iterator it;
//        for(it = _mapSetup.begin(); it != _mapSetup.end(); ++it)
//        {
//            U9_LLOG(__FUNCTION__ << " > " << it->first);
//        }
//        std::map<std::string, Ice::Double>::const_iterator itFind;
//        itFind = _mapSetup.find(suc::CORO_SLIT_W);
//        if(itFind != _mapSetup.end())
//        {
//            check_coro_fiber_dep_clash();
//        }
//
//        m_motion->moveToAbsolutePosition(m);
//    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::setupCalibUnitDict(const dictSetupPos &_mapSetup, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());

    Ice::Int status = EXIT_SUCCESS;
    if(_mapSetup.empty())
        // raise error, LOG a warning
        throw std::invalid_argument("Invalid input parameter for setup motion");
    else
    {
        std::map<std::string, double> m = _mapSetup;
        std::map<std::string, double>::const_iterator it;
        for(it = m.begin(); it != m.end(); ++it)
        {
            U5_LLOG(__FUNCTION__ << " > " << it->first);
        }
        m_calibration->moveToAbsolutePosition(_mapSetup);
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


/**
 * @brief      { function_description }
 *
 * @param[in]  _time  The time
 *
 * @return     { description_of_the_return_value }
 */
Ice::Int SequencerI::setupTracking(const dictTrackingMode &_mapSetup, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    if(m_track)
        status = m_track->setMode(_mapSetup);
    U8_LLOG("");
    return status;
}

Ice::Int SequencerI::setupCalibration(const dictNonSciAssembly &d, const std::string &_strSetup, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    W_LLOG("Provide implementation for setupCalibration");

    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::moveDeviceToNegativeLimit(const std::vector<std::string>& _vecDevAlias, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    if(m_motion)
    {
        try
        {
            status = m_motion->moveDeviceToNegativeLimit(_vecDevAlias);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::moveDeviceToPositiveLimit(const std::vector<std::string>& _vecDevAlias, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    if(m_motion)
    {
        try
        {
            status = m_motion->moveDeviceToPositiveLimit(_vecDevAlias);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::initMotion(const std::vector<std::string> &_vecDevAlias, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    if(m_motion)
    {
        try
        {
            status = initMotionStart(_vecDevAlias, _c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
        try
        {
            status = initMotionWait(_vecDevAlias, IceUtil::None, _c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::initMotionStart(const std::vector<std::string> &_vecDevAlias, const Ice::Current&)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_FAILURE;
    if(m_motion->CheckOnline())
    {
        try
        {
            bool fiber_safe = false;
            bool coro_slit_involved = std::find(_vecDevAlias.begin(), _vecDevAlias.end(), suc::CORO_SLIT_W) != _vecDevAlias.end();
            if(!_vecDevAlias.empty() && coro_slit_involved)
            {
                U9_LLOG("Trying to put Fiber in safe area");
                int counter = 0;
                while(!fiber_safe && counter < 10)
                {
                    counter++;
                    fiber_safe = m_seqSetup->put_cal_fiber_in_safe_area2();
                    usleep(50000000);
                }
            }
            else if(!coro_slit_involved)
            {
                fiber_safe = true;
            }

            if(fiber_safe)
            {
                m_motion->initializeStart(_vecDevAlias);
                status = EXIT_SUCCESS;
            }
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::initMotionWait(const std::vector<std::string> &_vecDevAlias, const IceUtil::Optional<Ice::Long> &_time, const Ice::Current&)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_SUCCESS;
    if(m_motion->CheckOnline())
    {
        try
        {
            if(_time)
                m_motion->initializeWait(Nice::Time::milliSeconds(_time.get()));
            else
                m_motion->initializeWait(Nice::Time::seconds(90));
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::initMotionAll(const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    if(m_motion->CheckOnline())
    {
        try
        {
            status = initMotionAllStart(_c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    if(m_motion->CheckOnline())
    {
        try
        {
            status = initMotionAllWait(IceUtil::None, _c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::initMotionAllStart(const Ice::Current &_c)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_SUCCESS;
    if(m_motion->CheckOnline())
    {
        try
        {
            U9_LLOG("Calibration Fiber put in safe area");
            m_seqSetup->put_cal_fiber_in_safe_area2();
            m_motion->initializeAllStart();
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::initMotionAllWait(const IceUtil::Optional<Ice::Long> &_time, const Ice::Current &_c)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_SUCCESS;
    if(m_motion->CheckOnline())
    {
        try
        {
            if(_time)
                m_motion->initializeAllWait(Nice::Time::milliSeconds(_time.get()));
            else
                m_motion->initializeAllWait();
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::initCalibUnit(const std::vector<std::string> &_vecDevAlias, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    if(m_calibration)
    {
        try
        {
            status = initCalibUnitStart(_vecDevAlias, _c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
        if(status == EXIT_SUCCESS)
        {
            try
            {
                status = initCalibUnitWait(_vecDevAlias, IceUtil::None, _c);
            }
            catch(...)
            {
                LogBoostDiagnosticInformation(__LINE__);
                U8_LLOG("");
                throw;
            }
        }
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::initCalibUnitStart(const std::vector<std::string> &_vecDevAlias, const Ice::Current&)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_FAILURE;
    if(m_calibration->CheckOnline())
    {
        try
        {
            m_calibration->moveToReferenceStart(_vecDevAlias);
            status = EXIT_SUCCESS;
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    else
    {
        U8_LLOG("");
        throw(std::runtime_error("Error Calibration is not active"));
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::initCalibUnitWait(const std::vector<std::string> &_vecDevAlias, const IceUtil::Optional<Ice::Long> &_time, const Ice::Current&)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_FAILURE;
    if(m_calibration->CheckOnline())
    {
        try
        {
            if(_time)
                m_calibration->moveToReferenceWait(_vecDevAlias, Nice::Time::milliSeconds(_time.get()));
            else
                m_calibration->moveToReferenceWait(_vecDevAlias);
            status = EXIT_SUCCESS;
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    else
    {
        U8_LLOG("");
        throw(std::runtime_error("Error Calibration is not active"));
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::initCalibUnitAll(const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    std::string strLog = "";
    if(m_calibration->CheckOnline())
    {
        try
        {
            status = initCalibUnitAllStart(_c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
        try
        {
            status = initCalibUnitAllWait(IceUtil::None, _c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    else
    {
        U8_LLOG("");
        throw(std::runtime_error("Error Calibration is not active"));
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::initCalibUnitAllStart(const Ice::Current &_c)
{
    U6_LLOG(__FUNCTION__);
    W_LLOG(__FUNCTION__ << " called");
    Ice::Int status = EXIT_SUCCESS;
    if(m_calibration->CheckOnline())
    {
        try
        {
            m_calibration->moveToReferenceAllStart();
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    else
    {
        U8_LLOG("");
        throw(std::runtime_error("Error Calibration is not active"));
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::initCalibUnitAllWait(const IceUtil::Optional<Ice::Long> &_time, const Ice::Current &_c)
{
    U6_LLOG(__FUNCTION__);
    W_LLOG(__FUNCTION__ << " called");
    Ice::Int status = EXIT_SUCCESS;
    if(m_calibration->CheckOnline())
    {
        try
        {
            if(_time)
                m_calibration->moveToReferenceAllWait(Nice::Time::milliSeconds(_time.get()));
            else
                m_calibration->moveToReferenceAllWait();
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    else
    {
        U8_LLOG("");
        throw(std::runtime_error("Error Calibration is not active"));
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::initTracking(const std::vector<std::string> &_vecDevAlias, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    if(m_track->CheckOnline())
    {
        try
        {
            status = initTrackingStart(_vecDevAlias, _c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
        try
        {
            status = initTrackingWait(_vecDevAlias, IceUtil::None, _c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::initTrackingStart(const std::vector<std::string> &_vecDevAlias, const Ice::Current&)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_SUCCESS;
    if(m_track->CheckOnline())
    {
        try
        {
            m_track->initializeStart(_vecDevAlias);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::initTrackingWait(const std::vector<std::string> &_vecDevAlias, const IceUtil::Optional<Ice::Long> &_time, const Ice::Current&)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_SUCCESS;
//    if(trackActive)
    {
        try
        {
            if(_time)
                m_track->initializeWait(_vecDevAlias, Nice::Time::milliSeconds(_time.get()));
            else
                m_track->initializeWait(_vecDevAlias);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::initTrackingAll(const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
//    if(trackActive)
    {
        try
        {
            status = initTrackingAllStart(_c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }

        try
        {
            status = initTrackingAllWait(IceUtil::None, _c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::initTrackingAllStart(const Ice::Current &_c)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_SUCCESS;
//    if(trackActive)
    {
        try
        {
            m_track->initializeStart();
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::initTrackingAllWait(const IceUtil::Optional<Ice::Long> &_time, const Ice::Current &_c)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_SUCCESS;
    // if(_time)
    //   Nice::Time niceTime = Nice::Time::seconds(_time);
//    if(trackActive)
    {
        try
        {
            if(_time)
                m_track->initializeWait(std::vector<std::string>(), Nice::Time::milliSeconds(_time.get()));
            else
                m_track->initializeWait();
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::initInstrument(const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        status = initInstrumentStart(_c);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    try
    {
        status = initInstrumentWait(IceUtil::None, _c);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::initInstrumentStart(const Ice::Current &_c)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_SUCCESS;
    if(m_motion->CheckOnline())
    {
        try
        {
            status = initMotionAllStart(_c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    if(m_calibration->CheckOnline())
    {
        try
        {
            status = initCalibUnitAllStart(_c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    if(m_track->CheckOnline())
    {
        try
        {
            status = initTrackingAllStart(_c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }

    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::initInstrumentWait(const IceUtil::Optional<Ice::Long> &_time, const Ice::Current &_c)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_SUCCESS;

    if(_time)
    {
        try
        {
            if(m_calibration->CheckOnline())
                status = initCalibUnitAllWait(_time.get(), _c);
            if(m_track->CheckOnline())
                status = initTrackingAllWait(_time.get(), _c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    else
    {
        try
        {
            if(m_calibration->CheckOnline())
                status = initCalibUnitAllWait(IceUtil::None, _c);
            if(m_track->CheckOnline())
                status = initTrackingAllWait(IceUtil::None, _c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }

    if(m_motion->CheckOnline())
    {
        try
        {
            if(_time)
                status = initMotionAllWait(_time.get(), _c);
            else
                status = initMotionAllWait(IceUtil::None, _c);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }

    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::moveDevices(const dictSetupNamedPos &_dSetupNamedPos, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqSetup->moveDevices(_dSetupNamedPos);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}
Ice::Int SequencerI::moveDevicesStart(const dictSetupNamedPos &_dSetupNamedPos, const Ice::Current &_c)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqSetup->moveDevicesStart(_dSetupNamedPos);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}
Ice::Int SequencerI::moveDevicesWait(const Ice::Current &_c)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqSetup->moveDevicesWait();
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::setupInstrument(const dictSetupNamedPos &_dSetupNamedPos, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqSetup->setupInstrument(_dSetupNamedPos, _c);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::setupInstrumentAbsolutePosition(const dictSetupPos &_dSetupPos,
                                                     const IceUtil::Optional<dictDevUnit> &_dUnit,
                                                     const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    dictDevUnit dUnit;
    if(_dUnit)dUnit = _dUnit.get();
    try
    {
        status = m_seqSetup->setupInstrumentAbsolutePosition(_dSetupPos, dUnit, _c);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::setupInstrumentRelativePosition(const dictSetupPos &_dSetupPos,
                                                     const IceUtil::Optional<dictDevUnit> &_dUnit,
                                                     const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    dictDevUnit dUnit;
    if(_dUnit)dUnit = _dUnit.get();
    try
    {
        status = m_seqSetup->setupInstrumentRelativePosition(_dSetupPos, dUnit, _c);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::parkInstrument(const IceUtil::Optional<dictSetupPos> &_dSetupPos,
    const IceUtil::Optional<dictDevUnit> &_dUnit, const Ice::Current& _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    E_LLOG("Error function under development");
//    parkInstrumentStart(_dSetupPos, _dUnit.get(), _c);
//    parkInstrumentWait(_dSetupPos, 60, _c);
    U8_LLOG(__FUNCTION__);
    return status;
}



//       ############        ###############        #########
//       ##############      ###############      #############
//       ###############     ###############     ###############
//       ###############     ###############     ###############
//       ###############     ###############     ###############
//       ###############     ###############     ######    #####
//       #####       ###          #####          #####
//       #####       ###          #####          #####
//       #####       ###          #####          #####
//       #####       ###          #####          #####
//       #####     ###            #####          #####
//       #####   ###              #####          #####
//       ########                 #####          #####
//       #############            #####          #####
//       #############            #####          #####
//       #####    ######          #####          #####
//       #####     #####          #####          #####
//       #####     #####          #####          #####
//       #####     #####          #####          ######    #####
//       #####     #####          #####          ###############
//       #####     #####          #####          ###############
//       #####     #####          #####          ###############
//       #####     #####          #####           #############
//       #####     #####          #####             #########



void SequencerI::CheckTipTilt()
{
    if(!tiptiltActive && m_tiptilt->CheckConnection())
    {
        std::stringstream log_msg("Tip tilt is not active");
        E_LLOG(log_msg.str());
        throw(std::runtime_error(log_msg.str()));
    }
}

Ice::Int SequencerI::RTCTTInit(const dictTipTiltSetup &_dtiptiltSetup, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int result = EXIT_SUCCESS;
    try
    {
        CheckTipTilt();
        result = m_tiptilt->init_bcu(_dtiptiltSetup);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return result;
}


Ice::Int SequencerI::RTCTTSetup(const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int result = EXIT_SUCCESS;
    try
    {
        CheckTipTilt();
        result = m_tiptilt->setup_bcu();
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return result;
}


Ice::Int SequencerI::RTCTTResetBCU(const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int result = EXIT_SUCCESS;
    try
    {
        CheckTipTilt();
        result = m_tiptilt->reset_bcu();
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
//        U8_LLOG("");
//        throw;
    }
    usleep(30000000);
    U8_LLOG("");
    return result;
}

Ice::Int SequencerI::RTCTTSwitchCcdMode(const dictTipTiltSetup &_dtiptiltSetup, const Ice::Current &)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int result = EXIT_SUCCESS;
    try
    {
        CheckTipTilt();
        result = m_tiptilt->switch_ccd_mode(_dtiptiltSetup);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return result;
}

Ice::Int SequencerI::RTCTTIsInit(bool &_isInit, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        CheckTipTilt();
        status = EXIT_SUCCESS;
        _isInit = m_tiptilt->is_init();
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::RTCTTStart(const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        CheckTipTilt();
        status = m_tiptilt->start_bcu();
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::RTCTTSetCentroidPos(Ice::Float centroidX, Ice::Float centroidY, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter() << " ~ [" << centroidX << ", " << centroidY << "]");
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        CheckTipTilt();
        status = m_tiptilt->set_centroid_pos(centroidX, centroidY);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


// upload modes vector to internal DM
// used to upload static NCPA or tip/tilt modes for fine centering
Ice::Int SequencerI::RTCTTModeUpload(const sharknir::SeqFloat &_seqModes, bool absolute, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        U9_LLOG(__FUNCTION__ << su::seq_float_to_str(_seqModes, 50));
        CheckTipTilt();
        status = m_tiptilt->apply_mode_vector(_seqModes, absolute);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::RTCTTStop(const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        throw(std::domain_error("Function " + std::string(__FUNCTION__) + " is deprecated!"));
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::RTCTTConfigCamera(const dictTipTiltSetup &_dictTipTiltSetup, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        CheckTipTilt();
        status = m_tiptilt->config_camera(_dictTipTiltSetup);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}

int SequencerI::RTCTTSendCameraCommand(const std::string &_command, std::string &_reply, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        CheckTipTilt();
        status = m_tiptilt->filter_known_commands(_command, _reply);
        if(status == EXIT_FAILURE)
        {
            status = m_tiptilt->send_command_to_camera(_command, _reply);
        }
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::RTCTTEnableLoop(const dictTipTiltSetup &_dictTipTiltSetup, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    int status = EXIT_SUCCESS;
    bool loopEnabled = false;
    if(shins::util::get_bool_from_setup(_dictTipTiltSetup, "TTLOOPENABLED", loopEnabled))
    {
        try
        {
            CheckTipTilt();
            m_tiptilt->enable_loop(loopEnabled);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    else
    {
        std::string msg = "Error : missing mandatory parameter TTLOOPENABLED";
        E_LLOG(msg);
        U8_LLOG("");
        throw(std::invalid_argument(msg));
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::RTCTTExecuteSetup(const dictTipTiltSetup &_execSetup, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        CheckTipTilt();
        m_tiptilt->exec_setup(_execSetup);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::RTCTTCloseLoop(const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        CheckTipTilt();
        status = m_tiptilt->enable_loop(true);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::RTCTTOpenLoop(const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        CheckTipTilt();
        status = m_tiptilt->enable_loop(false);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::RTCTTEnableDiagnostic(const dictTipTiltSetup &_dictTipTiltSetup, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        CheckTipTilt();
        status = m_tiptilt->enable_diagnostic(_dictTipTiltSetup);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


/**
 * @brief      get diagnostics records from BCU
 *
 * @param[in]  _nMaxRecords: maximum number of records to retrieve
 * @param[out] _seqDiagnosticRecord: sequential container (std vector) storing
 * retrieved diagnostics records
 * @return     status at the end of the opration: EXIT_SUCCESS or EXIT_FAILURE
 */
Ice::Int SequencerI::RTCTTGetDiagnostics(Ice::Int _nMaxRecords, /*input parameter*/
                                         obsControl::SeqDiagnosticRecord &_seqDiagnosticRecord, // output parameter
                                         const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    DiagnosticRecord tmpDiagRec;
    obsControl::DiagnosticRecordPtr tmpPtrDiagRec;
    Sharknir::Bcu::OverallDiagnosticRecord tmpOverallDiagRec;
    Sharknir::Bcu::SeqOverallDiagnosticRecord seqDiagRec;
    Nice::Time timeout = Nice::Time::seconds(10);
    try
    {
        CheckTipTilt();
        seqDiagRec = m_tiptilt->getPastOverallDiagnosticRecordsInOnePass(_nMaxRecords);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
    }

    try
    {
        CheckTipTilt();
        seqDiagRec = m_tiptilt->getFutureOverallDiagnosticRecordsInOnePass(_nMaxRecords, timeout);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }

    // seqDiagRec to obsControl::SeqDiagnosticRecord type out parameter
    std::vector<Sharknir::Bcu::OverallDiagnosticRecord>::iterator itDiag;
    for(itDiag = seqDiagRec.begin(); itDiag != seqDiagRec.end(); ++itDiag)
    {
        tmpOverallDiagRec = (*itDiag);
        tmpDiagRec = DiagnosticRecord(tmpOverallDiagRec);
        tmpPtrDiagRec = new DiagnosticRecord;
        *tmpPtrDiagRec = tmpDiagRec;
        _seqDiagnosticRecord.push_back(tmpPtrDiagRec);
    }
    // _diagnosticRecord.setFrameCounter(diagRec.frameCounter);
    // _diagnosticRecord.setSlopeRecord(diagRec.slopeRecord);
    // _diagnosticRecord.setAsmRecord(diagRec.asmRecord);
    // _diagnosticRecord.setCcdRecord(diagRec.ccdRecord);

    U8_LLOG(__FUNCTION__);
    return status;
}


// int SequencerI::RTCTTGetDiagnostics(const Ice::Int& _nMaxRecords,
//                        sharknir::obsControl::SeqOverallDiagnosticRecord& _diagnosticRecord,
//                        const Ice::Current&)
// {
//  int status = EXIT_SUCCESS;
//  W_LLOG("Provide implementation for RTCTTGetDiagnostics");
//  return status;
// }

Ice::Int SequencerI::RTCTTTeccamSetup(const sharknir::dictDetSetup &_dTechCamSetup, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;

    try
    {
        throw(std::domain_error("Function " + std::string(__FUNCTION__) + " is deprecated!"));
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::RTCTTTeccamExpose(const sharknir::dictDetSetup &_dTechCamSetup, std::string &_fitsFilename, const Ice::Current& _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    std::map<std::string, std::string>::const_iterator itSetup;
    for(itSetup = _dTechCamSetup.begin(); itSetup != _dTechCamSetup.end(); itSetup++)
    {
        U9_LLOG("Keyword : " << std::setfill('_') << std::setw(20) << itSetup->first << "; Value : " << std::setw(70) << itSetup->second);
    }
    try
    {
        CheckTipTilt();
        status = m_tiptilt->tech_cam_expose(_dTechCamSetup, _fitsFilename);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::RTCTTWriteTimeHistory(const dictTipTiltSetup &_dTipTiltSetup, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    bf::path p;
    bf::path pDefault = m_insroot;

    std::map<std::string, std::string>::const_iterator itFind;
    itFind = _dTipTiltSetup.find("TTHISTORYFILE");
    if(itFind != _dTipTiltSetup.end())
    {
        p = itFind->second;
        try
        {
            CheckTipTilt();
            status = m_tiptilt->write_time_history_to_bcu(p.generic_string());
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::RTCTTEnableTimeHistory(const dictTipTiltSetup &_dTipTiltSetup, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    bool enable = false;

    if(shins::util::get_bool_from_setup(_dTipTiltSetup, "TTHISTORYENABLED", enable))
    {
        try
        {
            CheckTipTilt();
            status = m_tiptilt->enable_time_history(enable);
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    else
    {
        std::string msg = "Error : missing mandatory parameter TTHISTORYENABLED";
        E_LLOG(msg);
        U8_LLOG("");
        throw std::invalid_argument(msg);
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::RTCTTReadSingle(Ice::Int address, Ice::Int size,const std::string & memory, sharknir::SeqFloat & read_data, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;

    try
    {
        CheckTipTilt();
        read_data = m_tiptilt->read_bcu_single(address, size, memory);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }

    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::RTCTTRead(Ice::Int address, Ice::Int size,const std::string & memory, sharknir::SeqInt & read_data, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;

    try
    {
        CheckTipTilt();
        read_data = m_tiptilt->read_bcu(address, size, memory);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::RTCTTWrite(const sharknir::SeqInt & command, Ice::Int address, const std::string & memory, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;

    try
    {
        CheckTipTilt();
        status = m_tiptilt->write_bcu(address, command, memory);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::RTCTTWriteSingle(const sharknir::SeqFloat & command, Ice::Int address, const std::string & memory, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;

    try
    {
        CheckTipTilt();
        status = m_tiptilt->write_bcu_single(address, command, memory);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


//       ###############     ############          ##########           #########        #####      ####
//       ###############     ##############       #############       #############      #####      ####
//       ###############     ###############     ###############     ###############     #####      ####
//       ###############     ###############     ###############     ###############     #####      ####
//       ###############     ###############     ###############     ###############     #####      ####
//       ###############     ###############     ###############     ######    #####     #####      ####
//            #####          #####       ###     #####       ###     #####               #####       ###
//            #####          #####       ###     #####       ###     #####               #####       ###
//            #####          #####     ###       #####       ###     #####               #####     ###
//            #####          #####   ###         #####       ###     #####               #####   ###
//            #####          ########            ###############     #####               ########
//            #####          #############       ###############     #####               #############
//            #####          #############       ###############     #####               #############
//            #####          #############       ###############     #####               #############
//            #####          #####    ######     #####     #####     #####               #####    ######
//            #####          #####     #####     #####     #####     #####               #####     #####
//            #####          #####     #####     #####     #####     #####               #####     #####
//            #####          #####     #####     #####     #####     ######    #####     #####     #####
//            #####          #####     #####     #####     #####     ###############     #####     #####
//            #####          #####     #####     #####     #####     ###############     #####     #####
//            #####          #####     #####     #####     #####     ###############     #####     #####
//            #####          #####     #####     #####     #####      #############      #####     #####
//            #####          #####     #####     #####     #####        #########        #####     #####



// Ice::Int SequencerI::trackingStart(const IceUtil::Optional<Ice::Long> &_secondsToStart)
// {
//     Nice::Date startDate;
//     if(!_secondsToStart)
//         startDate = Nice::Date::now() + Nice::Time::seconds(20);
//     else
//         startDate = Nice::Date::now() + Nice::Time::seconds(_secondsToStart.get());
//     return 0;
// }

/** @brief      { function_description }
  * @param[in]  <unnamed>  { parameter_description }
  * @return     { description_of_the_return_value } */
Ice::Int SequencerI::trackingTestStart(Ice::Double _startPosDegree, Ice::Double _endPosDegree, Ice::Double _speedDegreeSec, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    if(m_track)
    {
        try
        {
            U7_LLOG(__FUNCTION__ << " : Starting trajectory ... ");
            m_track->startTrackingTest(_startPosDegree, _endPosDegree, _speedDegreeSec);
            U7_LLOG("DONE");
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    else
    {
        std::stringstream log_msg;
        log_msg << "Error track object not defined";
        E_LLOG(log_msg.str());
        throw std::runtime_error(log_msg.str());
    }
    U8_LLOG("");
    return status;
}

/** @brief      { function_description }
  * @param[in]  <unnamed>  { parameter_description }
  * @return     { description_of_the_return_value } */
Ice::Int SequencerI::trackingStart2(Ice::Double _dateMjd, Ice::Double _position, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    Nice::Date startDate = Nice::Date::fromMJD(_dateMjd);
//    Ice::Double positionDrot;
    std::string tmpUnit;
    // checking on optional values, setting defaults if not provided
    if(m_track)
    {
        try
        {
            U7_LLOG(__FUNCTION__ << " : Starting trajectory on MJD :" << _dateMjd << " ~ " << startDate);
            status = m_track->startTracking(startDate, _position);
            U7_LLOG(__FUNCTION__ << " ~ DONE");
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    else
    {
        std::stringstream log_msg;
        log_msg << "Error track object not defined";
        E_LLOG(log_msg.str());
        throw std::runtime_error(log_msg.str());
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::resetPosition(const std::string & _devAlias, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    if(m_track)
    {
        try
        {
            m_track->resetPosition(_devAlias);
            status = EXIT_SUCCESS;
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    else
    {
        std::stringstream log_msg;
        log_msg << "Error track object not defined";
        E_LLOG(log_msg.str());
        throw std::runtime_error(log_msg.str());
    }
    U8_LLOG("");
    return status;
}



/** @brief      Asynchronously starts derotation with parameters previously defined
  * @return     returns as soon as the derotation starts */
Ice::Int SequencerI::trackingStart(const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    if(m_track)
    {
        try
        {
            U1_LLOG(__FUNCTION__ << ":Starting trajectory ... ");
            status = m_track->startTracking();
            U1_LLOG("DONE");
        }
        catch(...)
        {
            LogBoostDiagnosticInformation(__LINE__);
            U8_LLOG("");
            throw;
        }
    }
    else
    {
        std::stringstream log_msg;
        log_msg << "Error track object not defined";
        E_LLOG(log_msg.str());
        U8_LLOG("");
        throw std::runtime_error(log_msg.str());
    }
    U8_LLOG("");
    return status;
}


/** @brief      waits for the derotation to complete
  * @param[in]  _time  The timeout parameter for waiting if not defined 
  * @return     returns as soon as timeout expires or derotaion completes (or is stopped) */
Ice::Int SequencerI::trackingWait(const IceUtil::Optional<Ice::Long> &_time, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    if(m_track)
    {
        Ice::Long seconds = 1073741824;
        if(_time)
            seconds = _time;
        status = m_track->waitTracking(seconds);
    }
    else
    {
        std::stringstream log_msg;
        log_msg << "Error track object not defined";
        E_LLOG(log_msg.str());
        U8_LLOG("");
        throw std::runtime_error(log_msg.str());
    }
    U8_LLOG("");
    return status;
}


/** @brief      { function_description }
  * @param[in]  <unnamed>  { parameter_description }
  * @return     { description_of_the_return_value } */
Ice::Int SequencerI::trackingStop(const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    if(m_track)
    {
        try
        {
            U1_LLOG("Stopping tracking ... ");
            m_track->stopAll();
            U1_LLOG("DONE");
        }
        catch(const Sharknir::DrotServiceException &e)
        {
            status = EXIT_FAILURE;
            E_LLOG(e.what());
        }
    }
    U8_LLOG("");
    return status;
}


/** @brief      { function_description }
  * @param[in]  <unnamed>  { parameter_description }
  * @return     { description_of_the_return_value } */
Ice::Int SequencerI::trackingAbort(const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    if(m_track)
        m_track->emergencyAbort();
    U8_LLOG("");
    return EXIT_SUCCESS;
}


Ice::Int SequencerI::trackingIsMoving(dictIsMoving &_mapDev, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    if(m_track)
        status = m_track->isMoving(_mapDev);
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::setDerotationParameters(Ice::Int numPolynomials, Ice::Double samplingRate, Ice::Double frequency, Ice::Int polynomialOrder, Ice::Int faultTolerance, Ice::Int samplesPerSegment, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        status = m_track->setDerotationParameters1(numPolynomials, samplingRate, frequency);
        status = m_track->setDerotationParameters2(polynomialOrder, faultTolerance, samplesPerSegment);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}

Ice::Int SequencerI::setDerotationParameters1(Ice::Int numPolynomials, Ice::Double samplingRate, Ice::Double frequency, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        status = m_track->setDerotationParameters1(numPolynomials, samplingRate, frequency);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}

Ice::Int SequencerI::setDerotationParameters2(Ice::Int polynomialOrder, Ice::Int faultTolerance, Ice::Int samplesPerSegment, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        status = m_track->setDerotationParameters2(polynomialOrder, faultTolerance, samplesPerSegment);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}

Ice::Int SequencerI::setDerotationParameters3(Ice::Double debug1, Ice::Double debug2, Ice::Double debug3, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        status = m_track->setDerotationParameters3(debug1, debug2, debug3);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}

Ice::Int SequencerI::setDerotationParameters4(Ice::Double debug4, Ice::Double debug5, Ice::Double debug6, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        status = m_track->setDerotationParameters4(debug4, debug5, debug6);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}

Ice::Int SequencerI::sharkDerotatorBacklashProcedure(const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        status = m_track->sharkDerotatorBacklashProcedure();
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::setAdcCorrectionParameters(Ice::Double co, Ice::Double p0, Ice::Double p1, Ice::Double t0, Ice::Double t1, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        status = m_track->setAdcCorrectionParameters(co, p0, p1, t0, t1);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::setAdcCoRotationOffset(Ice::Double corotation, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        status = m_track->setAdcCoRotationOffset(corotation);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::setAdcCounterRotationOffset(Ice::Double counterrotation, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    try
    {
        status = m_track->setAdcCounterRotationOffset(counterrotation);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}















/** @brief      { function_description }
  * @param[in]  _c    { parameter_description }
  * @return     { description_of_the_return_value } */
Ice::Int SequencerI::emergencyAbortAll(const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    W_LLOG("Emergency motion ABORT triggered");

    m_track->emergencyAbort();

    m_seqSetup->abortSetup();

    m_motion->emergencyAbort();

    m_calibration->emergencyAbort();

    try
    {
        CheckTipTilt();
        m_tiptilt->emergencyAbortAll();
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
    }

    m_seqDataMgr->abortExposure();

    U8_LLOG("");
    return EXIT_SUCCESS;
}


/*
 * stopMotion should accept device name as input
 */
Ice::Int SequencerI::stopMotion(const std::vector<std::string> &_vecDevAlias, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    W_LLOG("Stopping motion of specified devices");
    std::string strLog = "";
    Ice::Int status = EXIT_SUCCESS;

    try
    {
        m_motion->stop(_vecDevAlias);
    }
    catch(Nice::Exception err)
    {
        E_LLOG(err.what());
        status = EXIT_FAILURE;
    }

    try
    {
        m_calibration->stop(_vecDevAlias);
    }
    catch(Nice::Exception err)
    {
        E_LLOG(err.what());
        status = EXIT_FAILURE;
    }

    try
    {
        m_track->stop(_vecDevAlias);
    }
    catch(Nice::Exception err)
    {
        E_LLOG(err.what());
        status = EXIT_FAILURE;
    }

    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::abortMotion(const std::vector<std::string> &_vecDevAlias, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    A_LLOG("Abort motion of specified devices");
    std::string strLog = "";
    Ice::Int status = EXIT_SUCCESS;

    try
    {
        m_motion->abort(_vecDevAlias);
    }
    catch(Nice::Exception err)
    {
        E_LLOG(err.what());
        status = EXIT_FAILURE;
    }

    try
    {
        m_calibration->abort(_vecDevAlias);
    }
    catch(Nice::Exception err)
    {
        E_LLOG(err.what());
        status = EXIT_FAILURE;
    }

    try
    {
        m_track->abort(_vecDevAlias);
    }
    catch(Nice::Exception err)
    {
        E_LLOG(err.what());
        status = EXIT_FAILURE;
    }

    U8_LLOG("");
    return status;
}





//          #########          ##########            #########        #####     #####       ##########
//        #############       #############        #############      #####     #####      #############
//       ###############     ###############      ###############     #####     #####     ###############
//       ###############     ###############      ###############     #####     #####     ###############
//       ###############     ###############      ###############     #####     #####     ###############
//       ######    #####     ###############      ######    #####     #####     #####     ###############
//       #####      ##       #####       ###      #####      ##       #####     #####     #####       ###
//        #####              #####       ###       #####              #####     #####     #####       ###
//         #####             #####       ###        #####             #####     #####     #####       ###
//          #####            #####       ###         #####            #####     #####     #####       ###
//           #####           ###############          #####           ###############     ###############
//            ######         ###############           ######         ###############     ###############
//            ######         ###############           ######         ###############     ###############
//              #####        ###############             #####        ###############     ###############
//               #####       #####     #####              #####       #####     #####     #####     #####
//                #####      #####     #####               #####      #####     #####     #####     #####
//         ##      #####     #####     #####        ##      #####     #####     #####     #####     #####
//       #####    ######     #####     #####      #####    ######     #####     #####     #####     #####
//       ###############     #####     #####      ###############     #####     #####     #####     #####
//       ###############     #####     #####      ###############     #####     #####     #####     #####
//       ###############     #####     #####      ###############     #####     #####     #####     #####
//        #############      #####     #####       #############      #####     #####     #####     #####
//          #########        #####     #####         #########        #####     #####     #####     #####






Ice::Int SequencerI::setContext(const dictSetupNamedPos & _osContext, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    std::map<std::string, std::string>::const_iterator itSetup;
    for(itSetup = _osContext.begin(); itSetup != _osContext.end(); itSetup++)
    {
        U9_LLOG("Keyword : " << std::setfill('_') << std::setw(16) << itSetup->first << "; Value : " << std::setw(70) << itSetup->second);
    }
    try
    {
        status = m_seqDataMgr->setContext(_osContext);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }

    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::setLampsStatus(const dictSetupNamedPos & _osLampsStatus, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    std::map<std::string, std::string>::const_iterator itSetup;
    for(itSetup = _osLampsStatus.begin(); itSetup != _osLampsStatus.end(); itSetup++)
    {
        U9_LLOG("Keyword : " << std::setfill('_') << std::setw(16) << itSetup->first << "; Value : " << std::setw(40) << itSetup->second);
    }
    try
    {
        status = m_seqDataMgr->setLampsStatus(_osLampsStatus);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }

    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::sashaSetup(const dictDetSetup &_dSashaSetup, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    std::map<std::string, std::string>::const_iterator itSetup;
    for(itSetup = _dSashaSetup.begin(); itSetup != _dSashaSetup.end(); itSetup++)
    {
        U9_LLOG("Keyword : " << std::setfill('_') << std::setw(20) << itSetup->first << "; Value : " << std::setw(70) << itSetup->second);
    }
    try
    {
        status = m_seqDataMgr->sashaSetup(_dSashaSetup);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::sashaSetFrequency(const dictDetSetup &_dSashaSetup, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqDataMgr->sashaSetFrequency(_dSashaSetup);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}
/*
 * expose the scientific camera SASHA with parameters in input dictionary
 */
Ice::Int SequencerI::sashaExpose(std::vector<std::string> & _out_files, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqDataMgr->sashaExpose(_out_files);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::sashaEnableSave(const dictDetSetup &_dSashaSetup, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        throw(std::domain_error("Function " + std::string(__FUNCTION__) + " is deprecated!"));
        status = m_seqDataMgr->sashaEnableSave(_dSashaSetup);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::sashaGetIndiMsges(const dictDetSetup &_dSashaSetup, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    std::map<std::string, std::string>::const_iterator itFind;
    int Test = 2;
    std::string Separator;
    itFind = _dSashaSetup.find("FTEST");
    if(itFind != _dSashaSetup.end())
    {
        Test = su::convertStringToType<int>(itFind->second);
        itFind =  _dSashaSetup.find("SEPARATOR");
        if(itFind != _dSashaSetup.end())
        {
            Separator = itFind->second;
        }
    }
    else
    {
        Test = 2;
    }

    if(Test == 3)
    {
        int banner_len = 60;
        int separator_size = Separator.length();
        if(separator_size > (banner_len - 6))
        {
            Separator = Separator.substr(0, banner_len - 6);
            separator_size = banner_len - 6;
        }
        int left = (banner_len - separator_size - 6)/2;
        int right = banner_len - separator_size - 6 - left;
        I_LLOG(std::string(banner_len, '#'));
        I_LLOG(std::string(left, '#') << " ~ " << Separator <<  " ~ " <<  std::string(right, '#'));
        I_LLOG(std::string(banner_len, '#'));
    }
    if(Test == 4)
    {
        U9_LLOG(__FUNCTION__ << " ~ m_calibration.get(): " << m_calibration.get());
//        U9_LLOG(__FUNCTION__ << " ~ m_seqSetup->m_calibration.get(): " << m_seqSetup->m_calibration.get());
//        m_calibration.reset();
        U9_LLOG(__FUNCTION__ << " ~ m_calibration.get(): " << m_calibration.get());
//        U9_LLOG(__FUNCTION__ << " ~ m_seqSetup->m_calibration.get(): " << m_seqSetup->m_calibration.get());
//        m_seqSetup->m_calibration.reset();
        U9_LLOG(__FUNCTION__ << " ~ m_calibration.get(): " << m_calibration.get());
//        U9_LLOG(__FUNCTION__ << " ~ m_seqSetup->m_calibration.get(): " << m_seqSetup->m_calibration.get());
//        int argc = 2;
//        char * argv[] = {"obsControlServer", "--LOGGER.LEVEL:LogLevel=DEBUG"};
//        m_calibration = boost::shared_ptr<calunitCtrl>(new calunitCtrl(argc, argv, m_strAliasFileName, m_mainMapNamedPos, m_mapCfgFiles, m_ptrStateMachine));
        U9_LLOG(__FUNCTION__ << " ~ m_calibration.get(): " << m_calibration.get());
//        U9_LLOG(__FUNCTION__ << " ~ m_seqSetup->m_calibration.get(): " << m_seqSetup->m_calibration.get());
     }

    U8_LLOG("");
    return 0;
}

/** @brief      { function_description }
  * @param[in]  _c    { parameter_description }
  * @return     { description_of_the_return_value } */
Ice::Int SequencerI::sashaAbortExposure(const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());

    m_seqDataMgr->abortExposure();

    U8_LLOG("");
    return EXIT_SUCCESS;
}


void SequencerI::sashaGetFitsFile_async(const ::sharknir::obsControl::AMD_Sequencer_sashaGetFitsFilePtr& _psGF,
                                        const dictDetSetup& _dSashaSetup,
                                        const std::string& _instMode,
                                        const Ice::Current& _c)
{
    U6_LLOG(__FUNCTION__);
    IceUtil::Mutex::Lock sync(*this);
    std::map<std::string, std::string>::const_iterator itFind;
    for(itFind = _c.ctx.begin(); itFind != _c.ctx.end(); itFind++)
    {
        U9_LLOG("Keyword : " << std::setw(20) << itFind->first << "; Value : " <<std::setw(20) << itFind->second);
    }
    GetFitsFileJobPtr job = new GetFitsFileJob(_psGF, m_seqDataMgr, _dSashaSetup, _instMode);
    _getFitsFileJobs.push_back(job);
    E_LLOG("Error : Function under development. Missing application thread running jobs!");
    U8_LLOG(__FUNCTION__);
}


Ice::Int SequencerI::sashaGetFitsFileSync(const dictDetSetup & _dSashaSetup, const std::string & _instMode, std::string & _outFilename, const Ice::Current& _c)
{
    U6_LLOG(__FUNCTION__);
    Ice::Int status = EXIT_FAILURE;
    try
    {
        throw(std::domain_error("Function " + std::string(__FUNCTION__) + " is deprecated!"));
    //    status = m_seqDataMgr->sashaGetFitsFile(_dSashaSetup, _instMode, _outFilename);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG("");
    return status;
}


/////////////////////////////////////////////////////
///////////////////// DATA MANAGER //////////////////
/////////////////////////////////////////////////////
Ice::Int SequencerI::datamgrCreateEmptyFile(const std::string &_filename, std::string &_outFilename, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    W_LLOG("Provide implementation for datamgrCreateEmptyFile");
    Ice::Int status = EXIT_SUCCESS;
    std::string outFilename = "";

    Ice::CommunicatorPtr dataMgrIC;
    // --Ice.Config=$INSROOT/etc/data_mgr/data_mgr-ice.cfg
    char Arg1[] = "SequncerI::datamgrCreateEmptyFile";
    char Arg2[] = "--Ice.Config=/opt/tan/etc/data_mgr/data_mgr-ice.cfg";
    char *argvDataMgr[] = { Arg1, Arg2 };
    int argcDataMgr = 2;
    try
    {
        dataMgrIC = Ice::initialize(argcDataMgr, argvDataMgr);
        Ice::ObjectPrx base = dataMgrIC->stringToProxy("dataManagerAdapter:default -p 10501");
        sd::fitsFilePrx archiver = sd::fitsFilePrx::checkedCast(base);
        if(!archiver)
            throw("Invalid Proxy");
        // outFilename must be saved somewhere for the specific observation
        status = archiver->createEmptyFile(_filename, IceUtil::None, outFilename);
        _outFilename = outFilename;
    }
    catch(const Ice::Exception &ex)
    {
        E_LLOG(ex.what());
        status = EXIT_FAILURE;
    }
    catch(const char *msg)
    {
        E_LLOG(msg);
        status = EXIT_FAILURE;
    }
    if(dataMgrIC)
        dataMgrIC->destroy();

    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::datamgrPrintFITS(const std::string &_key, const std::string &_value,
                                      const IceUtil::Optional<std::string> &_comment,
                                      const IceUtil::Optional<std::string> &_filename,
                                      const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    W_LLOG("Provide implementation for datamgrPrintFITS");
    std::string comment = "";
    Ice::Int status = EXIT_SUCCESS;
    Ice::CommunicatorPtr dataMgrIC;
    bf::path pathCfg = m_insroot;
    std::string strCfg = "";
    pathCfg += "/etc/data_mgr/data_mgr-ice.cfg";

    strCfg = "--Ice.Config=" + pathCfg.generic_string();

    char Arg1[] = "SequencerI::datamgrPrintFITS";
    char Arg2[] = "--Ice.Config=/opt/tan/etc/data_mgr/data_mgr-ice.cfg";
    char *argvDataMgr[] = { Arg1, Arg2 };
    // char *argvDataMgr[2];
    // argvDataMgr[0] = "SequencerI::datamgrPrintFITS";
    // strcpy(argvDataMgr[1], strCfg.c_str());
    int argcDataMgr = 2;

    try
    {
        dataMgrIC = Ice::initialize(argcDataMgr, argvDataMgr);
        Ice::ObjectPrx base = dataMgrIC->stringToProxy("dataManagerAdapter:default -p 10501");
        sd::fitsFilePrx archiver = sd::fitsFilePrx::checkedCast(base);
        if(!archiver)
            throw("Invalid Proxy");

        status = archiver->printFITS(_key, _value, _comment, _filename);
    }
    catch(const Ice::Exception &ex)
    {
        E_LLOG(ex.what());
        status = EXIT_FAILURE;
    }
    catch(const char *msg)
    {
        E_LLOG(msg);
        status = EXIT_FAILURE;
    }
    if(dataMgrIC)
        dataMgrIC->destroy();

    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::datamgrMergeHeaders(const IceUtil::Optional<std::string> &_filenameSASHA,
                                         const IceUtil::Optional<std::string> &_filenameSHINS,
                                         const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    W_LLOG("Provide implementation for datamgrMergeHeaders");
    Ice::Int status = EXIT_SUCCESS;
    Ice::CommunicatorPtr dataMgrIC;
    char Arg1[] = "SequncerI::datamgrMergeHeaders";
    char Arg2[] = "--Ice.Config=/opt/tan/etc/data_mgr/data_mgr-ice.cfg";
    char *argvDataMgr[] = { Arg1, Arg2 };
    int argcDataMgr = 2;

    try
    {
        dataMgrIC = Ice::initialize(argcDataMgr, argvDataMgr);
        Ice::ObjectPrx base = dataMgrIC->stringToProxy("dataManagerAdapter:default -p 10501");
        sd::fitsFilePrx archiver = sd::fitsFilePrx::checkedCast(base);
        if(!archiver)
            throw("Invalid Proxy");

        status = archiver->mergeHeaders(_filenameSASHA, _filenameSHINS);

    }
    catch(const Ice::Exception &ex)
    {
        E_LLOG(ex.what());
        status = EXIT_FAILURE;
    }
    catch(const char *msg)
    {
        E_LLOG(msg);
        status = EXIT_FAILURE;
    }
    if(dataMgrIC)
        dataMgrIC->destroy();

    U8_LLOG("");
    return status;
}


Ice::Int SequencerI::datamgrArchiveFITS(const IceUtil::Optional<std::string> &_absFileName, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_SUCCESS;
    Ice::CommunicatorPtr dataMgrIC;
    char Arg1[] = "SequncerI::datamgrArchiveFITS";
    char Arg2[] = "--Ice.Config=/opt/tan/etc/data_mgr/data_mgr-ice.cfg";
    char *argvDataMgr[] = { Arg1, Arg2 };
    int argcDataMgr = 2;

    try
    {
        dataMgrIC = Ice::initialize(argcDataMgr, argvDataMgr);
        Ice::ObjectPrx base = dataMgrIC->stringToProxy("dataManagerAdapter:default -p 10501");
        sd::fitsFilePrx archiver = sd::fitsFilePrx::checkedCast(base);
        if(!archiver)
            throw("Invalid Proxy");

        status = archiver->fitsToArchive(_absFileName);
    }
    catch(const Ice::Exception &ex)
    {
        E_LLOG(ex.what());
        status = EXIT_FAILURE;
    }
    catch(const char *msg)
    {
        E_LLOG(msg);
        status = EXIT_FAILURE;
    }
    if(dataMgrIC)
        dataMgrIC->destroy();

    U8_LLOG("");
    return status;
}






//       ###############        #########           #########
//       ###############      #############       #############
//       ###############     ###############     ###############
//       ###############     ###############     ###############
//       ###############     ###############     ###############
//       ###############     ######    #####     ######    #####
//            #####          #####               #####      ##
//            #####          #####                #####
//            #####          #####                 #####
//            #####          #####                  #####
//            #####          #####                   #####
//            #####          #####                    #####
//            #####          #####                     #####
//            #####          #####                      #####
//            #####          #####                       #####
//            #####          #####                        #####
//            #####          #####                 ##      #####
//            #####          ######    #####     #####    ######
//            #####          ###############     ###############
//            #####          ###############     ###############
//            #####          ###############     ###############
//            #####           #############       #############
//            #####             #########           #########






Ice::Int SequencerI::BinocularControl(const std::string &_flag, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqTcs->BinocularControl(_flag);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


// Ice::Int SequencerI::PresetTelescopeWithAO(const lbto::position2 &_target, const lbto::position2 &_guide,
//    const lbto::position2 &_AOreference, const std::string &_telescopeMode, const std::string &_AOmode, const Ice::Current &_c)
Ice::Int SequencerI::PresetTelescope(const dictTelescopeSetup &_tel_setup, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqTcs->PresetTelescope(_tel_setup);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::OffsetPointing(const dictTelescopeSetup &_tel_setup, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqTcs->OffsetPointing(_tel_setup);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


/* RunAO input - _mode: can be "NORMAL", "REPOINT", "SKIPREF", "SKIPSTART", "SKIPSTARTREPOINT", "SKIPALL" */
Ice::Int SequencerI::RunAO(const dictTelescopeSetup &_tel_setup, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqTcs->RunAO(_tel_setup);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::SendWavefront(const lbto::SeqWF &_zernikeC, const std::string &_ope, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqTcs->SendWavefront(_zernikeC, _ope);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::MoveFocus(Ice::Double _absPos, const std::string &_ope, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqTcs->MoveFocus(_absPos, _ope);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::OffsetZAO(Ice::Double _deltaZ, const std::string& _side, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqTcs->OffsetZAO(_deltaZ, _side);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::OffsetXYAO(Ice::Double DeltaX, Ice::Double DeltaY, const std::string & _side, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqTcs->OffsetXYAO(DeltaX, DeltaY, _side);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::ApplyWaffleAO(const dictTelescopeSetup &_telSup, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqTcs->ApplyWaffleAO(_telSup);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::setDdParameters(const dictTelescopeSetup & DdEntries, sharknir::SeqString & outMsgs, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        lbto::result res;
        lbto::DDstruct dd;
        lbto::SeqDD DDEntries;
        dictTelescopeSetup::const_iterator itEntry;
        for(itEntry = DdEntries.begin(); itEntry != DdEntries.end(); itEntry++)
        {
            dd.DDname = itEntry->first;
            dd.DDkey = itEntry->second;
            DDEntries.push_back(dd);
        }
        res = m_seqTcs->getIifInterface()->iifSetParameter(DDEntries);
        outMsgs = res.resmsg;
        status = res.rescode;
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::getDdParameters(const sharknir::SeqString & seqEntries, sharknir::SeqString & outMsgs, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        lbto::result res;
        lbto::DDstruct dd;
        lbto::SeqDD DDEntries;
        sharknir::SeqString::const_iterator itEntry;
        for(itEntry = seqEntries.begin(); itEntry != seqEntries.end(); itEntry++)
        {
            dd.DDname = *itEntry;
            DDEntries.push_back(dd);
        }
        res = m_seqTcs->getIifInterface()->iifGetParameter(DDEntries);
        outMsgs = res.resmsg;
        status = res.rescode;
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


/* pointingCorrectionStart()
 * runs in separate threadfor the duration of observation.
 *
 * reads periodically position of target on teccam, if out of threshold
 * sends offset to telescope accordingly. Implementation from
 * SHARKNIR_gen_tec_PointingCorrection template */
Ice::Int SequencerI::pointingCorrectionStart(Ice::Float _freq, Ice::Int &_thrdID, const Ice::Current &_c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqTcs->pointingCorrectionStart(_freq, _thrdID);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


/* pointingCorrectionStop()
 * stops thread running pointing Correction, reference to thread must be provided by pointingCorrectionStart  */
Ice::Int SequencerI::pointingCorrectionStop(Ice::Int _thrdID, const Ice::Current&)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    Ice::Int status = EXIT_FAILURE;
    try
    {
        status = m_seqTcs->pointingCorrectionStop(_thrdID);
    }
    catch(...)
    {
        LogBoostDiagnosticInformation(__LINE__);
        U8_LLOG("");
        throw;
    }
    U8_LLOG(__FUNCTION__);
    return status;
}


Ice::Int SequencerI::setFlags(Ice::Int flags, Ice::Int moreFlags, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    m_seqDataMgr->setFlags(flags, moreFlags);
    m_seqTcs->setFlags(flags, moreFlags);
    m_tiptilt->setFlags(flags, moreFlags);
    m_track->setFlags(flags, moreFlags);
    U8_LLOG("");
    return EXIT_SUCCESS;
}
Ice::Int SequencerI::unsetFlags(Ice::Int flags, Ice::Int moreFlags, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    m_seqDataMgr->unsetFlags(flags, moreFlags);
    m_seqTcs->unsetFlags(flags, moreFlags);
    m_tiptilt->unsetFlags(flags, moreFlags);
    m_track->unsetFlags(flags, moreFlags);
    U8_LLOG("");
    return EXIT_SUCCESS;
}
Ice::Int SequencerI::toggleFlags(Ice::Int flags, Ice::Int moreFlags, const Ice::Current & _c)
{
    IceCallCounter callCounter(m_IceCallMutex, m_IceCallCounter);
    U6_LLOG(__FUNCTION__ << " ~ IceCallCounter : " << callCounter.getCounter());
    m_seqDataMgr->toggleFlags(flags, moreFlags);
    m_seqTcs->toggleFlags(flags, moreFlags);
    m_tiptilt->toggleFlags(flags, moreFlags);
    m_track->toggleFlags(flags, moreFlags);
    U8_LLOG("");
    return EXIT_SUCCESS;
}


