CMS 3D CMS Logo

EcalSelectiveReadoutProducer.cc
Go to the documentation of this file.
10 //#include "DataFormats/EcalDigi/interface/EcalMGPASample.h"
11 
13 
14 #include <memory>
15 #include <fstream>
16 #include <atomic>
17 
18 
19 using namespace std;
20 
22  : params_(params),firstCallEB_(true),firstCallEE_(true),iEvent_(1)
23 {
24  //settings:
25  // settings which are only in python config files:
26  digiProducer_ = params.getParameter<string>("digiProducer");
27  ebdigiCollection_ = params.getParameter<std::string>("EBdigiCollection");
28  eedigiCollection_ = params.getParameter<std::string>("EEdigiCollection");
29  ebSRPdigiCollection_ = params.getParameter<std::string>("EBSRPdigiCollection");
30  eeSRPdigiCollection_ = params.getParameter<std::string>("EESRPdigiCollection");
31  ebSrFlagCollection_ = params.getParameter<std::string>("EBSrFlagCollection");
32  eeSrFlagCollection_ = params.getParameter<std::string>("EESrFlagCollection");
33  trigPrimProducer_ = params.getParameter<string>("trigPrimProducer");
34  trigPrimCollection_ = params.getParameter<string>("trigPrimCollection");
35  trigPrimBypass_ = params.getParameter<bool>("trigPrimBypass");
36  trigPrimBypassMode_ = params.getParameter<int>("trigPrimBypassMode");
37  dumpFlags_ = params.getUntrackedParameter<int>("dumpFlags", 0);
38  writeSrFlags_ = params.getUntrackedParameter<bool>("writeSrFlags", false);
39  produceDigis_ = params.getUntrackedParameter<bool>("produceDigis", true);
40  // settings which can come from either condition database or python configuration file:
41  useCondDb_ = false;
42  try{
43  if(params.getParameter<bool>("configFromCondDB")){
44  useCondDb_ = true;
45  }
46  } catch(cms::Exception){
47  /* pameter not found */
48  edm::LogWarning("EcalSelectiveReadout") << "Parameter configFromCondDB of EcalSelectiveReadout module not found. "
49  "Selective readout configuration will be read from python file.";
50  }
51  if(!useCondDb_){
52  settingsFromFile_ = unique_ptr<EcalSRSettings>(new EcalSRSettings());
55  }
56 
57  //declares the products made by this producer:
58  if(produceDigis_){
59  produces<EBDigiCollection>(ebSRPdigiCollection_);
60  produces<EEDigiCollection>(eeSRPdigiCollection_);
61  }
62 
63  if (writeSrFlags_) {
64  produces<EBSrFlagCollection>(ebSrFlagCollection_);
65  produces<EESrFlagCollection>(eeSrFlagCollection_);
66  }
67 
68  useFullReadout_ = false;
69  useFullReadout_ = params.getParameter<bool>("UseFullReadout");
70 
71  theGeometry = nullptr;
72  theTriggerTowerMap = nullptr;
73  theElecMap = nullptr;
74 
75  EB_token = consumes<EBDigiCollection>(edm::InputTag(digiProducer_, ebdigiCollection_));
76  EE_token = consumes<EEDigiCollection>(edm::InputTag(digiProducer_, eedigiCollection_));;
77  EcTP_token = consumes<EcalTrigPrimDigiCollection>(edm::InputTag(trigPrimProducer_, trigPrimCollection_));;
78 
79 }
80 
81 
82 
84 { }
85 
86 
87 void
89 {
90  if(useCondDb_){
91  //getting selective readout configuration:
93 
94  if(useFullReadout_){
95  eventSetup.get<EcalSRSettingsRcd>().get("fullReadout",hSr);
96  }
97  else{
98  eventSetup.get<EcalSRSettingsRcd>().get(hSr);
99  }
100  settings_ = hSr.product();
101  }
102 
103  //gets the trigger primitives:
104  EcalTrigPrimDigiCollection emptyTPColl;
105  const EcalTrigPrimDigiCollection* trigPrims =
106  (trigPrimBypass_ && trigPrimBypassMode_==0)?&emptyTPColl:getTrigPrims(event);
107 
108 
109  //gets the digis from the events:
110  EBDigiCollection dummyEbDigiColl;
111  EEDigiCollection dummyEeDigiColl;
112 
113  const EBDigiCollection* ebDigis = produceDigis_?getEBDigis(event)
114  :&dummyEbDigiColl;
115  const EEDigiCollection* eeDigis = produceDigis_?getEEDigis(event)
116  :&dummyEeDigiColl;
117 
118  //runs the selective readout algorithm:
119  unique_ptr<EBDigiCollection> selectedEBDigis;
120  unique_ptr<EEDigiCollection> selectedEEDigis;
121  unique_ptr<EBSrFlagCollection> ebSrFlags;
122  unique_ptr<EESrFlagCollection> eeSrFlags;
123 
124  if(produceDigis_){
125  selectedEBDigis = unique_ptr<EBDigiCollection>(new EBDigiCollection);
126  selectedEEDigis = unique_ptr<EEDigiCollection>(new EEDigiCollection);
127  }
128 
129  if(writeSrFlags_){
130  ebSrFlags = unique_ptr<EBSrFlagCollection>(new EBSrFlagCollection);
131  eeSrFlags = unique_ptr<EESrFlagCollection>(new EESrFlagCollection);
132  }
133 
134  if(suppressor_.get() == nullptr){
135  //Check the validity of EcalSRSettings
137 
138  //instantiates the selective readout algorithm:
139  suppressor_ = unique_ptr<EcalSelectiveReadoutSuppressor>(new EcalSelectiveReadoutSuppressor(params_, settings_));
140 
141  // check that everything is up-to-date
142  checkGeometry(eventSetup);
143  checkTriggerMap(eventSetup);
144  checkElecMap(eventSetup);
145  }
146 
147  suppressor_->run(eventSetup, *trigPrims, *ebDigis, *eeDigis,
148  selectedEBDigis.get(), selectedEEDigis.get(),
149  ebSrFlags.get(), eeSrFlags.get());
150 
151  if(dumpFlags_>=iEvent_){
152  ofstream ttfFile("TTF.txt", (iEvent_==1?ios::trunc:ios::app));
153  suppressor_->printTTFlags(ttfFile, iEvent_,
154  iEvent_==1?true:false);
155 
156  ofstream srfFile("SRF.txt", (iEvent_==1?ios::trunc:ios::app));
157  if(iEvent_==1){
158  suppressor_->getEcalSelectiveReadout()->printHeader(srfFile);
159  }
160  srfFile << "# Event " << iEvent_ << "\n";
161  suppressor_->getEcalSelectiveReadout()->print(srfFile);
162  srfFile << "\n";
163 
164  ofstream afFile("AF.txt", (iEvent_==1?ios::trunc:ios::app));
165  printSrFlags(afFile, *ebSrFlags, *eeSrFlags, iEvent_,
166  iEvent_==1?true:false);
167  }
168 
169  ++iEvent_; //event counter
170 
171  if(produceDigis_){
172  //puts the selected digis into the event:
173  event.put(std::move(selectedEBDigis), ebSRPdigiCollection_);
174  event.put(std::move(selectedEEDigis), eeSRPdigiCollection_);
175  }
176 
177  //puts the SR flags into the event:
178  if(writeSrFlags_) {
179  event.put(std::move(ebSrFlags), ebSrFlagCollection_);
180  event.put(std::move(eeSrFlags), eeSrFlagCollection_);
181  }
182 }
183 
184 const EBDigiCollection*
186 {
188  event.getByToken(EB_token, hEBDigis);
189  //product() method is called before id() in order to get an exception
190  //if the handle is not available (check not done by id() method).
191  const EBDigiCollection* result = hEBDigis.product();
192  if(firstCallEB_){
193  checkWeights(event, hEBDigis.id());
194  firstCallEB_ = false;
195  }
196  return result;
197 }
198 
199 const EEDigiCollection*
201 {
203  event.getByToken(EE_token, hEEDigis);
204  //product() method is called before id() in order to get an exception
205  //if the handle is not available (check not done by id() method).
206  const EEDigiCollection* result = hEEDigis.product();
207  if(firstCallEE_){
208  checkWeights(event, hEEDigis.id());
209  firstCallEE_ = false;
210  }
211  return result;
212 }
213 
216 {
218  event.getByToken(EcTP_token, hTPDigis);
219  return hTPDigis.product();
220 }
221 
222 
224 {
225  edm::ESHandle<CaloGeometry> hGeometry;
226  eventSetup.get<CaloGeometryRecord>().get(hGeometry);
227 
228  const CaloGeometry * pGeometry = &*hGeometry;
229 
230  // see if we need to update
231  if(pGeometry != theGeometry) {
232  theGeometry = pGeometry;
233  suppressor_->setGeometry(theGeometry);
234  }
235 }
236 
237 
239 {
240 
242  eventSetup.get<IdealGeometryRecord>().get(eTTmap);
243 
244  const EcalTrigTowerConstituentsMap * pMap = &*eTTmap;
245 
246  // see if we need to update
247  if(pMap!= theTriggerTowerMap) {
248  theTriggerTowerMap = pMap;
249  suppressor_->setTriggerMap(theTriggerTowerMap);
250  }
251 }
252 
253 
255 {
256 
258  eventSetup.get<EcalMappingRcd>().get(eElecmap);
259 
260  const EcalElectronicsMapping * pMap = &*eElecmap;
261 
262  // see if we need to update
263  if(pMap!= theElecMap) {
264  theElecMap = pMap;
265  suppressor_->setElecMap(theElecMap);
266  }
267 }
268 
269 
271  const char tccFlagMarker[] = { 'x', '.', 'S', '?', 'C', 'E', 'E', 'E', 'E'};
274 
275  //static bool firstCall=true;
276  // if(firstCall){
277  // firstCall=false;
278  os << "# TCC flag map\n#\n"
279  "# +-->Phi " << tccFlagMarker[0+1] << ": 000 (low interest)\n"
280  "# | " << tccFlagMarker[1+1] << ": 001 (mid interest)\n"
281  "# | " << tccFlagMarker[2+1] << ": 010 (not valid)\n"
282  "# V Eta " << tccFlagMarker[3+1] << ": 011 (high interest)\n"
283  "# " << tccFlagMarker[4+1] << ": 1xx forced readout (Hw error)\n"
284  "#\n";
285  //}
286 
287  vector<vector<int> > ttf(nEta, vector<int>(nPhi, -1));
289  it != tp.end(); ++it){
290  const EcalTriggerPrimitiveDigi& trigPrim = *it;
291  if(trigPrim.size()>0){
292  int iEta = trigPrim.id().ieta();
293  int iEta0 = iEta<0?iEta+nEta/2:iEta+nEta/2-1;
294  int iPhi0 = trigPrim.id().iphi() - 1;
295  ttf[iEta0][iPhi0] = trigPrim.ttFlag();
296  }
297  }
298  for(int iEta=0; iEta<nEta; ++iEta){
299  for(int iPhi=0; iPhi<nPhi; ++iPhi){
300  os << tccFlagMarker[ttf[iEta][iPhi]+1];
301  }
302  os << "\n";
303  }
304 }
305 
307  const edm::ProductID& noZsDigiId) const{
308  const vector<float> & weights = settings_->dccNormalizedWeights_[0]; //params_.getParameter<vector<double> >("dccNormalizedWeights");
310  static std::atomic<bool> warnWeightCnt{true};
311  bool expected = true;
312  if((int)weights.size() > nFIRTaps && warnWeightCnt.compare_exchange_strong(expected,false,std::memory_order_acq_rel)){
313  edm::LogWarning("Configuration") << "The list of DCC zero suppression FIR "
314  "weights given in parameter dccNormalizedWeights is longer "
315  "than the expected depth of the FIR filter :(" << nFIRTaps << "). "
316  "The last weights will be discarded.";
317  }
318 
319  if(!weights.empty()){
320  int iMaxWeight = 0;
321  double maxWeight = weights[iMaxWeight];
322  //looks for index of maximum weight
323  for(unsigned i=0; i<weights.size(); ++i){
324  if(weights[i]>maxWeight){
325  iMaxWeight = i;
326  maxWeight = weights[iMaxWeight];
327  }
328  }
329 
330  //position of time sample whose maximum weight is applied:
331  int maxWeightBin = settings_->ecalDccZs1stSample_[0] //params_.getParameter<int>("ecalDccZs1stSample")
332  + iMaxWeight;
333 
334  //gets the bin of maximum (in case of raw data it will not exist)
335  int binOfMax = 0;
336  bool rc = getBinOfMax(evt, noZsDigiId, binOfMax);
337 
338  if(rc && maxWeightBin!=binOfMax){
339  edm::LogWarning("Configuration")
340  << "The maximum weight of DCC zero suppression FIR filter is not "
341  "applied to the expected maximum sample(" << binOfMax
342  << (binOfMax==1?"st":(binOfMax==2?"nd":(binOfMax==3?"rd":"th")))
343  << " time sample). This may indicate faulty 'dccNormalizedWeights' "
344  "or 'ecalDccZs1sSample' parameters.";
345  }
346  }
347 }
348 
349 bool
351  const edm::ProductID& noZsDigiId,
352  int& binOfMax) const{
353  bool rc;
354  const edm::Provenance p=evt.getProvenance(noZsDigiId);
356  vector<string> ebDigiParamList = result.getParameterNames();
357  string bofm("binOfMaximum");
358  if(find(ebDigiParamList.begin(), ebDigiParamList.end(), bofm)
359  != ebDigiParamList.end()){//bofm found
360  binOfMax=result.getParameter<int>("binOfMaximum");
361  rc = true;
362  } else{
363  rc = false;
364  }
365  return rc;
366 }
367 
368 void
370  const EBSrFlagCollection& ebSrFlags,
371  const EESrFlagCollection& eeSrFlags,
372  int iEvent,
373  bool withHeader){
374  const char srpFlagMarker[] = {'.', 'z', 'Z', 'F', '4','5','6','7'};
375  if(withHeader){
376  time_t t;
377  time(&t);
378  const char* date = ctime(&t);
379  os << "#SRP flag map\n#\n"
380  "# Generatied on: " << date << "\n#\n"
381  "# +-->Phi/Y " << srpFlagMarker[0] << ": suppressed\n"
382  "# | " << srpFlagMarker[1] << ": ZS 1\n"
383  "# | " << srpFlagMarker[2] << ": ZS 2\n"
384  "# V Eta/X " << srpFlagMarker[3] << ": full readout\n"
385  "#\n";
386  }
387 
388  //EE-,EB,EE+ map wil be written onto file in following format:
389  //
390  // 72
391  // <-------------->
392  // 20
393  // <--->
394  // EEE A +-----> Y
395  // EEEEE | |
396  // EE EE | 20 EE- |
397  // EEEEE | |
398  // EEE V V X
399  // BBBBBBBBBBBBBBBBB A
400  // BBBBBBBBBBBBBBBBB | +-----> Phi
401  // BBBBBBBBBBBBBBBBB | |
402  // BBBBBBBBBBBBBBBBB | 34 EB |
403  // BBBBBBBBBBBBBBBBB | |
404  // BBBBBBBBBBBBBBBBB | V Eta
405  // BBBBBBBBBBBBBBBBB |
406  // BBBBBBBBBBBBBBBBB |
407  // BBBBBBBBBBBBBBBBB V
408  // EEE A +-----> Y
409  // EEEEE | |
410  // EE EE | 20 EE+ |
411  // EEEEE | |
412  // EEE V V X
413  //
414  //
415  //
416  //
417  //event header:
418  if(iEvent>=0){
419  os << "# Event " << iEvent << "\n";
420  }
421 
422  //retrieve flags:
423  const int nEndcaps = 2;
424  const int nScX = 20;
425  const int nScY = 20;
426  int eeSrf[nEndcaps][nScX][nScY];
427  for(size_t i=0; i < sizeof(eeSrf)/sizeof(int); ((int*)eeSrf)[i++] = -1){};
428  for(EESrFlagCollection::const_iterator it = eeSrFlags.begin();
429  it != eeSrFlags.end(); ++it){
430  const EESrFlag& flag = *it;
431  int iZ0 = flag.id().zside()>0?1:0;
432  int iX0 = flag.id().ix()-1;
433  int iY0 = flag.id().iy()-1;
434  assert(iZ0>=0 && iZ0<nEndcaps);
435  assert(iX0>=0 && iX0<nScX);
436  assert(iY0>=0 && iY0<nScY);
437  eeSrf[iZ0][iX0][iY0] = flag.value();
438  }
439  const int nEbTtEta = 34;
440  const int nEeTtEta = 11;
441  const int nTtEta = nEeTtEta*2+nEbTtEta;
442  const int nTtPhi = 72;
443  int ebSrf[nEbTtEta][nTtPhi];
444  for(size_t i=0; i<sizeof(ebSrf)/sizeof(int); ((int*)ebSrf)[i++] = -1){};
445  for(EBSrFlagCollection::const_iterator it = ebSrFlags.begin();
446  it != ebSrFlags.end(); ++it){
447 
448  const EBSrFlag& flag = *it;
449  int iEta = flag.id().ieta();
450  int iEta0 = iEta + nTtEta/2 - (iEta>=0?1:0); //0->55 from eta=-3 to eta=3
451  int iEbEta0 = iEta0 - nEeTtEta;//0->33 from eta=-1.48 to eta=1.48
452  int iPhi0 = flag.id().iphi() - 1;
453  assert(iEbEta0>=0 && iEbEta0<nEbTtEta);
454  assert(iPhi0>=0 && iPhi0<nTtPhi);
455 
456 // cout << __FILE__ << ":" << __LINE__ << ": "
457 // << iEta << "\t" << flag.id().iphi() << " -> "
458 // << iEbEta0 << "\t" << iPhi0
459 // << "... Flag: " << flag.value() << "\n";
460 
461 
462  ebSrf[iEbEta0][iPhi0] = flag.value();
463  }
464 
465 
466  //print flags:
467 
468  //EE-
469  for(int iX0=0; iX0<nScX; ++iX0){
470  for(int iY0=0; iY0<nScY; ++iY0){
471  int srFlag = eeSrf[0][iX0][iY0];
472  assert(srFlag>=-1
473  && srFlag<(int)(sizeof(srpFlagMarker)/sizeof(srpFlagMarker[0])));
474  os << (srFlag==-1?' ':srpFlagMarker[srFlag]);
475  }
476  os << "\n"; //one Y supercystal column per line
477  } //next supercrystal X-index
478 
479  //EB
480  for(int iEta0 = 0;
481  iEta0 < nEbTtEta;
482  ++iEta0){
483  for(int iPhi0 = 0; iPhi0 < nTtPhi; ++iPhi0){
484  int srFlag = ebSrf[iEta0][iPhi0];
485  assert(srFlag>=-1
486  && srFlag<(int)(sizeof(srpFlagMarker)/sizeof(srpFlagMarker[0])));
487  os << (srFlag==-1?'?':srpFlagMarker[srFlag]);
488  }
489  os << "\n"; //one phi per line
490  }
491 
492  //EE+
493  for(int iX0=0; iX0<nScX; ++iX0){
494  for(int iY0=0; iY0<nScY; ++iY0){
495  int srFlag = eeSrf[1][iX0][iY0];
496  assert(srFlag>=-1
497  && srFlag<(int)(sizeof(srpFlagMarker)/sizeof(srpFlagMarker[0])));
498  os << (srFlag==-1?' ':srpFlagMarker[srFlag]);
499  }
500  os << "\n"; //one Y supercystal column per line
501  } //next supercrystal X-index
502 
503  //event trailer:
504  os << "\n";
505 }
506 
508  if(settings.dccNormalizedWeights_.size() != 1){
509  throw cms::Exception("Configuration") << "Selective readout emulator, EcalSelectiveReadout, supports only single set of ZS weights. "
510  "while the configuration contains " << settings.dccNormalizedWeights_.size() << " set(s)\n";
511  }
512 
513 // if(settings.dccNormalizedWeights_.size() != 1
514 // && settings.dccNormalizedWeights_.size() != 2
515 // && settings.dccNormalizedWeights_.size() != 54
516 // && settings.dccNormalizedWeights_.size() != 75848){
517 // throw cms::Exception("Configuration") << "Invalid number of DCC weight set (" << settings.dccNormalizedWeights_.size()
518 // << ") in condition object EcalSRSetting::dccNormalizedWeights_. "
519 // << "Valid counts are: 1 (single set), 2 (EB and EE), 54 (one per DCC) and 75848 "
520 // "(one per crystal)\n";
521 // }
522 
523  if(settings.dccNormalizedWeights_.size() != settings.ecalDccZs1stSample_.size()){
524  throw cms::Exception("Configuration") << "Inconsistency between number of weigth sets ("
525  << settings.dccNormalizedWeights_.size() << ") and "
526  << "number of ecalDccZs1Sample values ("
527  << settings.ecalDccZs1stSample_.size() << ").";
528  }
529 }
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
int value() const
Definition: EcalSrFlag.h:44
const EBDigiCollection * getEBDigis(edm::Event &event)
void checkTriggerMap(const edm::EventSetup &eventSetup)
std::unique_ptr< EcalSelectiveReadoutSuppressor > suppressor_
ProductID id() const
Definition: HandleBase.cc:15
static void importParameterSet(EcalSRSettings &sr, const edm::ParameterSet &ps)
void checkGeometry(const edm::EventSetup &eventSetup)
void produce(edm::Event &event, const edm::EventSetup &eventSetup) override
std::vector< EcalTriggerPrimitiveDigi >::const_iterator const_iterator
std::vector< std::vector< float > > dccNormalizedWeights_
const char tccFlagMarker[]
Definition: GenABIO.cc:176
bool getBinOfMax(const edm::Event &evt, const edm::ProductID &noZsDigiId, int &binOfMax) const
void printTTFlags(const EcalTrigPrimDigiCollection &tp, std::ostream &os) const
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
int ieta() const
get the tower ieta
edm::EDGetTokenT< EBDigiCollection > EB_token
void checkElecMap(const edm::EventSetup &eventSetup)
int iEvent
Definition: GenABIO.cc:230
edm::SortedCollection< EBSrFlag > EBSrFlagCollection
int ix() const
Definition: EcalScDetId.h:71
const EcalTrigTowerConstituentsMap * theTriggerTowerMap
edm::SortedCollection< EESrFlag > EESrFlagCollection
std::vector< int > ecalDccZs1stSample_
const EEDigiCollection * getEEDigis(edm::Event &event)
const EcalElectronicsMapping * theElecMap
std::vector< std::string > getParameterNames() const
void checkWeights(const edm::Event &evt, const edm::ProductID &noZSDigiId) const
int iy() const
Definition: EcalScDetId.h:77
const_iterator end() const
const EcalTrigTowerDetId & id() const override
Definition: EBSrFlag.h:36
int iphi() const
get the tower iphi
static const int nEndcaps
Definition: GenABIO.cc:126
const EcalTrigPrimDigiCollection * getTrigPrims(edm::Event &event) const
const EcalTrigTowerDetId & id() const
std::unique_ptr< EcalSRSettings > settingsFromFile_
T const * product() const
Definition: Handle.h:81
static const size_t nTriggerTowersInEta
int zside() const
Definition: EcalScDetId.h:65
static const size_t nTriggerTowersInPhi
edm::EDGetTokenT< EcalTrigPrimDigiCollection > EcTP_token
edm::EDGetTokenT< EEDigiCollection > EE_token
T get() const
Definition: EventSetup.h:63
static void printSrFlags(std::ostream &os, const EBSrFlagCollection &ebSrFlags, const EESrFlagCollection &eeSrFlags, int iEvent=-1, bool withHeader=true)
EcalSelectiveReadoutProducer(const edm::ParameterSet &params)
const EcalScDetId & id() const override
Definition: EESrFlag.h:37
Provenance getProvenance(BranchID const &theID) const
Definition: Event.cc:129
static void checkValidity(const EcalSRSettings &settings)
int ttFlag() const
get the Trigger tower Flag of interesting sample
T const * product() const
Definition: ESHandle.h:86
ParameterSet const & parameterSet(Provenance const &provenance)
Definition: Provenance.cc:11
def move(src, dest)
Definition: eostools.py:510
const_iterator begin() const
const char srpFlagMarker[]
Definition: GenABIO.cc:175
Definition: event.py:1