CMS 3D CMS Logo

SiStripDetVOffBuilder.cc
Go to the documentation of this file.
2 #include "boost/foreach.hpp"
3 #include <sys/stat.h>
4 
5 // constructor
7  onlineDbConnectionString(pset.getParameter<std::string>("onlineDB")),
8  authenticationPath(pset.getParameter<std::string>("authPath")),
9  whichTable(pset.getParameter<std::string>("queryType")),
10  lastValueFileName(pset.getParameter<std::string>("lastValueFile")),
11  fromFile(pset.getParameter<bool>("lastValueFromFile")),
12  psuDetIdMapFile_(pset.getParameter<std::string>("PsuDetIdMapFile")),
13  debug_(pset.getParameter<bool>("debugModeOn")),
14  tDefault(7,0),
15  tmax_par(pset.getParameter< std::vector<int> >("Tmax")),
16  tmin_par(pset.getParameter< std::vector<int> >("Tmin")),
17  tset_par(pset.getParameter< std::vector<int> >("TSetMin")),
18  deltaTmin_(pset.getParameter<uint32_t>("DeltaTmin")),
19  maxIOVlength_(pset.getParameter<uint32_t>("MaxIOVlength")),
20  detIdListFile_(pset.getParameter< std::string >("DetIdListFile")),
21  excludedDetIdListFile_(pset.getParameter< std::string >("ExcludedDetIdListFile")),
22  highVoltageOnThreshold_(pset.getParameter<double>("HighVoltageOnThreshold"))
23 {
24  lastStoredCondObj.first = nullptr;
25  lastStoredCondObj.second = 0;
26 
27  edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::SiStripDetVOffBuilder] constructor" << endl;
28 
29  // set up vectors based on pset parameters (tDefault purely for initialization)
30 
31  whichQuery=(whichTable == "STATUSCHANGE" || (whichTable == "LASTVALUE" && !fromFile));
32 
33  //Define the query interval [Tmin, Tmax]
34  //where Tmax comes from the cfg
35  // Tmin comes from the cfg for the first o2o, after that it is extracted from Offline DB
36 
37  tmax = coral::TimeStamp(tmax_par[0],tmax_par[1],tmax_par[2],tmax_par[3],tmax_par[4],tmax_par[5],tmax_par[6]);
38 
39  if (whichQuery) {
40  // Is there a better way to do this? TODO - investigate
41  tmin=coral::TimeStamp(tmin_par[0],tmin_par[1],tmin_par[2],tmin_par[3],tmin_par[4],tmin_par[5],tmin_par[6]);
42  }
43 
44  if (whichTable == "LASTVALUE") {
45  tsetmin = coral::TimeStamp(tset_par[0],tset_par[1],tset_par[2],tset_par[3],tset_par[4],tset_par[5],tset_par[6]);
46  }
47 
48  if (onlineDbConnectionString == "") {
49  edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::SiStripDetVOffBuilder] DB name has not been set properly ... Returning ...";
50  return;
51  }
52 
53  if (fromFile && whichTable == "LASTVALUE" && lastValueFileName == "") {
54  edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::SiStripDetVOffBuilder] File expected for lastValue table, but filename not specified ... Returning ...";
55  return;
56  }
57 
58  // write out the parameters
59  std::stringstream ss;
60  ss << "[SiStripDetVOffBuilder::SiStripDetVOffBuilder]\n"
61  << " Parameters:\n"
62  << " DB connection string: " << onlineDbConnectionString << "\n"
63  << " Authentication path: " << authenticationPath << "\n"
64  << " Table to be queried: " << whichTable << "\n"
65  << " MapFile: " << psuDetIdMapFile_ << "\n";
66 
67  if (whichQuery){
68  ss << " Tmin: "; printPar(ss,tmin_par); ss << std::endl;
69  }
70  ss << " Tmax: " ; printPar(ss,tmax_par); ss << std::endl;
71 
72  if (whichTable == "LASTVALUE"){
73  ss << " TSetMin: "; printPar(ss,tset_par); ss << std::endl;
74  }
75  edm::LogError("SiStripDetVOffBuilder") << ss.str();
76 
77 }
78 
79 // destructor
81  edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::" << __func__ << "]: destructing ...";
82 }
83 
84 void SiStripDetVOffBuilder::printPar(std::stringstream& ss, const std::vector<int>& par){
85  BOOST_FOREACH(int val, par){
86  ss << val << " ";
87  }
88 }
89 
91 {
92  // vectors for storing output from DB or text file
93  TimesAndValues timesAndValues;
94 
95  // Open the PVSS DB connection
97  edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Query type is " << whichTable << endl;
98 
99  if (whichTable == "LASTVALUE") {edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Use file? " << ((fromFile) ? "TRUE" : "FALSE");}
100 
101  if (lastStoredCondObj.second > 0) {edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: retrieved last time stamp from DB: "
102  << lastStoredCondObj.second << endl;}
103  // access the information!
104  //We've been using the STATUSCHANGE query only in last year or so... LASTVALUE may have untested issues...
105  //In either case the idea is that the results of the query are saved into the timesAndValues struct
106  //ready to be anaylized (i.e. translated into detIDs, HV/LV statuses)
107 
108  if (whichQuery) {
109  if( whichTable == "STATUSCHANGE" ) {
110  statusChange( lastStoredCondObj.second, timesAndValues );
111  }
112  if( whichTable == "LASTVALUE" ) {
113  if( fromFile ) {
114  lastValueFromFile(timesAndValues);
115  }
116  else {
117  lastValue(timesAndValues);
118  }
119  }
120  }
121 
122  //Initialize the stuct that will be used to keep the detID-translated information
123  DetIdListTimeAndStatus dStruct;
124 
125  // build PSU - det ID map
126  //The following method actually "builds" 4 maps: LVMap, HVMap, HVUnmapped_Map, HVCrosstalking_Map.
127  //It also takes the timesAndValues from the query above and using the maps, it processes the information
128  //populating the DetIDListTimeAndStatus struct that will hold the information by detid.
129  buildPSUdetIdMap(timesAndValues, dStruct);
130 
131 
132  // initialize variables
133  modulesOff.clear();
134  cond::Time_t saveIovTime = 0;
135 
136 
137  // - If there is already an object stored in the database
138  // -- store it in the modulesOff vector
139  // -- set the saveIovTime as that
140  // -- set the payload stats to empty
141  // Successivamente:
142  // - loop su tutti gli elementi del detidV, che stato letto dal pvss (questi elementi sono pair<vettore di detid, time>)
143  // -- setta il tempo dell'IOV:
144  // --- LASTVALUE -> iovtime settato a latestTime
145  // --- altrimenti iovtime = tempo associato al detId vector del loop
146 
147 
148  // check if there is already an object stored in the DB
149  // This happens only if you are using STATUSCHANGE
150  if (lastStoredCondObj.first != nullptr && lastStoredCondObj.second > 0) {
151  modulesOff.push_back( lastStoredCondObj );
152  saveIovTime = lastStoredCondObj.second;
153  setPayloadStats(0, 0, 0);
154  }
155 
156 
157  //Master loop over all the results of the query stored in the dStruct (that contains vectors with vectors of detids, statuses, isHV flags, etc and in particular a vector of timestamps for which the info is valid... basically it is a loop over the timestamps (i.e. IOVs).
158  for (unsigned int i = 0; i < dStruct.detidV.size(); i++) {
159 
160  // std::vector<uint32_t> detids = dStruct.detidV[i].first;
161  // removeDuplicates(detids);
162  std::vector<uint32_t> * detids = &(dStruct.detidV[i].first);
163 
164  // set the condition time for the transfer
165  cond::Time_t iovtime = 0;
166 
167  if (whichTable == "LASTVALUE") {iovtime = timesAndValues.latestTime;}
168 
169  else {iovtime = getCondTime((dStruct.detidV[i]).second);}
170 
171  // decide how to initialize modV
172  SiStripDetVOff *modV = nullptr;
173 
174  // When using STATUSCHANGE they are equal only for the first
175  // When using LASTVALUE they are equal only if the tmin was set to tsetmin
176 
177  if (iovtime != saveIovTime) { // time is different, so create new object
178 
179  // This can be only when using LASTVALUE or with a new tag
180  if (modulesOff.empty()) {
181  // create completely new object and set the initial state to Tracker all off
182  modV = new SiStripDetVOff();
183 
184  // Use the file
187  const std::map<uint32_t, SiStripDetInfoFileReader::DetInfo >& detInfos = reader.getAllData();
188 
189  //FIXME:
190  //Following code is actually broken (well not until the cfg has "" for excludedDetIDListFile parameter!
191  //Fix it if felt necessary (remember that it assumes that whatever detids are excluded should NOT be in the regular map
192  //breaking our current situation with a fully mapped (LV-wise) tracker...
193  // Careful: if a module is in the exclusion list it must be ignored and the initial status is set to ON.
194  // These modules are expected to not be in the PSU-DetId map, so they will never get any status change from the query.
196  std::vector< std::pair<uint32_t, std::string> > excludedDetIdMap;
197  if( excludedDetIdListFile_ != "" ) {
198  map.BuildMap(excludedDetIdListFile_, excludedDetIdMap);
199  }
200  for(std::map<uint32_t, SiStripDetInfoFileReader::DetInfo >::const_iterator it = detInfos.begin(); it != detInfos.end(); ++it) {
201  std::vector< std::pair<uint32_t, std::string> >::const_iterator exclIt = excludedDetIdMap.begin();
202  bool excluded = false;
203  for( ; exclIt != excludedDetIdMap.end(); ++exclIt ) {
204  if( it->first == exclIt->first ) {
205  excluded = true;
206  break;
207  }
208  }
209  if( !excluded ) {
210  modV->put( it->first, 1, 1 );
211  }
212  }
213 
214  }
215  else {modV = new SiStripDetVOff( *(modulesOff.back().first) );} // start from copy of previous object
216  }
217  else {
218  modV = (modulesOff.back()).first; // modify previous object (TEST THIS if possible! it's fundamental in handling changes at the edges of O2O executions and also in case of PVSS DB buffering!
219  }
220 
221 
222 
223  // extract the detID vector before modifying for stats calculation
224  std::vector<uint32_t> beforeV;
225  modV->getDetIds(beforeV);
226 
227  //CHECKTHIS
228  //The following method call is potentially problematic:
229  //passing modV as argument while extracting information about dStruct,
230  //modV is not currently used in the method!
231  std::pair<int, int> hvlv = extractDetIdVector(i, modV, dStruct);//Returns a pair like this HV OFF->1,-1 HV ON->0,-1 LV OFF->-1,1 LV ON->-1,0
232  //Basically a LV OFF of -1 means that the information (IOV) in question is from an HV channel turning on or off and viceversa for an HVOFF of -1.
233  //This could be confusing when reading the debug output!
234 
235  for (unsigned int j = 0; j < detids->size(); j++) {
236  if( debug_ ) cout << "at time = " << iovtime << " detid["<<j<<"] = " << (*detids)[j] << " has hv = " << hvlv.first << " and lv = " << hvlv.second << endl;
237  modV->put((*detids)[j],hvlv.first,hvlv.second);
238  }
239 
240  // calculate the stats for storage
241  unsigned int numAdded = 0, numRemoved = 0;
242  if (iovtime == saveIovTime) {
243  std::vector<uint32_t> oldStats = payloadStats.back();
244  numAdded = oldStats[1];
245  numRemoved = oldStats[2];
246  }
247  std::vector<uint32_t> afterV;
248  modV->getDetIds(afterV);
249 
250  if ((afterV.size() - beforeV.size()) > 0) {
251  numAdded += afterV.size() - beforeV.size();
252  } else if ((beforeV.size() - afterV.size()) > 0) {
253  numRemoved += beforeV.size() - afterV.size();
254  }
255 
256 
257  // store the object if it's a new object
258  if (iovtime != saveIovTime) {
259  SiStripDetVOff * testV = nullptr;
260  if (!modulesOff.empty()) {testV = modulesOff.back().first;}
261  if (modulesOff.empty() || !(*modV == *testV) ) {
262  modulesOff.push_back( std::make_pair(modV,iovtime) );
263  // save the time of the object
264  saveIovTime = iovtime;
265  // save stats
266  setPayloadStats(afterV.size(), numAdded, numRemoved);
267  } else {
268  // modV will not be used anymore, DELETE it to avoid memory leak!
269  delete modV;
270  }
271  } else {
272  (payloadStats.back())[0] = afterV.size();
273  (payloadStats.back())[1] = numAdded;
274  (payloadStats.back())[2] = numRemoved;
275  }
276  }
277 
278 
279  // compare the first element and the last from previous transfer
280  if (lastStoredCondObj.first != nullptr && lastStoredCondObj.second > 0) {
281  if ( *(lastStoredCondObj.first) == *(modulesOff[0].first) ) {
282  if ( modulesOff.size() == 1 ){
283  // if no HV/LV transition was found in this period: update the last IOV to be tmax
284  modulesOff[0].second = getCondTime(tmax);
285  }else{
286  // HV/LV transitions found: remove the first one (which came from previous transfer)
287  modulesOff.erase(modulesOff.begin());
288  payloadStats.erase(payloadStats.begin());
289  }
290  }
291  }
292 
293  if (debug_) {
294  std::cout << std::endl;
295  std::cout << "Size of modulesOff = " << modulesOff.size() << std::endl;
296  for (unsigned int i = 0; i < modulesOff.size(); i++) {
297  std::vector<uint32_t> finalids;
298  (modulesOff[i].first)->getDetIds(finalids);
299  std::cout << "Index = " << i << " Size of DetIds vector = " << finalids.size() << std::endl;
300  std::cout << "Time = " << modulesOff[i].second << std::endl;
301  for (unsigned int j = 0; j < finalids.size(); j++) {
302  std::cout << "detid = " << finalids[j] << " LV off = " << (modulesOff[i].first)->IsModuleLVOff(finalids[j]) << " HV off = "
303  << (modulesOff[i].first)->IsModuleHVOff(finalids[j]) << std::endl;
304  }
305  }
306  }
307 }
308 
309 int SiStripDetVOffBuilder::findSetting(uint32_t id, const coral::TimeStamp& changeDate, const std::vector<uint32_t>& settingID, const std::vector<coral::TimeStamp>& settingDate) {
310  int setting = -1;
311  // find out how many channel entries there are
312  std::vector<int> locations;
313  for (unsigned int i = 0; i < settingID.size(); i++) { if (settingID[i] == id) {locations.push_back((int)i);} }
314 
315  // simple cases
316  if (locations.empty()) {setting = -1;}
317  else if (locations.size() == 1) {setting = locations[0];}
318  // more than one entry for this channel
319  // NB. entries ordered by date!
320  else {
321  for (unsigned int j = 0; j < locations.size(); j++) {
322 #ifdef USING_NEW_CORAL
323  const boost::posix_time::ptime& testSec = changeDate.time();
324  const boost::posix_time::ptime& limitSec = settingDate[(unsigned int)locations[j]].time();
325 #else
326  long testSec = changeDate.time().ns();
327  long limitSec = settingDate[(unsigned int)locations[j]].time().ns();
328 #endif
329  if (testSec >= limitSec) {setting = locations[j];}
330  }
331  }
332  return setting;
333 }
334 
335 int SiStripDetVOffBuilder::findSetting(std::string dpname, const coral::TimeStamp& changeDate, const std::vector<std::string>& settingDpname, const std::vector<coral::TimeStamp>& settingDate) {
336  int setting = -1;
337  // find out how many channel entries there are
338  std::vector<int> locations;
339  for (unsigned int i = 0; i < settingDpname.size(); i++) { if (settingDpname[i] == dpname) {locations.push_back((int)i);} }
340 
341  // simple cases
342  if (locations.empty()) {setting = -1;}
343  else if (locations.size() == 1) {setting = locations[0];}
344  // more than one entry for this channel
345  // NB. entries ordered by date!
346  else {
347  for (unsigned int j = 0; j < locations.size(); j++) {
348 #ifdef USING_NEW_CORAL
349  const boost::posix_time::ptime& testSec = changeDate.time();
350  const boost::posix_time::ptime& limitSec = settingDate[(unsigned int)locations[j]].time();
351 #else
352  long testSec = changeDate.time().ns();
353  long limitSec = settingDate[(unsigned int)locations[j]].time().ns();
354 #endif
355  if (testSec >= limitSec) {setting = locations[j];}
356  }
357  }
358  return setting;
359 }
360 
361 void SiStripDetVOffBuilder::readLastValueFromFile(std::vector<uint32_t> &dpIDs, std::vector<float> &vmonValues, std::vector<coral::TimeStamp> &dateChange) {
362  std::ifstream lastValueFile(lastValueFileName.c_str());
363  if (lastValueFile.bad()) {
364  edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::" << __func__ << "]: last Value file does not exist!";
365  return;
366  }
367 
368  dpIDs.clear();
369  vmonValues.clear();
370  dateChange.clear();
371  std::vector<std::string> changeDates;
372 
374  // remove the first line as it is the title line
375  // std::getline(lastValueFile,line);
376  // line.clear();
377  // now extract data
378  while( std::getline(lastValueFile,line) ) {
379  std::istringstream ss(line);
380  uint32_t dpid;
381  float vmon;
382  std::string changeDate;
383  ss >> std::skipws >> dpid >> vmon >> changeDate;
384  dpIDs.push_back(dpid);
385  vmonValues.push_back(vmon);
386  changeDates.push_back(changeDate);
387  }
388  lastValueFile.close();
389 
390  // Now convert dates to coral::TimeStamp
391  for (unsigned int i = 0; i < changeDates.size(); i++) {
392  std::string part = changeDates[i].substr(0,4);
393  int year = atoi(part.c_str());
394  part.clear();
395 
396  part = changeDates[i].substr(5,2);
397  int month = atoi(part.c_str());
398  part.clear();
399 
400  part = changeDates[i].substr(8,2);
401  int day = atoi(part.c_str());
402  part.clear();
403 
404  part = changeDates[i].substr(11,2);
405  int hour = atoi(part.c_str());
406  part.clear();
407 
408  part = changeDates[i].substr(14,2);
409  int minute = atoi(part.c_str());
410  part.clear();
411 
412  part = changeDates[i].substr(17,2);
413  int second = atoi(part.c_str());
414  part.clear();
415 
416  coral::TimeStamp date(year,month,day,hour,minute,second,0);
417  dateChange.push_back(date);
418  }
419 
420  if (changeDates.size() != dateChange.size()) {edm::LogError("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::" << __func__ << "]: date conversion failed!!";}
421 }
422 
423 cond::Time_t SiStripDetVOffBuilder::getCondTime(const coral::TimeStamp& coralTime) {
424 
425  // const boost::posix_time::ptime& t = coralTime.time();
426  cond::Time_t condTime = cond::time::from_boost(coralTime.time());
427 
428  // cout << "[SiStripDetVOffBuilder::getCondTime] Converting CoralTime into CondTime: "
429  // << " coralTime = (coralTimeInNs) " << coralTime.total_nanoseconds() << " condTime " << (condTime>> 32) << " - " << (condTime & 0xFFFFFFFF) << endl;
430 
431  return condTime;
432 }
433 
435 {
436  // This method is defined in the TimeConversions header and it does the following:
437  // - takes the seconds part of the iovTime (bit-shifting of 32)
438  // - adds the nanoseconds part (first 32 bits mask)
439  // - adds the time0 that is the time from begin of times (boost::posix_time::from_time_t(0);)
440  coral::TimeStamp coralTime(cond::time::to_boost(iovTime));
441 
442  if( debug_ ) {
443  unsigned long long iovSec = iovTime >> 32;
444  uint32_t iovNanoSec = uint32_t(iovTime);
445  cond::Time_t testTime=getCondTime(coralTime);
446  cout << "[SiStripDetVOffBuilder::getCoralTime] Converting CondTime into CoralTime: "
447  << " condTime = " << iovSec << " - " << iovNanoSec
448  << " getCondTime(coralTime) = " << (testTime>>32) << " - " << (testTime&0xFFFFFFFF) << endl;
449  }
450 
451  return coralTime;
452 }
453 
454 void SiStripDetVOffBuilder::removeDuplicates( std::vector<uint32_t> & vec ) {
455  std::sort(vec.begin(),vec.end());
456  std::vector<uint32_t>::iterator it = std::unique(vec.begin(),vec.end());
457  vec.resize( it - vec.begin() );
458 }
459 
461  lastStoredCondObj.first = lastPayload;
462  lastStoredCondObj.second = lastTimeStamp;
463 }
464 
465 cond::Time_t SiStripDetVOffBuilder::findMostRecentTimeStamp( const std::vector<coral::TimeStamp>& coralDate ) {
466  cond::Time_t latestDate = getCondTime(coralDate[0]);
467 
468  if( debug_ ) {
469  std::cout << "latestDate: condTime = "
470  << (latestDate>>32)
471  << " - "
472  << (latestDate&0xFFFFFFFF)
473  //<< " coralTime= " << coralDate[0]
474  << std::endl;
475  }
476 
477  for (unsigned int i = 1; i < coralDate.size(); i++) {
478  cond::Time_t testDate = getCondTime(coralDate[i]);
479  if (testDate > latestDate) {
480  latestDate = testDate;
481  }
482  }
483  return latestDate;
484 }
485 
486 void SiStripDetVOffBuilder::reduce( std::vector< std::pair<SiStripDetVOff*,cond::Time_t> >::iterator & it,
487  std::vector< std::pair<SiStripDetVOff*,cond::Time_t> >::iterator & initialIt,
488  std::vector< std::pair<SiStripDetVOff*,cond::Time_t> > & resultVec,
489  const bool last )
490 {
491  //const bool last is set to false by default in the header file...
492  int first = 0;
493  // Check if it is the first
494  if( distance(resultVec.begin(), initialIt) == 0 ) {
495  first = 1;
496  }
497 
498  if( debug_ && ( it->first->getLVoffCounts() - initialIt->first->getLVoffCounts() == 0 ) && ( it->first->getHVoffCounts() - initialIt->first->getHVoffCounts() == 0 ) ) {
499  cout << "Same number of LV and HV at start and end of sequence: LV off = " << it->first->getLVoffCounts() << " HV off = " << it->first->getHVoffCounts() << endl;
500  }
501 
502  // if it was going off
503  if( ( it->first->getLVoffCounts() - initialIt->first->getLVoffCounts() > 0 ) || ( it->first->getHVoffCounts() - initialIt->first->getHVoffCounts() > 0 ) ) {
504  // Set the time of the current (last) iov as the time of the initial iov of the sequence
505  // replace the first iov with the last one
506  //Naughty use of const bool last... by default it is false (=0), and for the case of the last timestamp in the query results it is set to true(=1) in the call
507  (it+last)->second = (initialIt)->second;
508  discardIOVs(it, initialIt, resultVec, last, 0);
509  if( debug_ ) cout << "Reducing IOV sequence (going off)" << endl;
510  }
511  // if it was going on
512  else if( ( it->first->getLVoffCounts() - initialIt->first->getLVoffCounts() <= 0 ) || ( it->first->getHVoffCounts() - initialIt->first->getHVoffCounts() <= 0 ) ) {
513  // replace the last minus one iov with the first one
514  discardIOVs(it, initialIt, resultVec, last, first);
515  if( debug_ ) cout << "Reducing IOV sequence (going on)" << endl;
516  }
517 }
518 
519 void SiStripDetVOffBuilder::discardIOVs( std::vector< std::pair<SiStripDetVOff*,cond::Time_t> >::iterator & it,
520  std::vector< std::pair<SiStripDetVOff*,cond::Time_t> >::iterator & initialIt,
521  std::vector< std::pair<SiStripDetVOff*,cond::Time_t> > & resultVec,
522  const bool last, const unsigned int first )
523 {
524  if( debug_ ) {
525  cout << "first (1->means the sequence started at the first timestamp in the query results, 0-> that it did not)= " << first << endl;
526  cout << "initial->first (initial SiStripDetVOff object of the IOV sequence)= " << initialIt->first << ", second (initial timestamp of the IOV sequence) = " << initialIt->second << endl;
527  cout << "last (0->means that the sequence is not ending with the last item in the query results, 1-> that it DOES!)= " << last << endl;
528  }
529  if( last == true ) {
530  resultVec.erase(initialIt+first, it+1);
531  // Minus 2 because it will be incremented at the end of the loop becoming end()-1.
532  it = resultVec.end()-2;
533  }
534  else {
535  it = resultVec.erase(initialIt+first, it);
536  }
537 }
538 
539 //This is the method that (called by GetModulesOff, declared in the header file) executes the reduction by massaging modulesOff
540 void SiStripDetVOffBuilder::reduction(const uint32_t deltaTmin, const uint32_t maxIOVlength)
541 {
542 
543  int count = 0;
544  std::vector< std::pair<SiStripDetVOff*,cond::Time_t> >::iterator initialIt;
545 
546  int resultVecSize = modulesOff.size();
547  int resultsIndex = 0;
548 
549  if( resultVecSize > 1 ) {
550  std::vector< std::pair<SiStripDetVOff*,cond::Time_t> >::iterator it = modulesOff.begin();
551  for( ; it != modulesOff.end()-1; ++it, ++resultsIndex ) {
552  unsigned long long deltaT = ((it+1)->second - it->second) >> 32;
553  unsigned long long deltaTsequence = 0;
554  if( count > 1 ) {
555  deltaTsequence = ((it+1)->second - initialIt->second) >> 32;
556  }
557  // Save the initial pair
558  if( (deltaT < deltaTmin) && ( (count == 0) || ( deltaTsequence < maxIOVlength ) ) ) {
559  // If we are not in a the sequence
560  if( count == 0 ) {
561  initialIt = it;
562  }
563  // Increase the counter in any case.
564  ++count;
565  }
566  // We do it only if the sequence is bigger than two cases
567  else if( count > 1 ) {
568  reduce(it, initialIt, modulesOff);
569  // reset all
570  count = 0;
571  }
572  else {
573  // reset all
574  count = 0;
575  }
576  // Border case
577  if( resultsIndex == resultVecSize-2 && count != 0 ) {
578  reduce(it, initialIt, modulesOff, true);
579  }
580  }
581  }
582 }
583 
585 {
586  // Setting tmin to the last value IOV of the database tag
587  if( lastTime > 0 ) {
588  tmin = getCoralTime(lastTime);
589  }
590 
591  coralInterface->doQuery(whichTable, tmin ,tmax, tStruct.changeDate, tStruct.actualValue, tStruct.dpname);
592  //UNIT TEST DEBUG to bypass the query wait time!!!
593  //coral::TimeStamp testtime=getCoralTime(lastTime);
594  //tStruct.changeDate.push_back(testtime);
595  //tStruct.actualValue.push_back(1.);
596  //tStruct.dpname.push_back("cms_trk_dcs_03:CAEN/CMS_TRACKER_SY1527_3/branchController00/easyCrate3/easyBoard17/channel002");
597 
598  // preset the size of the status vector
599  tStruct.actualStatus.resize(tStruct.actualValue.size());
600  tStruct.actualStatus.clear();
601 
602  BOOST_FOREACH(float val, tStruct.actualValue) {
603  tStruct.actualStatus.push_back(static_cast<int>(val));
604  }
605 }
606 
608 {
609  coralInterface->doQuery(whichTable, tmin ,tmax, tStruct.changeDate, tStruct.actualValue, tStruct.dpname);
610 
611  tStruct.latestTime = findMostRecentTimeStamp( tStruct.changeDate );
612 
613  // preset the size of the status vector
614  tStruct.actualStatus.resize(tStruct.actualValue.size());
615 
616  // retrieve the channel settings from the PVSS DB
617  std::vector<coral::TimeStamp> settingDate;
618  std::vector<float> settingValue;
619  std::vector<std::string> settingDpname;
620  std::vector<uint32_t> settingDpid;
621  coralInterface->doSettingsQuery(tsetmin,tmax,settingDate,settingValue,settingDpname,settingDpid);
622  LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Channel settings retrieved";
623  LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Number of PSU channels: " << settingDpname.size();
624 
625  unsigned int missing = 0;
626  std::stringstream ss;
627  for (unsigned int j = 0; j < tStruct.dpname.size(); j++) {
628  int setting = findSetting(tStruct.dpname[j],tStruct.changeDate[j],settingDpname,settingDate);
629  if (setting >= 0) {
630  if (tStruct.actualValue[j] > (highVoltageOnThreshold_*(settingValue[setting]))) {tStruct.actualStatus[j] = 1;}
631  else {tStruct.actualStatus[j] = 0;}
632  } else {
633  tStruct.actualStatus[j] = -1;
634  missing++;
635  ss << "Channel = " << tStruct.dpname[j] << std::endl;
636  }
637  }
638  LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Number of channels with no setting information " << missing;
639  LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Number of entries in dpname vector " << tStruct.dpname.size();
640 }
641 
643 {
644  readLastValueFromFile(tStruct.dpid,tStruct.actualValue,tStruct.changeDate);
645  tStruct.latestTime = findMostRecentTimeStamp( tStruct.changeDate );
646  LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: File access complete \n\t Number of values read from file: " << tStruct.dpid.size();
647 
648  // retrieve the channel settings from the PVSS DB
649  std::vector<coral::TimeStamp> settingDate;
650  std::vector<float> settingValue;
651  std::vector<std::string> settingDpname;
652  std::vector<uint32_t> settingDpid;
653 
654  coralInterface->doSettingsQuery(tsetmin,tmax,settingDate,settingValue,settingDpname,settingDpid);
655  LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Channel settings retrieved";
656  LogDebug("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::BuildDetVOff]: Number of PSU channels: " << settingDpname.size();
657 
658  unsigned int missing = 0;
659  std::stringstream ss;
660  // need to get the PSU channel names from settings
661  tStruct.dpname.clear();
662  tStruct.dpname.resize(tStruct. dpid.size());
663  for (unsigned int j = 0; j < tStruct.dpid.size(); j++) {
664  int setting = findSetting(tStruct.dpid[j],tStruct.changeDate[j],settingDpid,settingDate);
665  if (setting >= 0) {
666  if (tStruct.actualValue[j] > (highVoltageOnThreshold_*settingValue[setting])) {tStruct.actualStatus[j] = 1;}
667  else {
668  tStruct.actualStatus[j] = 0;
669  }
670  tStruct.dpname[j] = settingDpname[setting];
671  } else {
672  tStruct.actualStatus[j] = -1;
673  tStruct.dpname[j] = "UNKNOWN";
674  missing++;
675  ss << "DP ID = " << tStruct.dpid[j] << std::endl;
676  }
677  }
678  LogDebug("SiStripDetVOffBuilder") << "Number of missing psu channels = " << missing << std::endl;
679  LogDebug("SiStripDetVOffBuilder") << "IDs are: = " << ss.str();
680 }
681 
682 string SiStripDetVOffBuilder::timeToStream(const cond::Time_t & condTime, const string & comment)
683 {
684  stringstream ss;
685  ss << comment << (condTime>> 32) << " - " << (condTime & 0xFFFFFFFF) << std::endl;
686  return ss.str();
687 }
688 
689 string SiStripDetVOffBuilder::timeToStream(const coral::TimeStamp & coralTime, const string & comment)
690 {
691  stringstream ss;
692  ss << "Starting from IOV time in the database : year = " << coralTime.year()
693  << ", month = " << coralTime.month()
694  << ", day = " << coralTime.day()
695  << ", hour = " << coralTime.hour()
696  << ", minute = " << coralTime.minute()
697  << ", second = " << coralTime.second()
698  << ", nanosecond = " << coralTime.nanosecond() << std::endl;
699  return ss.str();
700 }
702  //Helper method to check if local files exist (needed to handle HVUnmapped, HVCrosstalking modules)
703  struct stat FileInfo;
704  bool Existence;
705  int Stat;
706  //Try to get file attributes
707  Stat=stat(FileName.c_str(),&FileInfo);
708  if (Stat==0) {
709  Existence=true;
710  }
711  else {
712  Existence=false;
713  }
714  return Existence;
715 }
716 
718 //This function builds a PSU to DetID map one way or the other. Then it processes the psuStruct that contains
719 //the results of the CAEN status query to the Online DB, filling the detIdStruct with the detIDs corresponding
720 //to the PSU (channel in some cases, PSU only in others) reported in the CAEN status query to the Online DB.
721 //It may make sense to split this method eventually.
722 {
724  if( psuDetIdMapFile_ == "" ) {
725  std::cout<<"PLEASE provide the name of a valid PSUDetIDMapFile in the cfg: currently still necessary to have a file, soon will access the info straight from the DB!"<<endl;
726  //map_.BuildMap();//This method is not currently used (it would try to build a map based on a query to SiStripConfigDB, and the info there is STALE!)
727  }
728  else {
729  map_.BuildMap(psuDetIdMapFile_,debug_); //This is the method used to build the map.
730  }
731  LogTrace("SiStripDetVOffBuilder") <<"[SiStripDetVOffBuilder::BuildDetVOff] PSU(Channel)-detID map(s) built";
732  //Following method to be replaced by printMaps... to print all 4 maps built!
733  map_.printMap(); //This method prints to the info.log file, notice that it is overwritten by each individual O2O job running in the same dir.
734 
735  // use map info to build input for list of objects
736  // no need to check for duplicates, as put method for SiStripDetVOff checks for you!
737 
738  //Debug variables
739  unsigned int ch0bad = 0, ch1bad = 0, ch2bad = 0, ch3bad = 0;
740  std::vector<unsigned int> numLvBad, numHvBad;
741 
742  //Create 2 extra maps that we'll use to keep track of unmapped and crosstalking detids when turning ON and OFF HV:
743  //-unmapped need to be both turned OFF when any HV goes OFF and to be turned ON when both are ON
744  //-crosstaling need to be both turned ON when any HV goes ON and to be turned OFF ONLY when BOTH are OFF.
745  std::map<std::string,bool> UnmappedState, CrosstalkingState;
746  //Get the HVUnmapped map from the map, so that we can set know which PSU are unmapped:
747  std::map<std::string,std::vector<uint32_t> > UnmappedPSUs=map_.getHVUnmappedMap();
748  //Check here if there is a file already, otherwise initialize to OFF all channels in these PSU!
749  if (FileExists("HVUnmappedChannelState.dat")) {
750  std::cout<<"File HVUnmappedChannelState.dat exists!"<<std::endl;
751  std::ifstream ifs("HVUnmappedChannelState.dat");
752  string line;
753  while( getline( ifs, line ) ) {
754  if( line != "" ) {
755  // split the line and insert in the map
756  stringstream ss(line);
757  string PSUChannel;
758  bool HVStatus;
759  ss >> PSUChannel;
760  ss >> HVStatus;
761  //Extract the PSU from the PSUChannel (since the HVUnmapped_Map uses PSU as key
762  std::string PSU=PSUChannel.substr(0,PSUChannel.size()-10);
763  //Look for the PSU in the unmapped map!
764  std::map<std::string,std::vector<uint32_t> >::iterator iter=UnmappedPSUs.find(PSU);
765  if (iter!=UnmappedPSUs.end()) {
766  UnmappedState[PSUChannel]=HVStatus;
767  }
768  else {
769  std::cout<<"WARNING!!! There are channels in the local file with the channel status for HVUnmapped channels, that ARE NOT CONSIDERED AS UNMAPPED in the current map!"<<std::endl;
770  }
771  }
772  }//End of the while loop reading and initializing UnmappedState map from file
773  //Extra check:
774  //Should check if there any HVUnmapped channels in the map that are not listed in the local file!
775  bool MissingChannels=false;
776  for (std::map<std::string, vector<uint32_t> >::iterator it=UnmappedPSUs.begin(); it!=UnmappedPSUs.end(); it++) {
777  std::string chan002=it->first+"channel002";
778  std::string chan003=it->first+"channel003";
779  std::map<std::string,bool>::iterator iter=UnmappedState.find(chan002);
780  if (iter==UnmappedState.end()) {
781  std::cout<<"ERROR! The local file with the channel status for HVUnmapped channels IS MISSING one of the following unmapped channel voltage status information:"<<std::endl;
782  std::cout<<chan002<<std::endl;
783  MissingChannels=true;
784  }
785  iter=UnmappedState.find(chan003);
786  if (iter==UnmappedState.end()) {
787  std::cout<<"ERROR! The local file with the channel status for HVUnmapped channels IS MISSING one of the following unmapped channel voltage status information:"<<std::endl;
788  std::cout<<chan003<<std::endl;
789  MissingChannels=true;
790  }
791  }
792  //Now if any channel WAS missing, exit!
793  if (MissingChannels) {
794  std::cout<<"!!!!\n"<<"Exiting now... please check the local HVUnmappedChannelState.dat and the mapfile you provided ("<<psuDetIdMapFile_<<")"<<std::endl;
795  exit(1);
796  }
797  }
798  else { //If the file HVUnmappedChannelState.dat does not exist, initialize the map to all OFF.
799  //(see below for creating the file at the end of the execution with the latest state of unmapped channels.
800  for (std::map<std::string, vector<uint32_t> >::iterator it=UnmappedPSUs.begin(); it!=UnmappedPSUs.end(); it++) {
801  std::string chan002=it->first+"channel002";
802  std::string chan003=it->first+"channel003";
803  UnmappedState[chan002]=false;
804  UnmappedState[chan003]=false;
805  }
806  }
807  //Get the HVCrosstalking map from the map, so that we can set know which PSU are crosstalking:
808  std::map<std::string,std::vector<uint32_t> > CrosstalkingPSUs=map_.getHVCrosstalkingMap();
809  //Check here if there is a file already, otherwise initialize to OFF all channels in these PSU!
810  if (FileExists("HVCrosstalkingChannelState.dat")) {
811  std::cout<<"File HVCrosstalkingChannelState.dat exists!"<<std::endl;
812  std::ifstream ifs("HVCrosstalkingChannelState.dat");
813  string line;
814  while( getline( ifs, line ) ) {
815  if( line != "" ) {
816  // split the line and insert in the map
817  stringstream ss(line);
818  string PSUChannel;
819  bool HVStatus;
820  ss >> PSUChannel;
821  ss >> HVStatus;
822  //Extract the PSU from the PSUChannel (since the HVCrosstalking_Map uses PSU as key
823  std::string PSU=PSUChannel.substr(0,PSUChannel.size()-10);
824  //Look for the PSU in the unmapped map!
825  std::map<std::string,std::vector<uint32_t> >::iterator iter=CrosstalkingPSUs.find(PSU);
826  if (iter!=CrosstalkingPSUs.end()) {
827  CrosstalkingState[PSUChannel]=HVStatus;
828  }
829  else {
830  std::cout<<"WARNING!!! There are channels in the local file with the channel status for HVUnmapped channels, that ARE NOT CONSIDERED AS UNMAPPED in the current map!"<<std::endl;
831  }
832  }
833  }//End of the while loop reading and initializing CrosstalkingState map from file
834  //Extra check:
835  //Should check if there any HVCrosstalking channels in the map that are not listed in the local file!
836  bool MissingChannels=false;
837  for (std::map<std::string, vector<uint32_t> >::iterator it=CrosstalkingPSUs.begin(); it!=CrosstalkingPSUs.end(); it++) {
838  std::string chan002=it->first+"channel002";
839  std::string chan003=it->first+"channel003";
840  std::map<std::string,bool>::iterator iter=CrosstalkingState.find(chan002);
841  if (iter==CrosstalkingState.end()) {
842  std::cout<<"ERROR! The local file with the channel status for HVCrosstalking channels IS MISSING one of the following unmapped channel voltage status information:"<<std::endl;
843  std::cout<<chan002<<std::endl;
844  MissingChannels=true;
845  }
846  iter=CrosstalkingState.find(chan003);
847  if (iter==CrosstalkingState.end()) {
848  std::cout<<"ERROR! The local file with the channel status for HVCrosstalking channels IS MISSING one of the following unmapped channel voltage status information:"<<std::endl;
849  std::cout<<chan003<<std::endl;
850  MissingChannels=true;
851  }
852  }
853  //Now if any channel WAS missing, exit!
854  if (MissingChannels) {
855  std::cout<<"!!!!\n"<<"Exiting now... please check the local HVCrosstalkingChannelState.dat and the mapfile you provided ("<<psuDetIdMapFile_<<")"<<std::endl;
856  exit(1);
857  }
858  }
859  else { //If the file HVCrosstalkingChannelState.dat does not exist, initialize the map to all OFF.
860  //(see below for creating the file at the end of the execution with the latest state of unmapped channels.
861  for (std::map<std::string, vector<uint32_t> >::iterator it=CrosstalkingPSUs.begin(); it!=CrosstalkingPSUs.end(); it++) {
862  std::string chan002=it->first+"channel002";
863  std::string chan003=it->first+"channel003";
864  CrosstalkingState[chan002]=false;
865  CrosstalkingState[chan003]=false;
866  }
867  }
868 
869  if (debug_) {
870  //print out the UnmappedState map:
871  std::cout<<"Printing the UnmappedChannelState initial map:"<<std::endl;
872  std::cout<<"PSUChannel\t\tHVON?(true or false)"<<std::endl;
873  for (std::map<std::string,bool>::iterator it=UnmappedState.begin(); it!=UnmappedState.end(); it++) {
874  std::cout<<it->first<<"\t\t"<<it->second<<std::endl;
875  }
876  //print out the CrosstalkingState map:
877  std::cout<<"Printing the CrosstalkingChannelState initial map:"<<std::endl;
878  std::cout<<"PSUChannel\t\tHVON?(true or false)"<<std::endl;
879  for (std::map<std::string,bool>::iterator it=CrosstalkingState.begin(); it!=CrosstalkingState.end(); it++) {
880  std::cout<<it->first<<"\t\t"<<it->second<<std::endl;
881  }
882  }
883 
884  //Loop over the psuStruct (DB query results), lopping over the PSUChannels
885  //This will probably change int he future when we will change the query itself
886  //to report directly the detIDs associated with a channel
887  //Probably we will report in the query results the detID, the changeDate
888  //and whether the channel is HV mapped, HV unmapped, HV crosstalking using a flag...
889  for (unsigned int dp = 0; dp < psuStruct.dpname.size(); dp++) {
890  //FIX ME:
891  //Check if the following if condition can EVER be true!
892  std::string PSUChannel=psuStruct.dpname[dp];
893  if (PSUChannel != "UNKNOWN") {
894 
895  // figure out the channel and the PSU individually
896  std::string Channel = PSUChannel.substr(PSUChannel.size()-10); //Channel is the channel, i.e. channel000, channel001 etc
897  std::string PSU = PSUChannel.substr(0,PSUChannel.size()-10);
898 
899  // Get the detIDs corresponding to the given PSU channel using the getDetID function of SiStripPsuDetIdMap.cc
900  //NOTA BENE
901  //Need to make sure the information is treated consistently here:
902  //The map by convention has
903  //detID-> channel002 or channel003 IF the channel is HV mapped,
904  //detID->channel000 if it is not HV mapped
905  //We want to differentiate the behavior depending on the status reported for the channel for channels that are unmapped!
906  //1-if the channel is turning OFF (!=1) then we want to report all detIDs for that channel and all detIDs that are listed as channel000 for that PSU.
907  //2-if the channel is turning ON (==1) then we want to turn on all detIDs for that channel but turn on all detIDs listed as channel000 for that PSU ONLY IF BOTH channel002 and channel003 are BOTH ON!
908  //Need to handle the case of coupled Power supplies (that only turn off when both are turned off).
909 
910  //Fixed SiStripPSUdetidMap.cc to make sure now getDetID gets the correct list of detIDs:
911  //-for channels 000/001 all the detIDs connected to the PSU
912  //-for channels 002/003 HV1/HV2 modules only (exclusively)
913  //UPDATE for HV channels:
914  //actually fixed it to report also detIDs listed as
915  //channel000 on the same supply of channel002 or channel003
916  //and the crosstalking ones (channel999) too..
917 
918  //Get the detIDs associated with the DPNAME (i.e. PSUChannel) reported by the query
919  //Declare the vector to be passed as reference parameters to the getDetID method
920  //std::vector<uint32_t> ids,unmapped_ids,crosstalking_ids;
921  std::vector<uint32_t> ids;
922  //map_.getDetID(PSUChannel, debug_, ids, unmapped_ids, crosstalking_ids);
923  //Actually the method above is a bit of an overkill, we could already use the individual methods:
924  //getLvDetID
925  //getHvDetID
926 
927  //Declaring the two vector needed for the HV case in this scope.
928  std::vector<uint32_t> unmapped_ids,crosstalking_ids;
929  bool LVCase;
930  //LV CASE
931  if (Channel=="channel000" || Channel=="channel001") {
932  LVCase=true;
933  ids=map_.getLvDetID(PSU); //Since in the LV case only 1 list of detids is returned (unmapped and crosstalking are irrelevant for LV) return the vector directly
934  }
935  //HV CASE
936  else { //if (Channel=="channel002" || Channel=="channel003") {
937  LVCase=false;
938  map_.getHvDetID(PSUChannel,ids,unmapped_ids,crosstalking_ids); //In the HV case since 3 vectors are filled, use reference parameters
939  }
940 
941  if ( debug_ ) {
942  cout <<"dpname["<<dp<<"] = "<<PSUChannel<<", for time = "<<timeToStream(psuStruct.changeDate[dp])<<endl;
943  if (!ids.empty()) {
944  if (Channel=="channel000" || Channel=="channel001") {
945  cout << "Corresponding to LV (PSU-)matching detids: "<<endl;
946  for (unsigned int i_detid=0;i_detid<ids.size();i_detid++) {
947  cout<< ids[i_detid] << std::endl;
948  }
949  }
950  else {
951  cout << "Corresponding to straight HV matching detids: "<<endl;
952  for (unsigned int i_detid=0;i_detid<ids.size();i_detid++) {
953  cout<< ids[i_detid] << std::endl;
954  }
955  }
956  }
957  //The unmapped_ids and crosstalking_ids are only filled for HV channels!
958  if (!unmapped_ids.empty()) {
959  cout << "Corresponding to HV unmapped (PSU-)matching detids: "<<endl;
960  for (unsigned int i_detid=0;i_detid<unmapped_ids.size();i_detid++) {
961  cout<< unmapped_ids[i_detid] << std::endl;
962  }
963  }
964  if (!crosstalking_ids.empty()) {
965  cout << "Corresponding to HV crosstalking (PSU-)matching detids: "<<endl;
966  for (unsigned int i_detid=0;i_detid<crosstalking_ids.size();i_detid++) {
967  cout<< crosstalking_ids[i_detid] << std::endl;
968  }
969  }
970  }
971 
972  //NOW implement the new logic using the detids, unmapped_detids, crosstalking_detids!
973 
974  //First check whether the channel we're looking at is turning OFF or turning ON!
975 
976  //TURN OFF case:
977  if (psuStruct.actualStatus[dp] != 1) {
978  //Behavior is different for LV vs HV channels:
979  //LV case:
980  if (LVCase) {
981  //Turn OFF all:
982  //-positively matching
983  //-unmapped matching
984  //-crosstalking
985  //for the LV case all the detids are automatically reported in the ids vector
986  //unmapped and crosstalking are only differentiated (relevant) for HV.
987  if (!ids.empty()) {
988  //debug variables increment
989  ch0bad++;
990  ch1bad++;
991 
992  //Create a pair with the relevant detIDs (vector) and its timestamp
993  //And put it in the detidV vector of the detIdStruct that will contain all the
994  //results
995  detIdStruct.detidV.push_back( std::make_pair(ids,psuStruct.changeDate[dp]) );
996 
997  //Set the status to OFF
998  detIdStruct.StatusGood.push_back(false);
999 
1000  //debug variable population
1001  numLvBad.insert(numLvBad.end(),ids.begin(),ids.end());
1002 
1003  //Set the flag for LV/HV:
1004  detIdStruct.isHV.push_back(0); //LV
1005 
1006  //Set the PSUChannel (I guess for debug purposes?)
1007  detIdStruct.psuName.push_back( PSUChannel );
1008  }
1009  }
1010  //HV case:
1011  else { //if (!LVCase) {
1012  //Debug variables increment:
1013  if (!ids.empty() || !unmapped_ids.empty() || !crosstalking_ids.empty()) {
1014  if (Channel=="channel002") {
1015  ch2bad++;
1016  }
1017  else if (Channel=="channel003") {
1018  ch3bad++;
1019  }
1020  }
1021  //First sum the ids (positively matching detids) and the unmapped_ids (since both should be TURNED OFF):
1022  std::vector<uint32_t> OFFids;
1023  OFFids.insert(OFFids.end(),ids.begin(),ids.end()); //Add the ids (if any!)
1024  OFFids.insert(OFFids.end(),unmapped_ids.begin(),unmapped_ids.end()); //Add the unmapped_ids (if any!)
1025  //Now for the cross-talking ids this is a bit more complicated!
1026  if (!crosstalking_ids.empty()) {//This already means that the PSUChannel is one of the crosstalking ones (even if only a few modules in that PSU are showing crosstalking behavior both its channels have to be considered crosstalking of course!
1027  //Set the channel OFF in the CrosstalkingState map!
1028  CrosstalkingState[PSUChannel]=false; //Turn OFF the channel in the state map!
1029 
1030  //Need to check if both channels (HV1==channel002 or HV2==channel003) are OFF!
1031  if (!CrosstalkingState[PSUChannel.substr(0,PSUChannel.size()-1)+"2"] && !CrosstalkingState[PSUChannel.substr(0,PSUChannel.size()-1)+"3"]) { //if HV1 & HV2 both OFF (false)
1032  OFFids.insert(OFFids.end(),crosstalking_ids.begin(),crosstalking_ids.end()); //Add the crosstalking_ids (if any!) since both HV1 and HV2 are OFF!
1033  if (debug_) {
1034  std::cout<<"Adding the unmapped detids corresponding to (HV1/2 cross-talking) PSU "<<PSUChannel.substr(0,PSUChannel.size()-10)<<" to the list of detids turning OFF"<<std::endl;
1035  }
1036  }
1037  }
1038  //Handle the crosstalking channel by setting it to OFF in the CrosstalkingState map!
1039  if (!unmapped_ids.empty()) {//This already means that the PSUChannel is one of the unmapped ones (even if only a few modules in that PSU are unmapped both its channels have to be considered crosstalking of course!
1040  UnmappedState[PSUChannel]=false; //Turn OFF the channel in the state map!
1041  }
1042  if (!OFFids.empty()) {
1043  //Create a pair with the relevant detIDs (vector) and its timestamp
1044  //And put it in the detidV vector of the detIdStruct that will contain all the
1045  //results
1046 
1047  //Going OFF HV:
1048  //report not only ids, but also unmapped_ids.
1049  //have to handle crosstalking_ids here... (only OFF if they corresponding PSU HV1/HV2 is off already...
1050  //then add all three vectors to the pair below...
1051  detIdStruct.detidV.push_back( std::make_pair(OFFids,psuStruct.changeDate[dp]) );
1052 
1053  //Set the status to OFF
1054  detIdStruct.StatusGood.push_back(false);
1055 
1056  //debug variable population
1057  numHvBad.insert(numHvBad.end(),ids.begin(),ids.end());
1058 
1059  //Set the flag for LV/HV:
1060  detIdStruct.isHV.push_back(1); //HV
1061 
1062  //Set the PSUChannel (I guess for debug purposes?)
1063  detIdStruct.psuName.push_back( PSUChannel );
1064  }
1065  }
1066  }
1067  //TURNING ON CASE
1068  else {
1069  //Implement the rest of the logic!
1070  //Behavior is different for LV vs HV channels:
1071  //LV case:
1072  if (LVCase) {
1073  //Turn ON all (PSU)matching detids:
1074  //for the LV case all the detids are automatically reported in the ids vector
1075  //unmapped and crosstalking are only differentiated (relevant) for HV.
1076  if (!ids.empty()) {
1077  //Create a pair with the relevant detIDs (vector) and its timestamp
1078  //And put it in the detidV vector of the detIdStruct that will contain all the
1079  //results
1080  detIdStruct.detidV.push_back( std::make_pair(ids,psuStruct.changeDate[dp]) );
1081 
1082  //Set the status to ON
1083  detIdStruct.StatusGood.push_back(true);
1084 
1085  //Set the flag for LV/HV:
1086  detIdStruct.isHV.push_back(0); //LV
1087 
1088  //Set the PSUChannel (I guess for debug purposes?)
1089  detIdStruct.psuName.push_back( PSUChannel );
1090  }
1091  }
1092  //HV case:
1093  else { //if (!LVCase) {
1094  //First sum the ids (positively matching detids) and the crosstalking_ids (since all ids on a crosstalking PSU should be TURNED ON when at least one HV channel is ON):
1095  std::vector<uint32_t> ONids;
1096  ONids.insert(ONids.end(),ids.begin(),ids.end()); //Add the ids (if any!)
1097  ONids.insert(ONids.end(),crosstalking_ids.begin(),crosstalking_ids.end()); //Add the crosstalking_ids (if any!)
1098  //Now for the unmapped ids this is a bit more complicated!
1099  if (!unmapped_ids.empty()) {//This already means that the PSUChannel is one of the unmapped ones (even if only a few modules in that PSU are unmapped both its channels have to be considered unmapped of course!
1100  //Set the HV1 channel on in the UnmappedState map!
1101  UnmappedState[PSUChannel]=true; //Turn ON the channel in the state map!
1102 
1103  //Need to check if BOTH channels (HV1==channel002 or HV2==channel003) are ON!
1104  if (UnmappedState[PSUChannel.substr(0,PSUChannel.size()-1)+"2"] && UnmappedState[PSUChannel.substr(0,PSUChannel.size()-1)+"3"]) { //if HV1 & HV2 are both ON (true)
1105  ONids.insert(ONids.end(),unmapped_ids.begin(),unmapped_ids.end()); //Add the unmapped_ids (if any!) since both HV1 and HV2 are ON!
1106  if (debug_) {
1107  std::cout<<"Adding the detids corresponding to HV-unmapped PSU "<<PSUChannel.substr(0,PSUChannel.size()-10)<<" to the list of detids turning ON"<<std::endl;
1108  }
1109  }
1110  }
1111  //Handle the crosstalking channel by setting it to OFF in the CrosstalkingState map!
1112  if (!crosstalking_ids.empty()) {//This already means that the PSUChannel is one of the crosstalking ones (even if only a few modules in that PSU are showing crosstalking behavior both its channels have to be considered crosstalking of course!
1113  CrosstalkingState[PSUChannel]=true; //Turn ON the channel in the state map!
1114  }
1115  if (!ONids.empty()) {
1116  //Create a pair with the relevant detIDs (vector) and its timestamp
1117  //And put it in the detidV vector of the detIdStruct that will contain all the
1118  //results
1119 
1120  //Going OFF HV:
1121  //report not only ids, but also unmapped_ids.
1122  //have to handle crosstalking_ids here... (only OFF if they corresponding PSU HV1/HV2 is off already...
1123  //then add all three vectors to the pair below...
1124  detIdStruct.detidV.push_back( std::make_pair(ONids,psuStruct.changeDate[dp]) );
1125 
1126  //Set the status to ON
1127  detIdStruct.StatusGood.push_back(true);
1128 
1129  //Set the flag for LV/HV:
1130  detIdStruct.isHV.push_back(1); //HV
1131 
1132  //Set the PSUChannel (I guess for debug purposes?)
1133  detIdStruct.psuName.push_back( PSUChannel );
1134  }
1135  }
1136  }
1137  }//End of if dpname not "UNKNOWN"
1138  else {
1139  //if (debug) {
1140  //std::cout<<"PSU Channel name WAS NOT RECOGNIZED"<<std::endl;
1141  //}
1142  detIdStruct.notMatched++;
1143  }
1144  }//End of the loop over all PSUChannels reported by the DB query.
1145  //At this point we need to (over)write the 2 files that will keep the HVUnmapped and HVCrosstalking channels status:
1146  std::ofstream ofsUnmapped("HVUnmappedChannelState.dat");
1147  for (std::map<std::string,bool>::iterator it=UnmappedState.begin(); it!=UnmappedState.end(); it++) {
1148  ofsUnmapped<<it->first<<"\t"<<it->second<<std::endl;
1149  }
1150  std::ofstream ofsCrosstalking("HVCrosstalkingChannelState.dat");
1151  for (std::map<std::string,bool>::iterator it=CrosstalkingState.begin(); it!=CrosstalkingState.end(); it++) {
1152  ofsCrosstalking<<it->first<<"\t"<<it->second<<std::endl;
1153  }
1154 
1155  removeDuplicates(numLvBad);
1156  removeDuplicates(numHvBad);
1157 
1158 
1159  // useful debugging stuff!
1160  if( debug_ ) {
1161  std::cout << "Number of channels that turned OFF in this O2O interval"<<std::endl;
1162  std::cout << "Channel000 = " << ch0bad << " Channel001 = " << ch1bad << std::endl;
1163  std::cout << "Channel002 = " << ch2bad << " Channel003 = " << ch3bad << std::endl;
1164  std::cout << "Number of LV detIDs that turned OFF in this O2O interval = " << numLvBad.size() << std::endl;
1165  std::cout << "Number of HV detIDs that turned OFF in this O2O interval = " << numHvBad.size() << std::endl;
1166  }
1167 
1168  LogTrace("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::" << __func__ << "]: Number of PSUs retrieved from DB with map information " << detIdStruct.detidV.size();
1169  LogTrace("SiStripDetVOffBuilder") << "[SiStripDetVOffBuilder::" << __func__ << "]: Number of PSUs retrieved from DB with no map information " << detIdStruct.notMatched;
1170 
1171  unsigned int dupCount = 0;
1172  for (unsigned int t = 0; t < numLvBad.size(); t++) {
1173  std::vector<unsigned int>::iterator iter = std::find(numHvBad.begin(),numHvBad.end(),numLvBad[t]);
1174  if (iter != numHvBad.end()) {dupCount++;}
1175  }
1176  if( debug_ ) std::cout << "Number of channels for which LV & HV turned OFF in this O2O interval = " << dupCount << std::endl;
1177 
1178 }
1179 
1180 void SiStripDetVOffBuilder::setPayloadStats(const uint32_t afterV, const uint32_t numAdded, const uint32_t numRemoved)
1181 {
1182  std::vector<uint32_t> pStats(3,0);
1183  pStats.push_back(afterV);
1184  pStats.push_back(numAdded);
1185  pStats.push_back(numRemoved);
1186  payloadStats.push_back(pStats);
1187 }
1188 
1189 pair<int, int> SiStripDetVOffBuilder::extractDetIdVector( const unsigned int i, SiStripDetVOff * modV, DetIdListTimeAndStatus & detIdStruct )
1190 {
1191  // set the LV and HV off flags ready for storing
1192  int lv_off = -1, hv_off = -1;
1193  if (detIdStruct.isHV[i] == 0) {lv_off = !(detIdStruct.StatusGood[i]);}
1194  if (detIdStruct.isHV[i] == 1) {
1195  hv_off = !(detIdStruct.StatusGood[i]);
1196 
1197  // TESTING WITHOUT THE FIX
1198  // -----------------------
1199 
1200  if( psuDetIdMapFile_ == "" ) {
1201  // temporary fix to handle the fact that we don't know which HV channel the detIDs are associated to
1202  if (i > 0) {
1203  std::string iChannel = detIdStruct.psuName[i].substr( (detIdStruct.psuName[i].size()-3) );
1204  std::string iPsu = detIdStruct.psuName[i].substr(0, (detIdStruct.psuName[i].size()-3) );
1205  if (iChannel == "002" || iChannel == "003") {
1206  bool lastStatusOfOtherChannel = true;
1207  for (unsigned int j = 0; j < i; j++) {
1208  std::string jPsu = detIdStruct.psuName[j].substr(0, (detIdStruct.psuName[j].size()-3) );
1209  std::string jChannel = detIdStruct.psuName[j].substr( (detIdStruct.psuName[j].size()-3) );
1210  if (iPsu == jPsu && iChannel != jChannel && (jChannel == "002" || jChannel == "003")) {
1211  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;
1212  lastStatusOfOtherChannel = detIdStruct.StatusGood[j];
1213  }
1214  }
1215  if (detIdStruct.StatusGood[i] != lastStatusOfOtherChannel) {
1216  if( debug_ ) cout << "turning off hv" << endl;
1217  hv_off = 1;
1218  }
1219  }
1220  }
1221  }
1222 
1223  // -----------------------
1224 
1225  }
1226 
1227  return make_pair(hv_off, lv_off);
1228 }
#define LogDebug(id)
Map map_
SiStripDetVOffBuilder(const edm::ParameterSet &, const edm::ActivityRegistry &)
void discardIOVs(std::vector< std::pair< SiStripDetVOff *, cond::Time_t > >::iterator &it, std::vector< std::pair< SiStripDetVOff *, cond::Time_t > >::iterator &initialIt, std::vector< std::pair< SiStripDetVOff *, cond::Time_t > > &resultVec, const bool last, const unsigned int first)
Removes IOVs as dictated by reduction.
std::pair< int, int > extractDetIdVector(const unsigned int i, SiStripDetVOff *modV, DetIdListTimeAndStatus &detIdStruct)
std::map< std::string, std::vector< uint32_t > > getHVCrosstalkingMap()
void printPar(std::stringstream &ss, const std::vector< int > &par)
void buildPSUdetIdMap(TimesAndValues &tStruct, DetIdListTimeAndStatus &dStruct)
Extension to SiStripConfigDb to map PSU channels to DetIDs using DCU-PSU map and DCU-DetID map...
bool put(const uint32_t DetId, const int HVoff, const int LVoff)
Insert information for a single detId.
std::map< std::string, std::vector< uint32_t > > getHVUnmappedMap()
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
std::auto_ptr< SiStripCoralIface > coralInterface
int findSetting(uint32_t id, const coral::TimeStamp &changeDate, const std::vector< uint32_t > &settingID, const std::vector< coral::TimeStamp > &settingDate)
void removeDuplicates(std::vector< uint32_t > &vec)
U second(std::pair< T, U > const &p)
bool FileExists(std::string filename)
unsigned long long Time_t
Definition: Time.h:16
cond::Time_t getCondTime(const coral::TimeStamp &coralTime)
std::vector< coral::TimeStamp > changeDate
void getDetIds(std::vector< uint32_t > &DetIds_) const
def unique(seq, keepstr=True)
Definition: tier0.py:24
std::vector< uint32_t > getLvDetID(std::string psu)
void reduction(const uint32_t deltaTmin, const uint32_t maxIOVlength)
An interface class to the PVSS cond DB.
void lastValue(TimesAndValues &tStruct)
void getHvDetID(std::string psuchannel, std::vector< uint32_t > &ids, std::vector< uint32_t > &unmapped_ids, std::vector< uint32_t > &crosstalking_ids)
Time_t from_boost(boost::posix_time::ptime bt)
void readLastValueFromFile(std::vector< uint32_t > &dpIDs, std::vector< float > &vmonValues, std::vector< coral::TimeStamp > &dateChange)
#define LogTrace(id)
cond::Time_t findMostRecentTimeStamp(const std::vector< coral::TimeStamp > &coralDate)
void lastValueFromFile(TimesAndValues &tStruct)
std::vector< int > tmax_par
coral::TimeStamp getCoralTime(cond::Time_t iovTime)
auto dp
Definition: deltaR.h:22
part
Definition: HCALResponse.h:20
void setLastSiStripDetVOff(SiStripDetVOff *lastPayload, cond::Time_t lastTimeStamp)
void BuildMap(const std::string &mapFile, const bool debug)
std::vector< int > tmin_par
std::vector< std::vector< uint32_t > > payloadStats
void setPayloadStats(const uint32_t afterV, const uint32_t numAdded, const uint32_t numRemoved)
void reduce(std::vector< std::pair< SiStripDetVOff *, cond::Time_t > >::iterator &it, std::vector< std::pair< SiStripDetVOff *, cond::Time_t > >::iterator &initialIt, std::vector< std::pair< SiStripDetVOff *, cond::Time_t > > &resultVec, const bool last=false)
Operates the reduction of the fast sequences of ramping up and down of the voltages.
std::string fullPath() const
Definition: FileInPath.cc:184
def day(string)
Definition: getRunInfo.py:11
DQMChannel Channel
std::vector< std::pair< SiStripDetVOff *, cond::Time_t > > modulesOff
void statusChange(cond::Time_t &lastTime, TimesAndValues &tStruct)
std::pair< SiStripDetVOff *, cond::Time_t > lastStoredCondObj
std::string timeToStream(const coral::TimeStamp &coralTime, const string &comment="")
std::vector< int > tset_par
boost::posix_time::ptime to_boost(Time_t iValue)
#define comment(par)
Definition: vmac.h:161