CMS 3D CMS Logo

SiStripApvGainFromFileBuilder.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: CondTools/SiStrip
4 // Class: SiStripApvGainFromFileBuilder
5 //
10 //
11 // Original Author: A. Di Mattia
12 // Contributors: M. Musich (modernization)
13 //
14 // Created: Wed, 1 Mar 2022 14:26:18 GMT
15 //
16 
17 // STL includes
18 #include <algorithm>
19 #include <cstdint>
20 #include <fstream>
21 #include <iomanip>
22 #include <iostream>
23 #include <map>
24 #include <sstream>
25 #include <stdexcept>
26 #include <utility>
27 #include <vector>
28 
29 // user includes
45 
47 public:
48  //enum ExceptionType = { NotConnected, ZeroGainFromScan, NegativeGainFromScan };
49 
50  typedef std::map<uint32_t, float> Gain;
51 
52  typedef struct {
53  uint32_t det_id;
54  uint16_t offlineAPV_id;
56  int FED_id;
57  int FED_ch;
58  int i2cAdd;
60  bool is_scanned;
62  float gain_in_db;
63  } Summary;
64 
67  explicit SiStripApvGainFromFileBuilder(const edm::ParameterSet& iConfig);
68 
72 
75  void analyze(const edm::Event&, const edm::EventSetup&) override;
76 
80 
81 private:
84  double gainThreshold_;
85  double dummyAPVGain_;
91  bool outputMaps_;
98  std::vector<Gain*> gains_;
99  std::vector<Gain*> negative_gains_;
100  std::vector<Gain*> null_gains_;
107  std::vector<Summary> summary_;
116  std::vector<Summary> ex_summary_;
128  void read_tickmark(void);
129 
136  Gain* get_map(std::vector<Gain*>* maps, int onlineAPV_id);
137 
143  void output_maps(std::vector<Gain*>* maps, const char* basename) const;
144 
153  void output_summary() const;
154 
157  void format_summary(std::stringstream& line, Summary summary) const;
158 
161  bool gain_from_maps(uint32_t det_id, int onlineAPV_id, float& gain);
162  void gain_from_maps(uint32_t det_id, uint16_t totalAPVs, std::vector<std::pair<int, float>>& gain) const;
163 
166  int online2offline(uint16_t onlineAPV_id, uint16_t totalAPVs) const;
167 
168  static constexpr float k_GainNormalizationFactor = 640.f;
169  static constexpr float k_InvalidGain = 999999.f;
170 };
171 
172 static const struct clean_up {
174  if (el != nullptr) {
175  el->clear();
176  delete el;
177  el = nullptr;
178  }
179  }
180 } CleanUp;
181 
183  for_each(gains_.begin(), gains_.end(), CleanUp);
184  for_each(negative_gains_.begin(), negative_gains_.end(), CleanUp);
185  for_each(null_gains_.begin(), null_gains_.end(), CleanUp);
186 }
187 
189  : cablingToken_(esConsumes()),
190  tfp_(iConfig.getParameter<edm::FileInPath>("tickFile")),
191  gainThreshold_(iConfig.getParameter<double>("gainThreshold")),
192  dummyAPVGain_(iConfig.getParameter<double>("dummyAPVGain")),
193  doGainNormalization_(iConfig.getParameter<bool>("doGainNormalization")),
194  putDummyIntoUncabled_(iConfig.getParameter<bool>("putDummyIntoUncabled")),
195  putDummyIntoUnscanned_(iConfig.getParameter<bool>("putDummyIntoUnscanned")),
196  putDummyIntoOffChannels_(iConfig.getParameter<bool>("putDummyIntoOffChannels")),
197  putDummyIntoBadChannels_(iConfig.getParameter<bool>("putDummyIntoBadChannels")),
198  outputMaps_(iConfig.getParameter<bool>("outputMaps")),
199  outputSummary_(iConfig.getParameter<bool>("outputSummary")) {}
200 
202  //unsigned int run=evt.id().run();
203 
204  edm::LogInfo("SiStripApvGainFromFileBuilder") << "@SUB=analyze"
205  << "Insert SiStripApvGain Data.";
206  this->read_tickmark();
207 
208  if (outputMaps_) {
209  try {
210  this->output_maps(&gains_, "tickmark_heights");
211  this->output_maps(&negative_gains_, "negative_tickmark");
212  this->output_maps(&null_gains_, "zero_tickmark");
213  } catch (std::exception& e) {
214  std::cerr << e.what() << std::endl;
215  }
216  }
217 
218  // Retrieve the SiStripDetCabling description
219  detCabling_ = &iSetup.getData(cablingToken_);
220 
221  // APV gain record to be filled with gains and delivered into the database.
222  auto obj = std::make_unique<SiStripApvGain>();
223 
224  const auto& reader =
226  const auto& DetInfos = reader.getAllData();
227 
228  LogTrace("SiStripApvGainFromFileBuilder") << " det id |APVOF| CON |APVON| FED |FEDCH|i2cAd|tickGain|" << std::endl;
229 
230  for (const auto& it : DetInfos) {
231  // check if det id is correct and if it is actually cabled in the detector
232  if (it.first == 0 || it.first == 0xFFFFFFFF) {
233  edm::LogError("DetIdNotGood") << "@SUB=analyze"
234  << "Wrong det id: " << it.first << " ... neglecting!";
235  continue;
236  }
237 
238  // For the cabled det_id retrieve the number of APV connected
239  // to the module with the FED cabling
240  uint16_t nAPVs = 0;
241  const std::vector<const FedChannelConnection*> connection = detCabling_->getConnections(it.first);
242  for (unsigned int ca = 0; ca < connection.size(); ca++) {
243  if (connection[ca] != nullptr) {
244  nAPVs += (connection[ca])->nApvs();
245  break;
246  }
247  }
248 
249  // check consistency among FED cabling and ideal cabling, exit on error
250  if (!connection.empty() && nAPVs != (uint16_t)it.second.nApvs) {
251  edm::LogError("SiStripCablingError")
252  << "@SUB=analyze"
253  << "det id " << it.first << ": APV number from FedCabling (" << nAPVs
254  << ") is different from the APV number retrieved from the ideal cabling (" << it.second.nApvs << ").";
255  throw("Inconsistency on the number of APVs.");
256  }
257 
258  // eventually separate the processing for the module that are fully
259  // uncabled. This is worth only if we decide not tu put the record
260  // in the DB for the uncabled det_id.
261  //if( !detCabling_->IsConnected(it.first) ) {
262  //
263  // continue;
264  //}
265 
266  //Gather the APV online id
267  std::vector<std::pair<int, float>> tickmark_for_detId(it.second.nApvs, std::pair<int, float>(-1, k_InvalidGain));
268  for (unsigned int ca = 0; ca < connection.size(); ca++) {
269  if (connection[ca] != nullptr) {
270  uint16_t id1 = (connection[ca])->i2cAddr(0) % 32;
271  uint16_t id2 = (connection[ca])->i2cAddr(1) % 32;
272  tickmark_for_detId[online2offline(id1, it.second.nApvs)].first = id1;
273  tickmark_for_detId[online2offline(id2, it.second.nApvs)].first = id2;
274  }
275  }
276  gain_from_maps(it.first, it.second.nApvs, tickmark_for_detId);
277  std::vector<float> theSiStripVector;
278 
279  // Fill the gain in the DB object, apply the logic for the dummy values
280  for (unsigned short j = 0; j < it.second.nApvs; j++) {
282  summary.det_id = it.first;
283  summary.offlineAPV_id = j;
284  summary.onlineAPV_id = tickmark_for_detId.at(j).first;
285  summary.is_connected = false;
286  summary.FED_id = -1;
287  summary.FED_ch = -1;
288  summary.i2cAdd = -1;
289 
290  for (unsigned int ca = 0; ca < connection.size(); ca++) {
291  if (connection[ca] != nullptr && (connection[ca])->i2cAddr(j % 2) % 32 == summary.onlineAPV_id) {
292  summary.is_connected = (connection[ca])->isConnected();
293  summary.FED_id = (connection[ca])->fedId();
294  summary.FED_ch = (connection[ca])->fedCh();
295  summary.i2cAdd = (connection[ca])->i2cAddr(j % 2);
296  }
297  }
298 
299  try {
300  float gain = tickmark_for_detId[j].second;
301  summary.gain_from_scan = gain;
302  LogTrace("SiStripApvGainFromFileBuilder")
303  << it.first << " " << std::setw(3) << j << " " << std::setw(3) << connection.size() << " "
304  << std::setw(3) << summary.onlineAPV_id << " " << std::setw(3) << summary.FED_id << " " << std::setw(3)
305  << summary.FED_ch << " " << std::setw(3) << summary.i2cAdd << " " << std::setw(7)
306  << summary.gain_from_scan << std::endl;
307 
308  if (gain != k_InvalidGain) {
309  summary.is_scanned = true;
310  if (gain > gainThreshold_) {
311  if (doGainNormalization_) {
312  // divide the tickmark by the normalization factor (640)
314  }
315  summary.gain_in_db = gain;
316  if (!summary.is_connected)
317  ex_summary_.push_back(summary);
318  else
319  summary_.push_back(summary);
320  } else {
321  if (gain == 0.f) {
322  summary.gain_in_db = (putDummyIntoOffChannels_ ? dummyAPVGain_ : 0.f);
323  ex_summary_.push_back(summary);
324  } else if (gain < 0.f) {
325  summary.gain_in_db = (putDummyIntoBadChannels_ ? dummyAPVGain_ : 0.f);
326  ex_summary_.push_back(summary);
327  }
328  }
329  } else {
330  summary.is_scanned = false;
331  if (!summary.is_connected) {
332  summary.gain_in_db = (putDummyIntoUncabled_ ? dummyAPVGain_ : 0.f);
333  } else {
334  summary.gain_in_db = (putDummyIntoUnscanned_ ? dummyAPVGain_ : 0.f);
335  }
336  ex_summary_.push_back(summary);
337  }
338 
339  theSiStripVector.push_back(summary.gain_in_db);
340  LogTrace("SiStripApvGainFromFileBuilder") << "output gain:" << summary.gain_in_db;
341  } catch (std::exception& e) {
342  std::cerr << e.what() << std::endl;
343  edm::LogError("MappingError") << "@SUB=analyze"
344  << "Job end prematurely.";
345  return;
346  }
347  }
348 
349  SiStripApvGain::Range range(theSiStripVector.begin(), theSiStripVector.end());
350  if (!obj->put(it.first, range))
351  edm::LogError("IndexError") << "@SUB=analyze"
352  << "detid already exists.";
353  }
354 
355  if (outputSummary_)
356  output_summary();
357 
358  //End now write sistripnoises data in DB
360 
361  if (mydbservice.isAvailable()) {
362  if (mydbservice->isNewTagRequest("SiStripApvGainRcd")) {
363  mydbservice->createOneIOV<SiStripApvGain>(*obj, mydbservice->beginOfTime(), "SiStripApvGainRcd");
364  } else {
365  mydbservice->appendOneIOV<SiStripApvGain>(*obj, mydbservice->currentTime(), "SiStripApvGainRcd");
366  }
367  } else {
368  edm::LogError("DBServiceNotAvailable") << "@SUB=analyze"
369  << "DB Service is unavailable";
370  }
371 }
372 
374  // Connect file for input
375  const auto& filename = tfp_.fullPath();
376  std::ifstream thickmark_heights(filename.c_str());
377 
378  if (!thickmark_heights.is_open()) {
379  edm::LogError("FileNotFound") << "@SUB=read_ticlmark"
380  << "File with thickmark height file " << filename.c_str() << " cannot be opened!";
381  return;
382  }
383 
384  // clear internal maps
385  for_each(gains_.begin(), gains_.end(), CleanUp);
386  for_each(negative_gains_.begin(), negative_gains_.end(), CleanUp);
387  for_each(null_gains_.begin(), null_gains_.end(), CleanUp);
388 
389  // read file and fill internal map
390  uint32_t det_id = 0;
391  uint32_t APV_id = 0;
392  float tick_h = 0.;
393 
394  int count = -1;
395 
396  for (;;) {
397  count++;
398  thickmark_heights >> det_id >> APV_id >> tick_h;
399 
400  if (!(thickmark_heights.eof() || thickmark_heights.fail())) {
401  if (count == 0) {
402  LogTrace("Debug") << "Reading " << filename.c_str() << " for gathering the tickmark heights" << std::endl;
403  LogTrace("Debug") << "| Det Id | APV Id | Tickmark" << std::endl;
404  LogTrace("Debug") << "+-----------+----------+----------" << std::endl;
405  }
406  LogTrace("Debug") << std::setw(11) << det_id << std::setw(8) << APV_id << std::setw(14) << tick_h << std::endl;
407 
408  // retrieve the map corresponding to the gain collection
409  Gain* map = nullptr;
410  if (tick_h > 0.f) {
411  map = get_map(&gains_, APV_id);
412  } else if (tick_h < 0.f) {
413  map = get_map(&negative_gains_, APV_id);
414  } else {
415  // if tick_h == 0.f
416  map = get_map(&null_gains_, APV_id);
417  }
418 
419  // insert the gain value in the map
420  if (map) {
421  std::pair<Gain::iterator, bool> ret = map->insert(std::pair<uint32_t, float>(det_id, tick_h));
422 
423  if (ret.second == false) {
424  edm::LogError("MapError") << "@SUB=read_tickmark"
425  << "Cannot not insert gain for detector id " << det_id
426  << " into the internal map: detector id already in the map.";
427  }
428  } else {
429  edm::LogError("MapError") << "@SUB=read_tickmark"
430  << "Cannot get the online-offline APV mapping!";
431  }
432  } else if (thickmark_heights.eof()) {
433  edm::LogInfo("SiStripApvGainFromFileBuilder") << "@SUB=read_tickmark"
434  << "EOF of " << filename.c_str() << " reached.";
435  break;
436  } else if (thickmark_heights.fail()) {
437  edm::LogError("FileiReadError") << "@SUB=read_tickmark"
438  << "error while reading " << filename.c_str();
439  break;
440  }
441  }
442 
443  thickmark_heights.close();
444 }
445 
447  int onlineAPV_id) {
448  Gain* map = nullptr;
449  if (onlineAPV_id < 0 || onlineAPV_id > 5)
450  return map;
451 
452  try {
453  map = maps->at(onlineAPV_id);
454  } catch (const std::out_of_range&) {
455  if (maps->size() < static_cast<unsigned int>(onlineAPV_id))
456  maps->resize(onlineAPV_id);
457  maps->insert(maps->begin() + onlineAPV_id, new Gain());
458  map = (*maps)[onlineAPV_id];
459  }
460 
461  if (map == nullptr) {
462  (*maps)[onlineAPV_id] = new Gain();
463  map = (*maps)[onlineAPV_id];
464  }
465 
466  return map;
467 }
468 
469 void SiStripApvGainFromFileBuilder::output_maps(std::vector<Gain*>* maps, const char* basename) const {
470  for (unsigned int APV = 0; APV < maps->size(); APV++) {
471  Gain* map = (*maps)[APV];
472  if (map != nullptr) {
473  // open output file
474  std::stringstream name;
475  name << basename << "_APV" << APV << ".txt";
476  std::ofstream* ofile = new std::ofstream(name.str(), std::ofstream::trunc);
477  if (!ofile->is_open())
478  throw "cannot open output file!";
479  for (Gain::const_iterator el = map->begin(); el != map->end(); el++) {
480  (*ofile) << (*el).first << " " << (*el).second << std::endl;
481  }
482  ofile->close();
483  delete ofile;
484  }
485  }
486 }
487 
489  std::ofstream* ofile = new std::ofstream("SiStripApvGainSummary.txt", std::ofstream::trunc);
490  (*ofile) << " det id | APV | isConnected | FED |FEDCH|i2cAd|APVON| is_scanned |tickGain|gainInDB|" << std::endl;
491  (*ofile) << "----------+-----+-------------+-----+-----+-----+-----+------------+--------+--------+" << std::endl;
492  for (unsigned int s = 0; s < summary_.size(); s++) {
494 
495  std::stringstream line;
496 
498 
499  (*ofile) << line.str() << std::endl;
500  }
501  ofile->close();
502  delete ofile;
503 
504  ofile = new std::ofstream("SiStripApvGainExceptionSummary.txt", std::ofstream::trunc);
505  (*ofile) << " det id | APV | isConnected | FED |FEDCH|i2cAd|APVON| is_scanned |tickGain|gainInDB|" << std::endl;
506  (*ofile) << "----------+-----+-------------+-----+-----+-----+-----+------------+--------+--------+" << std::endl;
507  for (unsigned int s = 0; s < ex_summary_.size(); s++) {
509 
510  std::stringstream line;
511 
513 
514  (*ofile) << line.str() << std::endl;
515  }
516  ofile->close();
517  delete ofile;
518 }
519 
521  std::string conn = (summary.is_connected) ? "CONNECTED" : "NOT_CONNECTED";
522  std::string scan = (summary.is_scanned) ? "IN_SCAN" : "NOT_IN_SCAN";
523 
524  line << summary.det_id << " " << std::setw(3) << summary.offlineAPV_id << " " << std::setw(13) << conn << " "
525  << std::setw(3) << summary.FED_id << " " << std::setw(3) << summary.FED_ch << " " << std::setw(3)
526  << summary.i2cAdd << " " << std::setw(3) << summary.onlineAPV_id << " " << std::setw(11) << scan << " "
527  << std::setw(7) << summary.gain_from_scan << " " << std::setw(7) << summary.gain_in_db;
528 }
529 
530 bool SiStripApvGainFromFileBuilder::gain_from_maps(uint32_t det_id, int onlineAPV_id, float& gain) {
531  Gain* map = nullptr;
532 
533  // search det_id and APV in the good scan map
534  map = get_map(&gains_, onlineAPV_id);
535  if (map != nullptr) {
536  Gain::const_iterator el = map->find(det_id);
537  if (el != map->end()) {
538  gain = el->second;
539  return true;
540  }
541  }
542 
543  // search det_id and APV in the zero gain scan map
544  map = get_map(&negative_gains_, onlineAPV_id);
545  if (map != nullptr) {
546  Gain::const_iterator el = map->find(det_id);
547  if (el != map->end()) {
548  gain = el->second;
549  return true;
550  }
551  }
552 
553  //search det_id and APV in the negative gain scan map
554  map = get_map(&null_gains_, onlineAPV_id);
555  if (map != nullptr) {
556  Gain::const_iterator el = map->find(det_id);
557  if (el != map->end()) {
558  gain = el->second;
559  return true;
560  }
561  }
562 
563  return false;
564 }
565 
567  uint16_t totalAPVs,
568  std::vector<std::pair<int, float>>& gain) const {
569  std::stringstream ex_msg;
570  ex_msg << "two APVs with the same online id for det id " << det_id
571  << ". Please check the tick mark file or the read_tickmark routine." << std::endl;
572 
573  for (unsigned int i = 0; i < 6; i++) {
574  int offlineAPV_id = online2offline(i, totalAPVs);
575  try {
576  Gain* map = gains_.at(i);
577  if (map != nullptr) {
578  Gain::const_iterator el = map->find(det_id);
579  if (el != map->end()) {
580  if (gain[offlineAPV_id].second != k_InvalidGain)
581  throw(ex_msg.str());
582  gain[offlineAPV_id].second = el->second;
583  }
584  }
585  } catch (const std::out_of_range&) {
586  // nothing to do, just pass over
587  }
588 
589  try {
590  Gain* map = negative_gains_.at(i);
591  if (map != nullptr) {
592  Gain::const_iterator el = map->find(det_id);
593  if (el != map->end()) {
594  if (gain[offlineAPV_id].second != k_InvalidGain)
595  throw(ex_msg.str());
596  gain[offlineAPV_id].second = el->second;
597  }
598  }
599  } catch (const std::out_of_range&) {
600  // nothing to do, just pass over
601  }
602 
603  try {
604  Gain* map = null_gains_.at(i);
605  if (map != nullptr) {
606  Gain::const_iterator el = map->find(det_id);
607  if (el != map->end()) {
608  if (gain[offlineAPV_id].second != k_InvalidGain)
609  throw(ex_msg.str());
610  gain[offlineAPV_id].second = el->second;
611  }
612  }
613  } catch (const std::out_of_range&) {
614  // nothing to do, just pass over
615  }
616  }
617 }
618 
619 int SiStripApvGainFromFileBuilder::online2offline(uint16_t onlineAPV_id, uint16_t totalAPVs) const {
620  return (onlineAPV_id >= totalAPVs) ? onlineAPV_id - 2 : onlineAPV_id;
621 }
622 
625  desc.setComment("Conditions Builder for SiStripApvGain Objects (G1 gain) from tickmark height file");
626  desc.add<edm::FileInPath>("tickFile", edm::FileInPath("CondTools/SiStrip/data/tickheight.txt"));
627  desc.add<double>("gainThreshold", 0.)->setComment("threshold to retain the scan vale");
628  desc.add<double>("dummyAPVGain", (690. / k_GainNormalizationFactor)); // from TDR
629  desc.add<bool>("doGainNormalization", false)->setComment("normalize the output gain in DB by 640");
630  desc.add<bool>("putDummyIntoUncabled", false)->setComment("use default gain for uncabled APVs");
631  desc.add<bool>("putDummyIntoUnscanned", false)->setComment("use default gain for unscanned APVs");
632  desc.add<bool>("putDummyIntoOffChannels", false)->setComment("use default gain for APVs reading HV off modules");
633  desc.add<bool>("putDummyIntoBadChannels", false)->setComment("use default gain for bad APV channels");
634  desc.add<bool>("outputMaps", false)->setComment("prints ouput maps");
635  desc.add<bool>("outputSummary", false)->setComment("prints output summary");
636  descriptions.addWithDefaultLabel(desc);
637 }
638 
const edm::ESGetToken< SiStripDetCabling, SiStripDetCablingRcd > cablingToken_
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
void output_maps(std::vector< Gain *> *maps, const char *basename) const
const std::vector< const FedChannelConnection * > & getConnections(uint32_t det_id) const
std::string fullPath() const
Definition: FileInPath.cc:161
ret
prodAgent to be discontinued
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
SiStripApvGainFromFileBuilder(const edm::ParameterSet &iConfig)
reader
Definition: DQM.py:105
Log< level::Error, false > LogError
void createOneIOV(const T &payload, cond::Time_t firstSinceTime, const std::string &recordName)
#define LogTrace(id)
U second(std::pair< T, U > const &p)
void appendOneIOV(const T &payload, cond::Time_t sinceTime, const std::string &recordName)
void operator()(SiStripApvGainFromFileBuilder::Gain *el)
bool isNewTagRequest(const std::string &recordName)
bool gain_from_maps(uint32_t det_id, int onlineAPV_id, float &gain)
std::pair< ContainerIterator, ContainerIterator > Range
double f[11][100]
SiStripDetInfo read(std::string filePath)
bool getData(T &iHolder) const
Definition: EventSetup.h:122
void format_summary(std::stringstream &line, Summary summary) const
Log< level::Info, false > LogInfo
Gain * get_map(std::vector< Gain *> *maps, int onlineAPV_id)
HLT enums.
int online2offline(uint16_t onlineAPV_id, uint16_t totalAPVs) const
conn
Definition: getInfo.py:9
static constexpr char const *const kDefaultFile
bool isAvailable() const
Definition: Service.h:40
static const struct clean_up CleanUp
void analyze(const edm::Event &, const edm::EventSetup &) override
static void fillDescriptions(edm::ConfigurationDescriptions &)