CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/CalibTracker/SiStripDCS/src/SiStripDetVOffBuilder.cc

Go to the documentation of this file.
00001 #include "CalibTracker/SiStripDCS/interface/SiStripDetVOffBuilder.h"
00002 #include "boost/foreach.hpp"
00003 
00004 // constructor
00005 SiStripDetVOffBuilder::SiStripDetVOffBuilder(const edm::ParameterSet& pset, const edm::ActivityRegistry&) : 
00006   onlineDbConnectionString(pset.getParameter<std::string>("onlineDB")),
00007   authenticationPath(pset.getParameter<std::string>("authPath")),
00008   whichTable(pset.getParameter<std::string>("queryType")),
00009   lastValueFileName(pset.getParameter<std::string>("lastValueFile")),
00010   fromFile(pset.getParameter<bool>("lastValueFromFile")),
00011   psuDetIdMapFile_(pset.getParameter<std::string>("PsuDetIdMapFile")),
00012   debug_(pset.getParameter<bool>("debugModeOn")),
00013   tDefault(7,0),
00014   tmax_par(pset.getParameter< std::vector<int> >("Tmax")),
00015   tmin_par(pset.getParameter< std::vector<int> >("Tmin")),
00016   tset_par(pset.getParameter< std::vector<int> >("TSetMin")),
00017   detIdListFile_(pset.getParameter< std::string >("DetIdListFile")),
00018   excludedDetIdListFile_(pset.getParameter< std::string >("ExcludedDetIdListFile")),
00019   highVoltageOnThreshold_(pset.getParameter<double>("HighVoltageOnThreshold"))
00020 { 
00021   lastStoredCondObj.first = NULL;
00022   lastStoredCondObj.second = 0;
00023 
00024   edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::SiStripDetVOffBuilder] constructor" << endl;
00025 
00026   // set up vectors based on pset parameters (tDefault purely for initialization)
00027 
00028   whichQuery=(whichTable == "STATUSCHANGE" || (whichTable == "LASTVALUE" && !fromFile));
00029 
00030   //Define the query interval [Tmin, Tmax]
00031   //where Tmax comes from the cfg
00032   //      Tmin comes from the cfg for the first o2o, after that it is extracted from Offline DB 
00033 
00034   tmax = coral::TimeStamp(tmax_par[0],tmax_par[1],tmax_par[2],tmax_par[3],tmax_par[4],tmax_par[5],tmax_par[6]);
00035 
00036   if (whichQuery) {
00037     // Is there a better way to do this?  TODO - investigate
00038     tmin=coral::TimeStamp(tmin_par[0],tmin_par[1],tmin_par[2],tmin_par[3],tmin_par[4],tmin_par[5],tmin_par[6]);
00039   }
00040   
00041   if (whichTable == "LASTVALUE") {
00042     tsetmin = coral::TimeStamp(tset_par[0],tset_par[1],tset_par[2],tset_par[3],tset_par[4],tset_par[5],tset_par[6]);
00043   }
00044   
00045   if (onlineDbConnectionString == "") {
00046     edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::SiStripDetVOffBuilder] DB name has not been set properly ... Returning ...";
00047     return;
00048   }
00049   
00050   if (fromFile && whichTable == "LASTVALUE" && lastValueFileName == "") {
00051     edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::SiStripDetVOffBuilder] File expected for lastValue table, but filename not specified ... Returning ...";
00052     return;
00053   }
00054   
00055   // write out the parameters
00056   std::stringstream ss;
00057   ss << "[SiStripDetVOffBuilder::SiStripDetVOffBuilder]\n" 
00058      << "     Parameters:\n" 
00059      << "     DB connection string: " << onlineDbConnectionString << "\n"
00060      << "     Authentication path: "  << authenticationPath       << "\n"
00061      << "     Table to be queried: "  << whichTable               << "\n";
00062   
00063   if (whichQuery){
00064     ss << "     Tmin: "; printPar(ss,tmin_par);  ss << std::endl;
00065   }
00066   ss << "     Tmax: "  ; printPar(ss,tmax_par);  ss << std::endl;
00067 
00068   if (whichTable == "LASTVALUE"){ 
00069     ss << "     TSetMin: "; printPar(ss,tset_par);  ss << std::endl;
00070   }
00071    edm::LogError("SiStripDetVOffBuilder") << ss.str();
00072 
00073 }
00074 
00075 // destructor
00076 SiStripDetVOffBuilder::~SiStripDetVOffBuilder() { 
00077   edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::" << __func__ << "]: destructing ...";
00078 }
00079 
00080 void SiStripDetVOffBuilder::printPar(std::stringstream& ss, const std::vector<int>& par){
00081   BOOST_FOREACH(int val, par){
00082     ss << val << " ";
00083   }
00084 }
00085 
00086 void SiStripDetVOffBuilder::BuildDetVOffObj()
00087 {
00088   // vectors for storing output from DB or text file
00089   TimesAndValues timesAndValues;
00090 
00091   // Open the PVSS DB connection
00092   coralInterface.reset( new SiStripCoralIface(onlineDbConnectionString, authenticationPath, debug_) );
00093   edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Query type is " << whichTable << endl;
00094 
00095   if (whichTable == "LASTVALUE") {edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Use file? " << ((fromFile) ? "TRUE" : "FALSE");}
00096 
00097   if (lastStoredCondObj.second > 0) {edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: retrieved last time stamp from DB: " 
00098                                                                             << lastStoredCondObj.second  << endl;}
00099   // access the information!
00100 
00101   if (whichQuery) {
00102     if( whichTable == "STATUSCHANGE" ) {
00103       statusChange( lastStoredCondObj.second, timesAndValues );
00104     }
00105     if( whichTable == "LASTVALUE" ) {
00106       if( fromFile ) {
00107         lastValueFromFile(timesAndValues);
00108       }
00109       else {
00110         lastValue(timesAndValues);
00111       }
00112     }
00113   }
00114 
00115   DetIdListTimeAndStatus dStruct;
00116 
00117   // build PSU - det ID map
00118   buildPSUdetIdMap(timesAndValues, dStruct);
00119 
00120 
00121   // initialize variables
00122   modulesOff.clear();
00123   cond::Time_t saveIovTime = 0;
00124   
00125 
00126   // - If there is already an object stored in the database
00127   // -- store it in the modulesOff vector
00128   // -- set the saveIovTime as that
00129   // -- set the payload stats to empty
00130   // Successivamente:
00131   // - loop su tutti gli elementi del detidV, che è stato letto dal pvss (questi elementi sono pair<vettore di detid, time>)
00132   // -- setta il tempo dell'IOV:
00133   // --- LASTVALUE -> iovtime settato a latestTime
00134   // --- altrimenti iovtime = tempo associato al detId vector del loop
00135 
00136 
00137   // check if there is already an object stored in the DB
00138   // This happens only if you are using STATUSCHANGE
00139   if (lastStoredCondObj.first != NULL && lastStoredCondObj.second > 0) {
00140     modulesOff.push_back( lastStoredCondObj );
00141     saveIovTime = lastStoredCondObj.second;
00142     setPayloadStats(0, 0, 0);
00143   }
00144 
00145 
00146   for (unsigned int i = 0; i < dStruct.detidV.size(); i++) {
00147 
00148     //     std::vector<uint32_t> detids = dStruct.detidV[i].first;
00149     //     removeDuplicates(detids);
00150     std::vector<uint32_t> * detids = &(dStruct.detidV[i].first);
00151 
00152     // set the condition time for the transfer
00153     cond::Time_t iovtime = 0;
00154 
00155     if (whichTable == "LASTVALUE") {iovtime = timesAndValues.latestTime;}
00156 
00157     else {iovtime = getCondTime((dStruct.detidV[i]).second);}
00158 
00159     // decide how to initialize modV
00160     SiStripDetVOff *modV = 0;
00161 
00162     // When using STATUSCHANGE they are equal only for the first
00163     // When using LASTVALUE they are equal only if the tmin was set to tsetmin
00164 
00165     if (iovtime != saveIovTime) { // time is different, so create new object
00166 
00167       // This can be only when using LASTVALUE or with a new tag
00168       if (modulesOff.empty()) {
00169         // create completely new object and set the initial state to Tracker all off
00170         modV = new SiStripDetVOff();
00171 
00172         // Use the file
00173         edm::FileInPath fp(detIdListFile_);
00174         SiStripDetInfoFileReader reader(fp.fullPath());
00175         const std::map<uint32_t, SiStripDetInfoFileReader::DetInfo > detInfos  = reader.getAllData();
00176 
00177         // Careful: if a module is in the exclusion list it must be ignored and the initial status is set to ON.
00178         // These modules are expected to not be in the PSU-DetId map, so they will never get any status change from the query.
00179         SiStripPsuDetIdMap map;
00180         std::vector< std::pair<uint32_t, std::string> > excludedDetIdMap;
00181         if( excludedDetIdListFile_ != "" ) {
00182           map.BuildMap(excludedDetIdListFile_, excludedDetIdMap);
00183         }
00184         for(std::map<uint32_t, SiStripDetInfoFileReader::DetInfo >::const_iterator it = detInfos.begin(); it != detInfos.end(); ++it) {
00185           std::vector< std::pair<uint32_t, std::string> >::const_iterator exclIt = excludedDetIdMap.begin();
00186           bool excluded = false;
00187           for( ; exclIt != excludedDetIdMap.end(); ++exclIt ) {
00188             if( it->first == exclIt->first ) {
00189               excluded = true;
00190               break;
00191             }
00192           }
00193           if( !excluded ) {
00194             modV->put( it->first, 1, 1 );
00195           }
00196         }
00197 
00198       }
00199       else {modV = new SiStripDetVOff( *(modulesOff.back().first) );} // start from copy of previous object
00200     }
00201     else {
00202       modV = (modulesOff.back()).first; // modify previous object
00203     }
00204 
00205 
00206     
00207     // extract the detID vector before modifying for stats calculation
00208     std::vector<uint32_t> beforeV;
00209     modV->getDetIds(beforeV);
00210 
00211     std::pair<int, int> hvlv = extractDetIdVector(i, modV, dStruct);
00212 
00213     for (unsigned int j = 0; j < detids->size(); j++) {
00214       if( debug_ ) cout << "at time = " << iovtime << " detid["<<j<<"] = " << (*detids)[j] << " has hv = " << hvlv.first << " and lv = " << hvlv.second << endl;
00215       modV->put((*detids)[j],hvlv.first,hvlv.second);
00216     }
00217 
00218     // calculate the stats for storage
00219     unsigned int numAdded = 0, numRemoved = 0;
00220     if (iovtime == saveIovTime) {
00221       std::vector<uint32_t> oldStats = payloadStats.back();
00222       numAdded = oldStats[1];
00223       numRemoved = oldStats[2];
00224     }
00225     std::vector<uint32_t> afterV;
00226     modV->getDetIds(afterV);
00227     
00228     if ((afterV.size() - beforeV.size()) > 0) {
00229       numAdded += afterV.size() - beforeV.size();
00230     } else if ((beforeV.size() - afterV.size()) > 0) {
00231       numRemoved += beforeV.size() - afterV.size();
00232     }
00233 
00234     
00235     // store the object if it's a new object
00236     if (iovtime != saveIovTime) {
00237       SiStripDetVOff * testV = 0;
00238       if (!modulesOff.empty()) {testV = modulesOff.back().first;}
00239       if (modulesOff.empty() ||  !(*modV == *testV) ) {
00240         modulesOff.push_back( std::make_pair(modV,iovtime) );
00241         // save the time of the object
00242         saveIovTime = iovtime;
00243         // save stats
00244         setPayloadStats(afterV.size(), numAdded, numRemoved);
00245       }
00246     } else {
00247       (payloadStats.back())[0] = afterV.size();
00248       (payloadStats.back())[1] = numAdded;
00249       (payloadStats.back())[2] = numRemoved;
00250     }
00251   }
00252 
00253 
00254   // compare the first element and the last from previous transfer
00255   if (lastStoredCondObj.first != NULL && lastStoredCondObj.second > 0) {
00256     if ( lastStoredCondObj.second == modulesOff[0].second &&
00257          *(lastStoredCondObj.first) == *(modulesOff[0].first) ) {
00258       std::vector< std::pair<SiStripDetVOff*,cond::Time_t> >::iterator moIt = modulesOff.begin();
00259       modulesOff.erase(moIt);
00260       std::vector< std::vector<uint32_t> >::iterator plIt = payloadStats.begin();
00261       payloadStats.erase(plIt);
00262     }
00263   }
00264   
00265   if (debug_) {
00266     std::cout << std::endl;
00267     std::cout << "Size of modulesOff = " << modulesOff.size() << std::endl;
00268     for (unsigned int i = 0; i < modulesOff.size(); i++) {
00269       std::vector<uint32_t> finalids;
00270       (modulesOff[i].first)->getDetIds(finalids);
00271       std::cout << "Index = " << i << " Size of DetIds vector = " << finalids.size() << std::endl;
00272       std::cout << "Time = " << modulesOff[i].second << std::endl;
00273       for (unsigned int j = 0; j < finalids.size(); j++) {
00274         std::cout << "detid = " << finalids[j] << " LV off = " << (modulesOff[i].first)->IsModuleLVOff(finalids[j]) << " HV off = " 
00275                   << (modulesOff[i].first)->IsModuleHVOff(finalids[j]) << std::endl;
00276       }
00277     }
00278   }
00279 }
00280 
00281 int SiStripDetVOffBuilder::findSetting(uint32_t id, coral::TimeStamp changeDate, std::vector<uint32_t> settingID, std::vector<coral::TimeStamp> settingDate) {
00282   int setting = -1;
00283   // find out how many channel entries there are
00284   std::vector<int> locations;
00285   for (unsigned int i = 0; i < settingID.size(); i++) { if (settingID[i] == id) {locations.push_back((int)i);} }
00286 
00287   // simple cases
00288   if (locations.size() == 0) {setting = -1;}
00289   else if (locations.size() == 1) {setting = locations[0];}
00290   // more than one entry for this channel
00291   // NB.  entries ordered by date!
00292   else {
00293     for (unsigned int j = 0; j < locations.size(); j++) {
00294 #ifdef USING_NEW_CORAL
00295       const boost::posix_time::ptime& testSec = changeDate.time();
00296       const boost::posix_time::ptime& limitSec = settingDate[(unsigned int)locations[j]].time();
00297 #else
00298       long testSec = changeDate.time().ns();
00299       long limitSec = settingDate[(unsigned int)locations[j]].time().ns();
00300 #endif
00301       if (testSec >= limitSec) {setting = locations[j];}
00302     }
00303   }
00304   return setting;
00305 }
00306 
00307 int SiStripDetVOffBuilder::findSetting(std::string dpname, coral::TimeStamp changeDate, std::vector<std::string> settingDpname, std::vector<coral::TimeStamp> settingDate) {
00308   int setting = -1;
00309   // find out how many channel entries there are
00310   std::vector<int> locations;
00311   for (unsigned int i = 0; i < settingDpname.size(); i++) { if (settingDpname[i] == dpname) {locations.push_back((int)i);} }
00312   
00313   // simple cases
00314   if (locations.size() == 0) {setting = -1;}
00315   else if (locations.size() == 1) {setting = locations[0];}
00316   // more than one entry for this channel
00317   // NB.  entries ordered by date!
00318   else {
00319     for (unsigned int j = 0; j < locations.size(); j++) {
00320 #ifdef USING_NEW_CORAL
00321       const boost::posix_time::ptime& testSec = changeDate.time();
00322       const boost::posix_time::ptime& limitSec = settingDate[(unsigned int)locations[j]].time();
00323 #else
00324       long testSec = changeDate.time().ns();
00325       long limitSec = settingDate[(unsigned int)locations[j]].time().ns();
00326 #endif
00327       if (testSec >= limitSec) {setting = locations[j];}
00328     }
00329   }
00330   return setting;
00331 }
00332 
00333 void SiStripDetVOffBuilder::readLastValueFromFile(std::vector<uint32_t> &dpIDs, std::vector<float> &vmonValues, std::vector<coral::TimeStamp> &dateChange) {
00334   std::ifstream lastValueFile(lastValueFileName.c_str());
00335   if (lastValueFile.bad()) {
00336     edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::" << __func__ << "]: last Value file does not exist!";
00337     return;
00338   }
00339 
00340   dpIDs.clear();
00341   vmonValues.clear();
00342   dateChange.clear();
00343   std::vector<std::string> changeDates;
00344 
00345   std::string line;
00346   // remove the first line as it is the title line
00347   //  std::getline(lastValueFile,line);
00348   //  line.clear();
00349   // now extract data
00350   while( std::getline(lastValueFile,line) ) {
00351     std::istringstream ss(line);
00352     uint32_t dpid;
00353     float vmon;
00354     std::string changeDate;
00355     ss >> std::skipws >> dpid >> vmon >> changeDate;
00356     dpIDs.push_back(dpid);
00357     vmonValues.push_back(vmon);
00358     changeDates.push_back(changeDate);
00359   }
00360   lastValueFile.close();  
00361 
00362   // Now convert dates to coral::TimeStamp
00363   for (unsigned int i = 0; i < changeDates.size(); i++) {
00364     std::string part = changeDates[i].substr(0,4);
00365     int year = atoi(part.c_str());
00366     part.clear();
00367 
00368     part = changeDates[i].substr(5,2);
00369     int month = atoi(part.c_str());
00370     part.clear();
00371 
00372     part = changeDates[i].substr(8,2);
00373     int day = atoi(part.c_str());
00374     part.clear();
00375 
00376     part = changeDates[i].substr(11,2);
00377     int hour = atoi(part.c_str());
00378     part.clear();
00379 
00380     part = changeDates[i].substr(14,2);
00381     int minute = atoi(part.c_str());
00382     part.clear();
00383 
00384     part = changeDates[i].substr(17,2);
00385     int second = atoi(part.c_str());
00386     part.clear();
00387 
00388     coral::TimeStamp date(year,month,day,hour,minute,second,0);
00389     dateChange.push_back(date);
00390   }
00391 
00392   if (changeDates.size() != dateChange.size()) {edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::" << __func__ << "]: date conversion failed!!";}
00393 }
00394 
00395 cond::Time_t SiStripDetVOffBuilder::getCondTime(coral::TimeStamp coralTime) {
00396 
00397   // const boost::posix_time::ptime& t = coralTime.time();
00398   cond::Time_t condTime = cond::time::from_boost(coralTime.time());
00399 
00400   // cout << "[SiStripDetVOffBuilder::getCondTime] Converting CoralTime into CondTime: "
00401   //      << " coralTime = (coralTimeInNs) " <<  coralTime.total_nanoseconds() << " condTime " << (condTime>> 32) << " - " << (condTime & 0xFFFFFFFF) << endl;
00402 
00403   return condTime;
00404 }
00405 
00406 coral::TimeStamp SiStripDetVOffBuilder::getCoralTime(cond::Time_t iovTime)
00407 {
00408   // This method is defined in the TimeConversions header and it does the following:
00409   // - takes the seconds part of the iovTime (bit-shifting of 32)
00410   // - adds the nanoseconds part (first 32 bits mask)
00411   // - adds the time0 that is the time from begin of times (boost::posix_time::from_time_t(0);)
00412   coral::TimeStamp coralTime(cond::time::to_boost(iovTime));
00413 
00414   if( debug_ ) {
00415     unsigned long long iovSec = iovTime >> 32;
00416     uint32_t iovNanoSec = uint32_t(iovTime);
00417     cond::Time_t testTime=getCondTime(coralTime);
00418     cout << "[SiStripDetVOffBuilder::getCoralTime] Converting CondTime into CoralTime: "
00419          << " condTime = " <<  iovSec << " - " << iovNanoSec 
00420          << " getCondTime(coralTime) = " << (testTime>>32) << " - " << (testTime&0xFFFFFFFF)  << endl;
00421   }
00422 
00423   return coralTime;
00424 }
00425 
00426 void SiStripDetVOffBuilder::removeDuplicates( std::vector<uint32_t> & vec ) {
00427   std::sort(vec.begin(),vec.end());
00428   std::vector<uint32_t>::iterator it = std::unique(vec.begin(),vec.end());
00429   vec.resize( it - vec.begin() );
00430 }
00431 
00432 void SiStripDetVOffBuilder::setLastSiStripDetVOff( SiStripDetVOff * lastPayload, cond::Time_t lastTimeStamp ) {
00433   lastStoredCondObj.first = lastPayload;
00434   lastStoredCondObj.second = lastTimeStamp;
00435 }
00436 
00437 cond::Time_t SiStripDetVOffBuilder::findMostRecentTimeStamp( std::vector<coral::TimeStamp> coralDate ) {
00438   cond::Time_t latestDate = getCondTime(coralDate[0]);
00439   
00440   if( debug_ ) {
00441     std::cout << "latestDate: condTime = " 
00442               << (latestDate>>32) 
00443               << " - " 
00444               << (latestDate&0xFFFFFFFF) 
00445       //<< " coralTime= " << coralDate[0] 
00446               << std::endl;
00447   }
00448 
00449   for (unsigned int i = 1; i < coralDate.size(); i++) {
00450     cond::Time_t testDate = getCondTime(coralDate[i]);
00451     if (testDate > latestDate) {
00452       latestDate = testDate;
00453     }
00454   }
00455   return latestDate;
00456 }
00457 
00458 void SiStripDetVOffBuilder::reduce( std::vector< std::pair<SiStripDetVOff*,cond::Time_t> >::iterator & it,
00459                                     std::vector< std::pair<SiStripDetVOff*,cond::Time_t> >::iterator & initialIt,
00460                                     std::vector< std::pair<SiStripDetVOff*,cond::Time_t> > & resultVec,
00461                                     const bool last )
00462 {
00463   int first = 0;
00464   // Check if it is the first
00465   if( distance(resultVec.begin(), initialIt) == 0 ) {
00466     first = 1;
00467   }
00468 
00469   if( debug_ && ( it->first->getLVoffCounts() - initialIt->first->getLVoffCounts() == 0 ) && ( it->first->getHVoffCounts() - initialIt->first->getHVoffCounts() == 0 ) ) {
00470     cout << "Same number of LV and HV at start and end of sequence: LV off = " << it->first->getLVoffCounts() << " HV off = " << it->first->getHVoffCounts() << endl;
00471   }
00472 
00473   // if it was going off
00474   if( ( it->first->getLVoffCounts() - initialIt->first->getLVoffCounts() > 0 ) || ( it->first->getHVoffCounts() - initialIt->first->getHVoffCounts() > 0 ) ) {
00475     // Set the time of the current (last) iov as the time of the initial iov of the sequence
00476     // replace the first iov with the last one
00477     (it+last)->second = (initialIt)->second;
00478     discardIOVs(it, initialIt, resultVec, last, 0);
00479     if( debug_ ) cout << "going off" << endl;
00480   }
00481   // if it was going on
00482   else if( ( it->first->getLVoffCounts() - initialIt->first->getLVoffCounts() <= 0 ) || ( it->first->getHVoffCounts() - initialIt->first->getHVoffCounts() <= 0 ) ) {
00483     // replace the last minus one iov with the first one
00484     discardIOVs(it, initialIt, resultVec, last, first);
00485     if( debug_ ) cout << "going on" << endl;
00486   }
00487 }
00488 
00489 void SiStripDetVOffBuilder::discardIOVs( std::vector< std::pair<SiStripDetVOff*,cond::Time_t> >::iterator & it,
00490                                          std::vector< std::pair<SiStripDetVOff*,cond::Time_t> >::iterator & initialIt,
00491                                          std::vector< std::pair<SiStripDetVOff*,cond::Time_t> > & resultVec,
00492                                          const bool last, const unsigned int first )
00493 {
00494   if( debug_ ) {
00495     cout << "first = " << first << endl;
00496     cout << "initial->first = " << initialIt->first << ", second  = " << initialIt->second << endl;
00497     cout << "last = " << last << endl;
00498   }
00499   if( last == true ) {
00500     resultVec.erase(initialIt+first, it+1);
00501     // Minus 2 because it will be incremented at the end of the loop becoming end()-1.
00502     it = resultVec.end()-2;
00503   }
00504   else {
00505     it = resultVec.erase(initialIt+first, it);
00506   }
00507 }
00508 
00509 void SiStripDetVOffBuilder::reduction(const uint32_t deltaTmin, const uint32_t maxIOVlength)
00510 {
00511   int count = 0;
00512   std::vector< std::pair<SiStripDetVOff*,cond::Time_t> >::iterator initialIt;
00513 
00514   int resultVecSize = modulesOff.size();
00515   int resultsIndex = 0;
00516 
00517   if( resultVecSize > 1 ) {
00518   std::vector< std::pair<SiStripDetVOff*,cond::Time_t> >::iterator it = modulesOff.begin();
00519     for( ; it != modulesOff.end()-1; ++it, ++resultsIndex ) {
00520       unsigned long long deltaT = ((it+1)->second - it->second) >> 32;
00521       unsigned long long deltaTsequence = 0;
00522       if( count > 1 ) {
00523         deltaTsequence = ((it+1)->second - initialIt->second) >> 32;
00524       }
00525       // Save the initial pair
00526       if( (deltaT < deltaTmin) && ( (count == 0) || ( deltaTsequence < maxIOVlength ) ) ) {
00527         // If we are not in a the sequence
00528         if( count == 0 ) {
00529           initialIt = it;
00530         }
00531         // Increase the counter in any case.
00532         ++count;
00533       }
00534       // We do it only if the sequence is bigger than two cases
00535       else if( count > 1 ) {
00536         reduce(it, initialIt, modulesOff);
00537         // reset all
00538         count = 0;
00539       }
00540       else {
00541         // reset all
00542         count = 0;
00543       }
00544       // Border case
00545       if( resultsIndex == resultVecSize-2 && count != 0 ) {
00546         reduce(it, initialIt, modulesOff, true);
00547       }
00548     }
00549   }
00550 }
00551 
00552 void SiStripDetVOffBuilder::statusChange( cond::Time_t & lastTime, TimesAndValues & tStruct )
00553 {
00554   // Setting tmin to the last value IOV of the database tag
00555   if( lastTime > 0 ) {
00556     tmin = getCoralTime(lastTime);
00557   }
00558   
00559   coralInterface->doQuery(whichTable, tmin ,tmax, tStruct.changeDate, tStruct.actualValue, tStruct.dpname);
00560 
00561   // preset the size of the status vector
00562   tStruct.actualStatus.resize(tStruct.actualValue.size());
00563   tStruct.actualStatus.clear();
00564   
00565   BOOST_FOREACH(float val, tStruct.actualValue) {
00566     tStruct.actualStatus.push_back(static_cast<int>(val));
00567   }
00568 }
00569 
00570 void SiStripDetVOffBuilder::lastValue(TimesAndValues & tStruct)
00571 {
00572   coralInterface->doQuery(whichTable, tmin ,tmax, tStruct.changeDate, tStruct.actualValue, tStruct.dpname);
00573   
00574   tStruct.latestTime = findMostRecentTimeStamp( tStruct.changeDate );
00575   
00576   // preset the size of the status vector
00577   tStruct.actualStatus.resize(tStruct.actualValue.size());
00578   
00579   // retrieve the channel settings from the PVSS DB
00580   std::vector<coral::TimeStamp> settingDate;
00581   std::vector<float> settingValue;
00582   std::vector<std::string> settingDpname;
00583   std::vector<uint32_t> settingDpid;
00584   coralInterface->doSettingsQuery(tsetmin,tmax,settingDate,settingValue,settingDpname,settingDpid);
00585   LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Channel settings retrieved";
00586   LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Number of PSU channels: " << settingDpname.size();
00587     
00588   unsigned int missing = 0;
00589   std::stringstream ss;
00590   for (unsigned int j = 0; j < tStruct.dpname.size(); j++) {
00591     int setting = findSetting(tStruct.dpname[j],tStruct.changeDate[j],settingDpname,settingDate);
00592     if (setting >= 0) {
00593       if (tStruct.actualValue[j] > (highVoltageOnThreshold_*(settingValue[setting]))) {tStruct.actualStatus[j] = 1;}
00594       else {tStruct.actualStatus[j] = 0;}
00595     } else {
00596       tStruct.actualStatus[j] = -1;
00597       missing++;
00598       ss << "Channel = " << tStruct.dpname[j] << std::endl;
00599     }
00600   }
00601   LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Number of channels with no setting information " << missing;
00602   LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Number of entries in dpname vector " << tStruct.dpname.size();
00603 }
00604 
00605 void SiStripDetVOffBuilder::lastValueFromFile(TimesAndValues & tStruct)
00606 {
00607   readLastValueFromFile(tStruct.dpid,tStruct.actualValue,tStruct.changeDate);
00608   tStruct.latestTime = findMostRecentTimeStamp( tStruct.changeDate );
00609   LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: File access complete \n\t Number of values read from file: " << tStruct.dpid.size();
00610   
00611   // retrieve the channel settings from the PVSS DB
00612   std::vector<coral::TimeStamp> settingDate;
00613   std::vector<float> settingValue;
00614   std::vector<std::string> settingDpname;
00615   std::vector<uint32_t> settingDpid;
00616   
00617   coralInterface->doSettingsQuery(tsetmin,tmax,settingDate,settingValue,settingDpname,settingDpid);
00618   LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Channel settings retrieved";
00619   LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Number of PSU channels: " << settingDpname.size();
00620   
00621   unsigned int missing = 0;
00622   std::stringstream ss;
00623   // need to get the PSU channel names from settings
00624   tStruct.dpname.clear();
00625   tStruct.dpname.resize(tStruct. dpid.size());
00626   for (unsigned int j = 0; j < tStruct.dpid.size(); j++) {
00627     int setting = findSetting(tStruct.dpid[j],tStruct.changeDate[j],settingDpid,settingDate);
00628     if (setting >= 0) {
00629       if (tStruct.actualValue[j] > (highVoltageOnThreshold_*settingValue[setting])) {tStruct.actualStatus[j] = 1;}
00630       else {
00631         tStruct.actualStatus[j] = 0;
00632       }
00633       tStruct.dpname[j] = settingDpname[setting];
00634     } else {
00635       tStruct.actualStatus[j] = -1;
00636       tStruct.dpname[j] = "UNKNOWN";
00637       missing++;
00638       ss << "DP ID = " << tStruct.dpid[j] << std::endl;
00639     }
00640   }
00641   LogDebug("SiStripDetVOffBuilder") << "Number of missing psu channels = " << missing << std::endl;
00642   LogDebug("SiStripDetVOffBuilder") << "IDs are: = " << ss.str();
00643 }
00644 
00645 string SiStripDetVOffBuilder::timeToStream(const cond::Time_t & condTime, const string & comment)
00646 {
00647   stringstream ss;
00648   ss << comment << (condTime>> 32) << " - " << (condTime & 0xFFFFFFFF) << std::endl;
00649   return ss.str();
00650 }
00651 
00652 string SiStripDetVOffBuilder::timeToStream(const coral::TimeStamp & coralTime, const string & comment)
00653 {
00654   stringstream ss;
00655   ss << "Starting from IOV time in the database : year = " << coralTime.year()
00656      << ", month = " << coralTime.month()
00657      << ", day = " << coralTime.day()
00658      << ", hour = " << coralTime.hour()
00659      << ", minute = " << coralTime.minute()
00660      << ", second = " << coralTime.second()
00661      << ", nanosecond = " << coralTime.nanosecond() << std::endl;
00662   return ss.str();
00663 }
00664 
00665 void SiStripDetVOffBuilder::buildPSUdetIdMap(TimesAndValues & psuStruct, DetIdListTimeAndStatus & detIdStruct)
00666 {
00667   SiStripPsuDetIdMap map_;
00668   if( psuDetIdMapFile_ == "" ) {
00669     map_.BuildMap();
00670   }
00671   else {
00672     map_.BuildMap(psuDetIdMapFile_);
00673   }
00674   LogTrace("SiStripDetVOffBuilder") <<"[SiStripDetVOffBuilder::BuildDetVOff] DCU-DET ID map built";
00675   map_.printMap();
00676 
00677   // use map info to build input for list of objects
00678   // no need to check for duplicates, as put method for SiStripDetVOff checks for you!
00679   
00680   unsigned int ch0bad = 0, ch1bad = 0, ch2bad = 0, ch3bad = 0;
00681   std::vector<unsigned int> numLvBad, numHvBad;
00682 
00683   for (unsigned int dp = 0; dp < psuStruct.dpname.size(); dp++) {
00684     if (psuStruct.dpname[dp] != "UNKNOWN") {
00685 
00686       // figure out the channel
00687       std::string board = psuStruct.dpname[dp];
00688       std::string::size_type loc = board.size()-10;
00689       board.erase(0,loc);
00690       // now store!
00691       std::vector<uint32_t> ids = map_.getDetID(psuStruct.dpname[dp]);
00692 
00693       if( debug_ ) cout << "dbname["<<dp<<"] = " << psuStruct.dpname[dp] << ", for time = " << timeToStream(psuStruct.changeDate[dp]) << std::endl;
00694 
00695       if (!ids.empty()) {
00696         // DCU-PSU maps only channel000 and channel000 and channel001 switch on and off together
00697         // so check only channel000
00698         //      if (board == "channel000" || board == "channel001") {
00699         if (board == "channel000") {
00700           detIdStruct.detidV.push_back( std::make_pair(ids,psuStruct.changeDate[dp]) );
00701           if (psuStruct.actualStatus[dp] != 1) {
00702             //      if (board == "channel000") {ch0bad++;}
00703             //      if (board == "channel001") {ch1bad++;}
00704             ++ch0bad;
00705             ++ch1bad;
00706             detIdStruct.StatusGood.push_back(false);
00707             numLvBad.insert(numLvBad.end(),ids.begin(),ids.end());
00708           }
00709           else {
00710             detIdStruct.StatusGood.push_back(true);
00711           }
00712           detIdStruct.isHV.push_back(0);
00713           detIdStruct.psuName.push_back( psuStruct.dpname[dp] );
00714         }
00715         else if( board == "channel002" || board == "channel003" ) {
00716           detIdStruct.detidV.push_back( std::make_pair(ids,psuStruct.changeDate[dp]) );
00717           if( debug_ ) cout << "actualStatus = " << psuStruct.actualStatus[dp] << " for psu: " << psuStruct.dpname[dp] << endl;
00718           if (psuStruct.actualStatus[dp] != 1) {
00719             if (board == "channel002") {ch2bad++;}
00720             if (board == "channel003") {ch3bad++;}
00721             detIdStruct.StatusGood.push_back(false);
00722             numHvBad.insert(numHvBad.end(),ids.begin(),ids.end());
00723           }
00724           else {
00725             detIdStruct.StatusGood.push_back(true);
00726           }
00727           detIdStruct.isHV.push_back(1);
00728           detIdStruct.psuName.push_back( psuStruct.dpname[dp] );
00729         }
00730         else {
00731           if (board != "channel001") {
00732             LogTrace("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::" << __func__ << "] channel name not recognised! " << board;
00733           }
00734         }
00735       }
00736     } else {
00737       detIdStruct.notMatched++;
00738     }
00739   }
00740 
00741   removeDuplicates(numLvBad);
00742   removeDuplicates(numHvBad);
00743 
00744   // useful debugging stuff!
00745   if( debug_ ) {
00746     std::cout << "Bad 000 = " << ch0bad << " Bad 001 = " << ch1bad << std::endl;
00747     std::cout << "Bad 002 = " << ch0bad << " Bad 003 = " << ch1bad << std::endl;
00748     std::cout << "Number of bad LV detIDs = " << numLvBad.size() << std::endl;
00749     std::cout << "Number of bad HV detIDs = " << numHvBad.size() << std::endl;
00750   }
00751 
00752   LogTrace("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::" << __func__ << "]: Number of PSUs retrieved from DB with map information    " << detIdStruct.detidV.size();
00753   LogTrace("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::" << __func__ << "]: Number of PSUs retrieved from DB with no map information " << detIdStruct.notMatched;
00754   
00755   unsigned int dupCount = 0;
00756   for (unsigned int t = 0; t < numLvBad.size(); t++) {
00757     std::vector<unsigned int>::iterator iter = std::find(numHvBad.begin(),numHvBad.end(),numLvBad[t]);
00758     if (iter != numHvBad.end()) {dupCount++;}
00759   }
00760   if( debug_ ) std::cout << "Number of channels with LV & HV bad = " << dupCount << std::endl;
00761 }
00762 
00763 void SiStripDetVOffBuilder::setPayloadStats(const uint32_t afterV, const uint32_t numAdded, const uint32_t numRemoved)
00764 {
00765   std::vector<uint32_t> pStats(3,0);
00766   pStats.push_back(afterV);
00767   pStats.push_back(numAdded);
00768   pStats.push_back(numRemoved);
00769   payloadStats.push_back(pStats);
00770 }
00771 
00772 pair<int, int> SiStripDetVOffBuilder::extractDetIdVector( const unsigned int i, SiStripDetVOff * modV, DetIdListTimeAndStatus & detIdStruct )
00773 {
00774   // set the LV and HV off flags ready for storing
00775   int lv_off = -1, hv_off = -1;
00776   if (detIdStruct.isHV[i] == 0) {lv_off = !(detIdStruct.StatusGood[i]);}
00777   if (detIdStruct.isHV[i] == 1) {
00778     hv_off = !(detIdStruct.StatusGood[i]);
00779 
00780     // TESTING WITHOUT THE FIX
00781     // -----------------------
00782 
00783     if( psuDetIdMapFile_ == "" ) {
00784       // temporary fix to handle the fact that we don't know which HV channel the detIDs are associated to
00785       if (i > 0) {
00786         std::string iChannel = detIdStruct.psuName[i].substr( (detIdStruct.psuName[i].size()-3) );
00787         std::string iPsu = detIdStruct.psuName[i].substr(0, (detIdStruct.psuName[i].size()-3) );
00788         if (iChannel == "002" || iChannel == "003") {
00789           bool lastStatusOfOtherChannel = true;
00790           for (unsigned int j = 0; j < i; j++) {
00791             std::string jPsu = detIdStruct.psuName[j].substr(0, (detIdStruct.psuName[j].size()-3) );
00792             std::string jChannel = detIdStruct.psuName[j].substr( (detIdStruct.psuName[j].size()-3) );
00793             if (iPsu == jPsu && iChannel != jChannel && (jChannel == "002" || jChannel == "003")) {
00794               if( debug_ ) cout << "psu["<<i<<"] = " << detIdStruct.psuName[i] << " with status = " << detIdStruct.StatusGood[i] << " and psu["<<j<<"] = " << detIdStruct.psuName[j] << " with status " << detIdStruct.StatusGood[j] << endl;
00795               lastStatusOfOtherChannel = detIdStruct.StatusGood[j];
00796             }
00797           }
00798           if (detIdStruct.StatusGood[i] != lastStatusOfOtherChannel) {
00799             if( debug_ ) cout << "turning off hv" << endl;
00800             hv_off = 1;
00801           }
00802         }
00803       }
00804     }
00805 
00806     // -----------------------
00807 
00808   }
00809 
00810   return make_pair(hv_off, lv_off);
00811 }