/* * dbVoltageChannel.cc * * Created on: July 28, 2014 * Author: Hovanes Egiyan */ #include "dbVoltageChannel.hh" #include "mpv8008lChannel.hh" #include "mpv8016Channel.hh" #include "mpv8030lChannel.hh" #include "mpv8120lChannel.hh" #include "ehsf201pfChannel.hh" #include "ehsf205pfChannel.hh" #include "iuBaseChannel.hh" #include "CaenHVChannel.hh" #include "mpvDoubletChannel.hh" #include "mpvTripletChannel.hh" // SQL String to find the crate for a channel QString dbVoltageChannel::sqlFindModuleType = "SELECT " " Channel.chanid as chid, Module.type as mtype , Channel.col_name as chtype " " FROM Channel JOIN " " Module ON Channel.moduleid = Module.moduleid, " " Detector_Hierarchy ON Channel.chanid = Detector_Hierarchy.chanid" " WHERE Detector_Hierarchy.id='%1' "; map dbVoltageChannel::instanceFunMap; static volatile int dummyInt = dbVoltageChannel::initInstMap(); //dbChannel::dbChannel(string uri, int subsystemID, dbSubsystem* parent) : // dbSubsystem(uri, subsystemID, parent), // chanID(0), moduleType(""), typedChanObj(0) { // this->getChannelProperties(); // typedChanObj = (instanceFunMap[this->moduleType])(uri, chanID); //} // Constructor of a channel using the base class subsystem as argument dbVoltageChannel::dbVoltageChannel( dbSubsystem* subsystem, string mType, string name, string func ) : subsystemPtr(subsystem), chanID(0), moduleType(mType), chanFunc(func), typedChanObj(0) { // cout << "Copied Id is " << id << endl; cout << "Building dbChannel for <" << subsystem->getFullPath() << "> with type <" << mType << "> name <" << name << "> and functionality <" << func << ">"<< endl; try { // If module type is specified in the constructor as MT string // then the module type needs to be read from the DB. Otherwise, // it is take from the constructor argument and chanid stays zero. if( mType == "" ) { getChannelProperties(); } // cout << "Got channel properties, module type is " << this->moduleType // << " full path is " << getFullPath(":") << endl; if (instanceFunMap.count(moduleType) < 1) { // Raise an exception if there are no module types in the module map stringstream errMsg; errMsg << "Error: Do not know anything about module type " << moduleType << ". Did you forget to add it to the list of constructors?" << endl; qWarning() << errMsg.str().c_str() << endl; throw StringException(errMsg.str()); } cout << "Creating object for module type <" << moduleType << "> with name <" << name << "> with full name <" << subsystemPtr->getFullPath() << ">" << endl; cout << "Sending pointer " << hex << this << dec << " to the new object " << endl; // Here we build the object of subclass of baseChannel using the string value to determine which type to build string chanName = name; if( name == "" ) chanName = subsystemPtr->getFullPath(":"); if( func != "" ) chanFunc = func; typedChanObj = (instanceFunMap[this->moduleType])(subsystemPtr->getURI(), chanName, subsystemPtr, chanID); // typedChanObj->SetSubsystemID( id ); cout << "Object has been build" << endl; return; } catch (NoModuleTypeException& e) { cout << e.what() << endl; cout << "There is no channel to match this leaf" << endl; throw e; } } dbVoltageChannel::~dbVoltageChannel() { if( typedChanObj != 0 ) delete typedChanObj; } int dbVoltageChannel::getChannelProperties() { subsystemPtr->checkDB(); QSqlQuery query(subsystemPtr->getDatabase()); // Search for the crate in the DB for this particular channel using unique ID QString sqlString = sqlFindModuleType.arg(subsystemPtr->getID()); // qWarning() << sqlString << endl; query.prepare(sqlString); query.exec(); // qDebug() << "The query has been executed" << endl; if ( dbObject::sqlSize(query) > 1) { // Raise an exception if there are too many rows from the previous SQL // There has to be only one entry in the table for each unique id stringstream errMsg; errMsg << "Error: Too many crates for the id " << subsystemPtr->getID() << " , to be exact there are " << dbObject::sqlSize(query) ; qWarning() << errMsg.str().c_str() << endl; throw StringException(errMsg.str()); } if( query.next() ) { chanID = query.value(0).toInt(); moduleType = query.value(1).toString().toStdString(); chanFunc = query.value(2).toString().toStdString(); } else { // Raise an exception if there are no raws for this channel stringstream errMsg; errMsg << "Error: No channels found for the subsystem id " << subsystemPtr->getID() << endl; qWarning() << errMsg.str().c_str() << endl; throw NoModuleTypeException(errMsg.str()); } return 0; } void dbVoltageChannel::loadRecords( string detPrefix, string iocPrefix ) { typedChanObj->loadRecords( detPrefix, iocPrefix ); cout << "EPICS DB loaded for subsystem channel " << subsystemPtr->getFullPath() << endl; } // Define points to template functions for instantiating actual board objects. int dbVoltageChannel::initInstMap() { // CAEN SY1527 board channels instanceFunMap["A1535SN"] = &createChannel; instanceFunMap["A1535N"] = &createChannel; instanceFunMap["A1550N"] = &createChannel; instanceFunMap["A1550P"] = &createChannel; instanceFunMap["A7236SN"] = &createChannel; instanceFunMap["A7435N"] = &createChannel; instanceFunMap["A7030N"] = &createChannel; // MPOD LV board channels instanceFunMap["MPV8008L"] = &createChannel; instanceFunMap["MPV8030"] = &createChannel; instanceFunMap["MPV8030L"] = &createChannel; instanceFunMap["MPV8016" ] = &createChannel; instanceFunMap["MPV8120" ] = &createChannel; instanceFunMap["MPV8120L"] = &createChannel; // Coupled channels for MPOD LV channels instanceFunMap["MPV_DOUBLET"] = &createChannel; instanceFunMap["MPV_TRIPLET"] = &createChannel; // MPOD EHS board channels instanceFunMap["EHSF201PF" ] = &createChannel; instanceFunMap["EHSF205PF" ] = &createChannel; // Our SQLite DB has only ISEG key in them instanceFunMap["ISEG" ] = &createChannel; // IU board channels instanceFunMap["IU_BASE_BUS" ] = &createChannel; return 0; }