CMS 3D CMS Logo

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