#ifndef _BASECOMPONENTCORE_H_ #define _BASECOMPONENTCORE_H_ /***********************************************************************\ IRA Istituto di Radioastronomia This code is under GNU General Public License (GPL). Andrea Orlati (andrea.orlati@inaf.it): Author \***********************************************************************/ #include "Configuration.h" #include #include #include #include #define NUMBER_OF_STAGES 1 #define PHYSICAL_FEEDS 3 #define KBAND_FEED 0 #define QBAND_FEED 1 #define WBAND_FEED 2 /** * This class extends the ReceiverControl class in order to include the bypass activation on the Wband RF chain to enable Sun observations * @author Andrea Orlati, * Istituto di Radioastronomia, Italia *
*/ class CKQWReceiverControl: public virtual IRA::ReceiverControl { public: CKQWReceiverControl(const std::string dewar_ip, const unsigned short dewar_port, const std::string lna_ip, const unsigned short lna_port, const unsigned int guard_time=250000, const unsigned short number_of_feeds=1) : ReceiverControl(dewar_ip,dewar_port,lna_ip,lna_port,guard_time,number_of_feeds) {} virtual ~CKQWReceiverControl() {} /** * @throw ReceiverControlEx */ bool enableBypass(); /** * @throw ReceiverControlEx */ bool disableBypass(); }; /** * This class contains the code of almost all the features of the component * @author Andrea Orlati, * Istituto di Radioastronomia, Italia *
*/ class CComponentCore { public: CComponentCore(); virtual ~CComponentCore(); /** * This method initializes the object * @param service pointer to container services object provided by the container */ virtual void initialize(maci::ContainerServices* services); /** * This method prepares the object for execution. * @return the pointer to the configuration class * @throw (ComponentErrors::CDBAccessExImpl, ComponentErrors::MemoryAllocationExImpl, ComponentErrors::SocketErrorExImpl, * ReceiversErrors::ModeErrorExImpl) */ virtual CConfiguration const * const execute(); /** * This function is responsible to free all allocated resources */ virtual void cleanup(); /* * It sets the local oscillators. Before commanding the new value * some check are done. The corresponding signal amplitude is computed. * @param lo lists of values for the local oscillator (MHz), one for each IF. * In that case just the first one is significant. In a -1 is passed the present value is kept. * @throw ComponentErrors::ValidationErrorExImpl * @throw ComponentErrors::ValueOutofRangeExImpl * @throw ComponentErrors::CouldntGetComponentExImpl * @throw ComponentErrors::CORBAProblemExImpl * @thorw ReceiversErrors::LocalOscillatorErrorExImpl */ void setLO(const ACS::doubleSeq& lo); /** * It activate the receiver, in other words it allows to setup the default configuration * and to make sure the LNA are turned on. * @throw ReceiversErrors::ModeErrorExImpl, * @throw ComponentErrors::ValidationErrorExImpl, * @throw ComponentErrors::ValueOutofRangeExImpl, * @throw ComponentErrors::CouldntGetComponentExImpl, * @throw ComponentErrors::CORBAProblemExImpl, * @throw ReceiversErrors::LocalOscillatorErrorExImpl, * @throw ReceiversErrors::NoRemoteControlErrorExImpl, * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void activate(); /** * It deactivates the receiver. * @throw ReceiversErrors::NoRemoteControlErrorExImpl * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void deactivate(); /** * It allows to compute the value of the calibration mark for any given sub bands in * the IF space. * @param result this the sequence of computed mark values, the first entry correspond to * first sub band and so on.... * @param, resFreq the sequence reports the initial observed sky frequency (MHz), the * first entry correspond to first sub band and so on.... * @param resBw the sequence reports the real bandwidth observed (MHz), the first entry * correspond to first sub band and so on.... * @param freqs list of start frequencies (MHz) * @param bandwidth list of the band widths (MHz) * @param feeds list of feed identifier, it allows to specifies form which feed the sub * band comes from. In that case it is neglected since the receiver is a single feed * @param ifs list of IF identifier, it allows to specifies from which receiver IF the * sub band comes from. * @param scale value to scale tsys measurement * @throw ComponentErrors::ValidationErrorExImpl * @throw ComponentErrors::ValueOutofRangeExImpl */ void getCalibrationMark( ACS::doubleSeq& result, ACS::doubleSeq& resFreq, ACS::doubleSeq& resBw, const ACS::doubleSeq& freqs, const ACS::doubleSeq& bandwidths, const ACS::longSeq& feeds, const ACS::longSeq& ifs, bool& onoff, double &scale ); /** * It is called to get the all the receiver output information in one call. * An output is identified by providing the feed and the IF identifier. It can process any number of requests at a time. * @param feeds is a list that stores the corresponding feed of the output we are asking for * @param ifs is a list that identifies which IFs of the feed we are interested in, usually 0..IFs-1 * @param freq used to return the start frequency of the band provided by the output the oscillator * (if present) is not added (MHz) * @param bw used to return the total provided bandwidth. (MHz) * @param pols it specifies the polarization of the receiver output, since ACS does not support for enum * sequences the correct value must be matched against the Receivers::TPolarization enumeration. * @param LO it gives (if present) the value of the local oscillator (MHz). * @throw ComponentErrors::ValidationErrorExImpl * @throw ComponentErrors::ValueOutofRangeExImpl */ void getIFOutput( const ACS::longSeq& feeds, const ACS::longSeq& ifs, ACS::doubleSeq& freqs, ACS::doubleSeq& bw, ACS::longSeq& pols, ACS::doubleSeq& LO ); /** * It computes the taper given a reference band. * @param freq start frequency of the reference band * @param bw width of the reference band * @param feed feed number * @param ifNumber IF chain identifier * @param waveLen wave length of the reference band, the band is transformed in a real sky * observed band and the the central frequency is taken. * @throw ComponentErrors::ValidationErrorExImpl * @thorw ComponentErrors::ValueOutofRangeExImpl */ double getTaper( const double& freq, const double& bw, const long& feed, const long& ifNumber, double& waveLen ); /** It turns the calibration diode on. * @throw ReceiversErrors::NoRemoteControlErrorExImpl * @throw ComponentErrors::ValidationErrorExImpl * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void calOn(); /** It turns the calibration diode off * @throw ReceiversErrors::NoRemoteControlErrorExImpl * @throw ComponentErrors::ValidationErrorExImpl * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void calOff(); /** It turns the external calibration diode on. * @throw ReceiversErrors::NoRemoteControlErrorExImpl * @throw ComponentErrors::ValidationErrorExImpl * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void externalCalOn(); /** It turns the external calibration diode off. * @throw ReceiversErrors::NoRemoteControlErrorExImpl * @throw ComponentErrors::ValidationErrorExImpl * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void externalCalOff(); /** It turns on the sensor for vacuum measurement. * @throw ReceiversErrors::NoRemoteControlErrorExImpl * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void vacuumSensorOn(); /** It turns off the sensor for vacuum measurement. * @throw ReceiversErrors::NoRemoteControlErrorExImpl * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl) */ void vacuumSensorOff(); /** It allows to turn LNA on * @throw ReceiversErrors::NoRemoteControlErrorExImpl * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl) */ void lnaOn(); /** It allows to turn LNA off * @throw ReceiversErrors::NoRemoteControlErrorExImpl * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl) */ void lnaOff(); /** * It reads and updates from the control board the current value of the vacuum * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void updateVacuum(); /** * It check if the vacuum pump is on and check is the status is fault or not (VACUUMPUMPFAULT) * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void updateVacuumPump(); /** * It checks if the vacuum valve is opened or not * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void updateVacuumValve(); /** * It reads and updates from the control board the current cryo temperature measured near the cool head * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void updateCryoCoolHead(); /** * It reads and updates from the control board the current cryo temperature measured near the cool head window * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void updateCryoCoolHeadWin(); /** * It reads and updates from the control board the current cryo temperature measured near the LNA */ void updateCryoLNA(); /** * It reads and updates from the control board the current cryo temperature measured near the LNA window * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void updateCryoLNAWin(); /** * It reads and updates from the control board the current vertex temperature * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void updateVertexTemperature(); /** * It checks if the Dewar power box is in remote or not * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void updateIsRemote(); /** * It checks if the cool head is turned on or not * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void updateCoolHead(); /** * It checks is the status of the noise mark correspond to the commanded status, * otherwise it sets the NOISEMARKERROR bit. It also check if the * external control of the noise mark has been enabled or not */ void updateNoiseMark(); /** * This method resumes the whole status of the component. It set the componentStatus member variable. */ void updateComponent(); /** * This is getter method. No need to make it thread safe...... * @return the current value of the vacuum in mbar */ double getVacuum() const { return m_vacuum; } /** * This is getter method. No need to make it thread safe...... * @return the current value of the cryogenic temperature at cool head in °K */ CConfiguration::BoardValue getCryoCoolHead() const { return m_cryoCoolHead; } /** * This is getter method. No need to make it thread safe...... * @return the current value of the cryogenic temperature at cool head window in °K */ CConfiguration::BoardValue getCryoCoolHeadWin() const { return m_cryoCoolHeadWin; } /** * This is getter method. No need to make it thread safe...... * @return the current value of the cryogenic temperature at LNA in °K */ CConfiguration::BoardValue getCryoLNA() const { return m_cryoLNA; } /** * This is getter method. No need to make it thread safe...... * @return the current value of the cryogenic temperature at LNA window in °K */ CConfiguration::BoardValue getCryoLNAWin() const { return m_cryoLNAWin; } /** * This is getter method. No need to make it thread safe...... * @return the current vertex temperature in °K */ CConfiguration::BoardValue getVertexTemperature() const { return m_envTemperature; } /** * This is getter method. No need to make it thread safe...... * @return the current status word */ DWORD getStatusWord() const { return m_statusWord; } /** * It returns the feed geometry of the receiver with respect to the central one. * For this implementation it is just a placeholder since there is just one feed. */ long getFeeds(ACS::doubleSeq& X, ACS::doubleSeq& Y, ACS::doubleSeq& power); /** * It returns the current operating mode of the receiver. * @return output string */ const IRA::CString& getActualMode(); /** * It returns the number of IF chains for each feed * @return output value */ const DWORD& getIFs(); /** * It returns the number of feeds * @return output value */ const DWORD& getFeeds(); /** * @return the status flag of the component */ const Management::TSystemStatus& getComponentStatus(); /** * Allows to set the "default_value" for the vacuum characteristic. In principle it is possible * to read it directly from CDB, but I found it more * comfortable to get it directly from the characteristic itself. */ inline void setVacuumDefault(const double& val) { m_vacuumDefault=val; } void getBandwidth(ACS::doubleSeq& bw); void getInitialFreq(ACS::doubleSeq& f); void getLocalOscillator(ACS::doubleSeq& lo); void getPolarizations(ACS::longSeq& pol); /** * It allows to change the operating mode of the receiver. * If the mode does not correspond to a valid mode an error is thrown. * @param mode mode code as a string * @throw ComponentErrors::ValidationErrorExImpl * @throw ComponentErrors::ValueOutofRangeExImpl * @throw ComponentErrors::CouldntGetComponentExImpl * @throw ComponentErrors::CORBAProblemExImpl * @throw ReceiversErrors::LocalOscillatorErrorExImpl * @throw ComponentErrors::CDBAccessExImpl * @throw ReceiversErrors::ModeErrorExImpl * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ virtual void setMode(const char * mode); /* * This method will update the last readout of the gate voltage parameters of the LNAs * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void updateVgLNAControls(); /* * This method will update the last readout of the drain voltage parameters of the LNAs * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void updateVdLNAControls(); /* * This method will update the last readout of the drain current parameters of the LNAs * @throw ReceiversErrors::ReceiverControlBoardErrorExImpl */ void updateIdLNAControls(); ACS::doubleSeq getStageValues(const IRA::ReceiverControl::FetValue& control, DWORD ifs, DWORD stage); protected: /** Obtain a valid reference to the local oscillator device * @throw ComponentErrors::CouldntGetComponentExImpl */ void loadLocalOscillator(Receivers::LocalOscillator_var& device,bool &fault,const IRA::CString& name); /** Used to free the reference to the local oscillator device */ void unloadLocalOscillator(Receivers::LocalOscillator_var& device,const IRA::CString& name); /************************ CONVERSION FUNCTIONS **************************/ // Convert the voltage value of the vacuum to mbar static double voltage2mbar(double voltage) { return(pow(10, 1.5 * voltage - 12)); } // Convert the voltage value of the temperatures to Kelvin static double voltage2Kelvin(double voltage) { return voltage < 1.12 ? \ (660.549422889947 * pow(voltage, 6)) - (2552.334255456860 * \ pow(voltage, 5)) + (3742.529989384570 * pow(voltage, 4)) - \ (2672.656926956470 * pow(voltage, 3)) + (947.905578508975 * \ pow(voltage, 2)) - 558.351002849576 * voltage + 519.607622398508 \ : (865.747519105672 * pow(voltage, 6)) - (7271.931957100480 * \ pow(voltage, 5)) + (24930.666241800500 * pow(voltage, 4)) - \ (44623.988512320400 * pow(voltage, 3)) + (43962.922216886600 * \ pow(voltage, 2)) - 22642.245121997700 * voltage + 4808.631312836750; } // Convert the voltage value of the temperatures to Celsius (Sensor B57703-10K) static double voltage2Celsius(double voltage) { return -5.9931 * pow(voltage, 5) + 40.392 * pow(voltage, 4) - 115.41 * pow(voltage, 3) + 174.67 * pow(voltage, 2) - 174.23 * voltage + 112.79; } // Convert the ID voltage value to the mA value static double currentConverter(double voltage) { return(10 * voltage); } // Convert the VD and VG voltage values using a right scale factor static double voltageConverter(double voltage) { return(voltage); } /********************** END CONVERSION FUNCTIONS ***********************/ enum TStatusBit { LOCAL=0, VACUUMSENSOR=1, VACUUMPUMPSTATUS=2, VACUUMPUMPFAULT=3, VACUUMVALVEOPEN=4, COOLHEADON=5, COMPRESSORFAULT=6, NOISEMARK=7, NOISEMARKERROR=8, EXTNOISEMARK=9, CONNECTIONERROR=10, UNLOCKED=11 }; /** This function will set the a status bit. It may be considered thread safe due to its definition */ inline void setStatusBit(TStatusBit bit) { m_statusWord |= 1 << bit; } /** This function will unset (clear) a status bit. It may be considered thread safe due to its definition */ inline void clearStatusBit(TStatusBit bit) { m_statusWord &= ~(1 << bit); } /** This function check is a bit is set or not. It may be considered thread safe due to its definition */ inline bool checkStatusBit(TStatusBit bit) { return m_statusWord & (1 << bit); } CConfiguration m_configuration; CKQWReceiverControl *m_control; // This object is thread safe BACIMutex m_mutex; //IRA::CString m_actualMode; //IRA::CString m_setupMode; private: maci::ContainerServices* m_services; Receivers::LocalOscillator_var m_localOscillatorDevice_K; bool m_localOscillatorFault_K; Receivers::LocalOscillator_var m_localOscillatorDevice_Q; bool m_localOscillatorFault_Q; Receivers::LocalOscillator_var m_localOscillatorDevice_WL; bool m_localOscillatorFault_WL; Receivers::LocalOscillator_var m_localOscillatorDevice_WH; bool m_localOscillatorFault_WH; //double m_localOscillatorValue; double m_vacuum; CConfiguration::BoardValue m_cryoCoolHead; CConfiguration::BoardValue m_cryoCoolHeadWin; CConfiguration::BoardValue m_cryoLNA; CConfiguration::BoardValue m_cryoLNAWin; CConfiguration::BoardValue m_envTemperature; std::vector m_vdStageValues; std::vector m_idStageValues; std::vector m_vgStageValues; double m_vacuumDefault; bool m_calDiode; IRA::ReceiverControl::FetValues m_fetValues; DWORD m_statusWord; // m_ioMarkError is a flag used to know if we already got an IO // error. bool m_ioMarkError; Management::TSystemStatus m_componentStatus; void setComponentStatus(const Management::TSystemStatus& status) { if (status>m_componentStatus) m_componentStatus=status; } double linearFit(ACS::doubleSeq& X,ACS::doubleSeq& Y, const WORD& size, double x) const; double linearFit(double *X,double *Y,const WORD& size,double x) const; }; #endif