CMS 3D CMS Logo

EcalABAnalyzer.cc
Go to the documentation of this file.
1 /*
2  * \class EcalABAnalyzer
3  *
4  * primary author: Julie Malcles - CEA/Saclay
5  * author: Gautier Hamel De Monchenault - CEA/Saclay
6  */
7 
8 #include <TAxis.h>
9 #include <TH1.h>
10 #include <TProfile.h>
11 #include <TTree.h>
12 #include <TChain.h>
13 #include <TFile.h>
14 #include <TMath.h>
15 
17 
18 #include <sstream>
19 #include <fstream>
20 #include <iomanip>
21 
29 
37 
38 using namespace std;
39 
40 //========================================================================
42  //========================================================================
43  : iEvent(0),
44  eventHeaderCollection_(iConfig.getParameter<std::string>("eventHeaderCollection")),
45  eventHeaderProducer_(iConfig.getParameter<std::string>("eventHeaderProducer")),
46  digiCollection_(iConfig.getParameter<std::string>("digiCollection")),
47  digiProducer_(iConfig.getParameter<std::string>("digiProducer")),
48  rawDataToken_(consumes<EcalRawDataCollection>(edm::InputTag(eventHeaderProducer_, eventHeaderCollection_))),
49  mappingToken_(esConsumes()),
50  // framework parameters with default values
51  _nsamples(iConfig.getUntrackedParameter<unsigned int>("nSamples", 10)),
52  _presample(iConfig.getUntrackedParameter<unsigned int>("nPresamples", 2)),
53  _firstsample(iConfig.getUntrackedParameter<unsigned int>("firstSample", 1)),
54  _lastsample(iConfig.getUntrackedParameter<unsigned int>("lastSample", 2)),
55  _timingcutlow(iConfig.getUntrackedParameter<unsigned int>("timingCutLow", 2)),
56  _timingcuthigh(iConfig.getUntrackedParameter<unsigned int>("timingCutHigh", 9)),
57  _timingquallow(iConfig.getUntrackedParameter<unsigned int>("timingQualLow", 3)),
58  _timingqualhigh(iConfig.getUntrackedParameter<unsigned int>("timingQualHigh", 8)),
59  _ratiomincutlow(iConfig.getUntrackedParameter<double>("ratioMinCutLow", 0.4)),
60  _ratiomincuthigh(iConfig.getUntrackedParameter<double>("ratioMinCutHigh", 0.95)),
61  _ratiomaxcutlow(iConfig.getUntrackedParameter<double>("ratioMaxCutLow", 0.8)),
62  _presamplecut(iConfig.getUntrackedParameter<double>("presampleCut", 5.0)),
63  _niter(iConfig.getUntrackedParameter<unsigned int>("nIter", 3)),
64  _alpha(iConfig.getUntrackedParameter<double>("alpha", 1.5076494)),
65  _beta(iConfig.getUntrackedParameter<double>("beta", 1.5136036)),
66  _nevtmax(iConfig.getUntrackedParameter<unsigned int>("nEvtMax", 200)),
67  _noise(iConfig.getUntrackedParameter<double>("noise", 2.0)),
68  _chi2cut(iConfig.getUntrackedParameter<double>("chi2cut", 100.0)),
69  _ecalPart(iConfig.getUntrackedParameter<std::string>("ecalPart", "EB")),
70  _fedid(iConfig.getUntrackedParameter<int>("fedId", -999)),
71  _qualpercent(iConfig.getUntrackedParameter<double>("qualPercent", 0.2)),
72  _debug(iConfig.getUntrackedParameter<int>("debug", 0)),
73  resdir_(iConfig.getUntrackedParameter<std::string>("resDir")),
74  nCrys(NCRYSEB),
75  runType(-1),
76  runNum(0),
77  fedID(-1),
78  dccID(-1),
79  side(2),
80  lightside(2),
81  iZ(1),
82  phi(-1),
83  eta(-1),
84  event(0),
85  color(-1),
86  channelIteratorEE(0)
87 
88 //========================================================================
89 
90 {
91  if (_ecalPart == "EB") {
92  ebDigiToken_ = consumes<EBDigiCollection>(edm::InputTag(digiProducer_, digiCollection_));
93  } else if (_ecalPart == "EE") {
94  eeDigiToken_ = consumes<EEDigiCollection>(edm::InputTag(digiProducer_, digiCollection_));
95  }
96 
97  // Geometrical constants initialization
98 
99  if (_ecalPart == "EB") {
100  nCrys = NCRYSEB;
101  } else {
102  nCrys = NCRYSEE;
103  }
104  iZ = 1;
105  if (_fedid <= 609)
106  iZ = -1;
107 
108  for (unsigned int j = 0; j < nCrys; j++) {
109  iEta[j] = -1;
110  iPhi[j] = -1;
111  iTowerID[j] = -1;
112  iChannelID[j] = -1;
113  idccID[j] = -1;
114  iside[j] = -1;
115  wasTimingOK[j] = true;
116  wasGainOK[j] = true;
117  nevtAB[j] = 0;
118  }
119 
120  // Quality check flags
121 
122  isGainOK = true;
123  isTimingOK = true;
124 
125  // Objects dealing with pulses
126 
128  _presample,
129  _firstsample,
130  _lastsample,
138 
139  // Objects needed for npresample calculation
140 
141  Delta01 = new TMom();
142  Delta12 = new TMom();
143  _fitab = true;
144 }
145 
146 //========================================================================
148  //========================================================================
149 
150  // do anything here that needs to be done at desctruction time
151  // (e.g. close files, deallocate resources etc.)
152 }
153 
154 //========================================================================
156  //========================================================================
157 
158  //Calculate alpha and beta
159 
160  // Define output results filenames and shape analyzer object (alpha,beta)
161  //=====================================================================
162 
163  // 1) AlphaBeta files
164 
165  doesABTreeExist = true;
166 
167  std::stringstream nameabinitfile;
168  nameabinitfile << resdir_ << "/ABInit.root";
169  alphainitfile = nameabinitfile.str();
170 
171  std::stringstream nameabfile;
172  std::stringstream link;
173  nameabfile << resdir_ << "/AB.root";
174 
175  FILE* test;
176  test = fopen(nameabinitfile.str().c_str(), "r");
177  if (test == nullptr) {
178  doesABTreeExist = false;
179  _fitab = true;
180  } else {
181  fclose(test);
182  }
183 
184  TFile* fAB = nullptr;
185  TTree* ABInit = nullptr;
186  if (doesABTreeExist) {
187  fAB = new TFile(nameabinitfile.str().c_str());
188  }
189  if (doesABTreeExist && fAB) {
190  ABInit = (TTree*)fAB->Get("ABCol0");
191  }
192 
193  // 2) Shape analyzer
194 
195  if (doesABTreeExist && fAB && ABInit && ABInit->GetEntries() != 0) {
196  shapana = new TShapeAnalysis(ABInit, _alpha, _beta, 5.5, 1.0);
197  doesABTreeExist = true;
198  } else {
199  shapana = new TShapeAnalysis(_alpha, _beta, 5.5, 1.0);
200  doesABTreeExist = false;
201  _fitab = true;
202  }
204 
205  if (doesABTreeExist && fAB)
206  fAB->Close();
207 
208  if (_fitab) {
209  alphafile = nameabfile.str();
210  } else {
212  link << "ln -s " << resdir_ << "/ABInit.root " << resdir_ << "/AB.root";
213  system(link.str().c_str());
214  }
215 
216  // Define output results files' names
217 
218  std::stringstream namefile;
219  namefile << resdir_ << "/AB.root";
220  alphafile = namefile.str();
221 }
222 
223 //========================================================================
225  //========================================================================
226 
227  ++iEvent;
228 
229  // retrieving DCC header
231  const EcalRawDataCollection* DCCHeader = nullptr;
232  e.getByToken(rawDataToken_, pDCCHeader);
233  if (!pDCCHeader.isValid()) {
234  edm::LogError("nodata") << "Error! can't get the product retrieving DCC header" << eventHeaderCollection_.c_str()
235  << " " << eventHeaderProducer_.c_str();
236  } else {
237  DCCHeader = pDCCHeader.product();
238  }
239 
240  //retrieving crystal data from Event
242  const EBDigiCollection* EBDigi = nullptr;
244  const EEDigiCollection* EEDigi = nullptr;
245  if (_ecalPart == "EB") {
246  e.getByToken(ebDigiToken_, pEBDigi);
247  if (!pEBDigi.isValid()) {
248  edm::LogError("nodata") << "Error! can't get the product retrieving EB crystal data " << digiCollection_.c_str();
249  } else {
250  EBDigi = pEBDigi.product();
251  }
252  } else if (_ecalPart == "EE") {
253  e.getByToken(eeDigiToken_, pEEDigi);
254  if (!pEEDigi.isValid()) {
255  edm::LogError("nodata") << "Error! can't get the product retrieving EE crystal data " << digiCollection_.c_str();
256  } else {
257  EEDigi = pEEDigi.product();
258  }
259  } else {
260  edm::LogError("cfg_error") << " Wrong ecalPart in cfg file";
261  return;
262  }
263 
264  // retrieving electronics mapping
265  const auto& TheMapping = c.getData(mappingToken_);
266 
267  // =============================
268  // Decode DCCHeader Information
269  // =============================
270 
271  for (EcalRawDataCollection::const_iterator headerItr = DCCHeader->begin(); headerItr != DCCHeader->end();
272  ++headerItr) {
273  // Get run type and run number
274 
275  int fed = headerItr->fedId();
276  if (fed != _fedid && _fedid != -999)
277  continue;
278 
279  runType = headerItr->getRunType();
280  runNum = headerItr->getRunNumber();
281  event = headerItr->getLV1();
282 
283  dccID = headerItr->getDccInTCCCommand();
284  fedID = headerItr->fedId();
285  lightside = headerItr->getRtHalf();
286 
287  // Check fed corresponds to the DCC in TCC
288 
289  if (600 + dccID != fedID)
290  continue;
291 
292  // Cut on runType
293 
296  return;
297 
298  // Retrieve laser color and event number
299 
300  EcalDCCHeaderBlock::EcalDCCEventSettings settings = headerItr->getEventSettings();
301  color = settings.wavelength;
302  if (color < 0)
303  return;
304 
305  std::vector<int>::iterator iter = find(colors.begin(), colors.end(), color);
306  if (iter == colors.end()) {
307  colors.push_back(color);
308  }
309  }
310 
311  // Cut on fedID
312 
313  if (fedID != _fedid && _fedid != -999)
314  return;
315 
316  // ===========================
317  // Decode EBDigis Information
318  // ===========================
319 
320  int adcGain = 0;
321 
322  if (EBDigi) {
323  // Loop on crystals
324  //===================
325 
326  for (EBDigiCollection::const_iterator digiItr = EBDigi->begin(); digiItr != EBDigi->end();
327  ++digiItr) { // Loop on crystals
328 
329  // Retrieve geometry
330  //===================
331 
332  EBDetId id_crystal(digiItr->id());
333  EBDataFrame df(*digiItr);
334 
335  int etaG = id_crystal.ieta(); // global
336  int phiG = id_crystal.iphi(); // global
337 
338  int etaL; // local
339  int phiL; // local
340  std::pair<int, int> LocalCoord = MEEBGeom::localCoord(etaG, phiG);
341 
342  etaL = LocalCoord.first;
343  phiL = LocalCoord.second;
344 
345  eta = etaG;
346  phi = phiG;
347 
348  side = MEEBGeom::side(etaG, phiG);
349 
350  // Recover the TT id and the electronic crystal numbering from EcalElectronicsMapping
351 
352  EcalElectronicsId elecid_crystal = TheMapping.getElectronicsId(id_crystal);
353 
354  int towerID = elecid_crystal.towerId();
355  int strip = elecid_crystal.stripId();
356  int xtal = elecid_crystal.xtalId();
357  int channelID = 5 * (strip - 1) + xtal - 1;
358 
359  unsigned int channel = MEEBGeom::electronic_channel(etaL, phiL);
360 
361  assert(channel < nCrys);
362 
363  iEta[channel] = eta;
364  iPhi[channel] = phi;
365  iTowerID[channel] = towerID;
366  iChannelID[channel] = channelID;
367  idccID[channel] = dccID;
368  iside[channel] = side;
369 
370  // APD Pulse
371  //===========
372 
373  // Loop on adc samples
374 
375  for (unsigned int i = 0; i < (*digiItr).size(); ++i) {
376  EcalMGPASample samp_crystal(df.sample(i));
377  adc[i] = samp_crystal.adc();
378  adcG[i] = samp_crystal.gainId();
379  adc[i] *= adcG[i];
380  if (i == 0)
381  adcGain = adcG[i];
382  if (i > 0)
383  adcGain = TMath::Max(adcG[i], adcGain);
384  }
385 
387 
388  // Quality checks
389  //================
390 
391  if (adcGain != 1)
392  nEvtBadGain[channel]++;
393  if (!APDPulse->isTimingQualOK())
394  nEvtBadTiming[channel]++;
395  nEvtTot[channel]++;
396 
397  // Fill if Pulse is fine
398  //=======================
399 
400  if (APDPulse->isPulseOK() && lightside == side) {
403 
404  if (nevtAB[channel] < _nevtmax && _fitab) {
405  if (doesABTreeExist)
406  shapana->putAllVals(channel, adc, eta, phi);
407  else
408  shapana->putAllVals(channel, adc, eta, phi, dccID, side, towerID, channelID);
409  nevtAB[channel]++;
410  }
411  }
412  }
413 
414  } else if (EEDigi) {
415  // Loop on crystals
416  //===================
417 
418  for (EEDigiCollection::const_iterator digiItr = EEDigi->begin(); digiItr != EEDigi->end();
419  ++digiItr) { // Loop on crystals
420 
421  // Retrieve geometry
422  //===================
423 
424  EEDetId id_crystal(digiItr->id());
425  EEDataFrame df(*digiItr);
426 
427  phi = id_crystal.ix();
428  eta = id_crystal.iy();
429 
430  int iX = (phi - 1) / 5 + 1;
431  int iY = (eta - 1) / 5 + 1;
432 
433  side = MEEEGeom::side(iX, iY, iZ);
434  EcalElectronicsId elecid_crystal = TheMapping.getElectronicsId(id_crystal);
435 
436  int towerID = elecid_crystal.towerId();
437  int channelID = elecid_crystal.channelId() - 1;
438 
439  int hashedIndex = 100000 * eta + phi;
440 
441  if (channelMapEE.count(hashedIndex) == 0) {
444  }
445 
446  unsigned int channel = channelMapEE[hashedIndex];
447 
448  assert(channel < nCrys);
449 
450  iEta[channel] = eta;
451  iPhi[channel] = phi;
452  iTowerID[channel] = towerID;
453  iChannelID[channel] = channelID;
454  idccID[channel] = dccID;
455  iside[channel] = side;
456 
457  // APD Pulse
458  //===========
459 
460  if ((*digiItr).size() > 10)
461  edm::LogVerbatim("EcalABAnalyzer") << "SAMPLES SIZE > 10!" << (*digiItr).size();
462 
463  // Loop on adc samples
464 
465  for (unsigned int i = 0; i < (*digiItr).size(); ++i) {
466  EcalMGPASample samp_crystal(df.sample(i));
467  adc[i] = samp_crystal.adc();
468  adcG[i] = samp_crystal.gainId();
469  adc[i] *= adcG[i];
470 
471  if (i == 0)
472  adcGain = adcG[i];
473  if (i > 0)
474  adcGain = TMath::Max(adcG[i], adcGain);
475  }
476 
478 
479  // Quality checks
480  //================
481 
482  if (adcGain != 1)
483  nEvtBadGain[channel]++;
484  if (!APDPulse->isTimingQualOK())
485  nEvtBadTiming[channel]++;
486  nEvtTot[channel]++;
487 
488  // Fill if Pulse is fine
489  //=======================
490 
491  if (APDPulse->isPulseOK() && lightside == side) {
494 
495  if (nevtAB[channel] < _nevtmax && _fitab) {
496  if (doesABTreeExist)
497  shapana->putAllVals(channel, adc, eta, phi);
498  else
499  shapana->putAllVals(channel, adc, eta, phi, dccID, side, towerID, channelID);
500  nevtAB[channel]++;
501  }
502  }
503  }
504  }
505 } // analyze
506 
507 //========================================================================
509  //========================================================================
510 
511  edm::LogVerbatim("EcalABAnalyzer") << "\n\t+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+";
512  edm::LogVerbatim("EcalABAnalyzer") << "\t+=+ Analyzing data: getting (alpha, beta) +=+";
513 
514  // Adjust channel numbers for EE
515  //===============================
516 
517  if (_ecalPart == "EE") {
518  nCrys = channelMapEE.size();
520  }
521 
522  // Set presamples number
523  //======================
524 
525  double delta01 = Delta01->getMean();
526  double delta12 = Delta12->getMean();
527  if (delta12 > _presamplecut) {
528  _presample = 2;
529  if (delta01 > _presamplecut)
530  _presample = 1;
531  }
532 
535 
536  // Get alpha and beta
537  //======================
538 
539  if (_fitab) {
540  edm::LogVerbatim("EcalABAnalyzer") << "\n\t+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+";
541  edm::LogVerbatim("EcalABAnalyzer") << "\t+=+ Analyzing data: getting (alpha, beta) +=+";
542  TFile* fAB = nullptr;
543  TTree* ABInit = nullptr;
544  if (doesABTreeExist) {
545  fAB = new TFile(alphainitfile.c_str());
546  }
547  if (doesABTreeExist && fAB) {
548  ABInit = (TTree*)fAB->Get("ABCol0");
549  }
550  shapana->computeShape(alphafile, ABInit);
551 
552  // Set quality flags for gains and timing
553 
554  double BadGainEvtPercentage = 0.0;
555  double BadTimingEvtPercentage = 0.0;
556 
557  int nChanBadGain = 0;
558  int nChanBadTiming = 0;
559 
560  for (unsigned int i = 0; i < nCrys; i++) {
561  if (nEvtTot[i] != 0) {
562  BadGainEvtPercentage = double(nEvtBadGain[i]) / double(nEvtTot[i]);
563  BadTimingEvtPercentage = double(nEvtBadTiming[i]) / double(nEvtTot[i]);
564  }
565  if (BadGainEvtPercentage > _qualpercent) {
566  wasGainOK[i] = false;
567  nChanBadGain++;
568  }
569  if (BadTimingEvtPercentage > _qualpercent) {
570  wasTimingOK[i] = false;
571  nChanBadTiming++;
572  }
573  }
574 
575  double BadGainChanPercentage = double(nChanBadGain) / double(nCrys);
576  double BadTimingChanPercentage = double(nChanBadTiming) / double(nCrys);
577 
578  if (BadGainChanPercentage > _qualpercent)
579  isGainOK = false;
580  if (BadTimingChanPercentage > _qualpercent)
581  isTimingOK = false;
582 
583  if (!isGainOK)
584  edm::LogVerbatim("EcalABAnalyzer") << "\t+=+ ............................ WARNING! APD GAIN WAS NOT 1 +=+";
585  if (!isTimingOK)
586  edm::LogVerbatim("EcalABAnalyzer") << "\t+=+ ............................ WARNING! TIMING WAS BAD +=+";
587 
588  edm::LogVerbatim("EcalABAnalyzer") << "\t+=+ .................................... done +=+";
589  edm::LogVerbatim("EcalABAnalyzer") << "\t+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+";
590  }
591 }
592 
void addEntry(double val)
Definition: TMom.cc:88
Log< level::Info, true > LogVerbatim
static XYCoord localCoord(int icr)
Definition: MEEBGeom.cc:142
unsigned int nCrys
int nEvtBadGain[1700]
const double _qualpercent
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
std::string alphainitfile
int idccID[1700]
const double _ratiomincuthigh
double getDelta(int, int)
Definition: TAPDPulse.cc:116
const unsigned int _nevtmax
const std::string digiCollection_
Ecal readout channel identification [32:20] Unused (so far) [19:13] DCC id [12:6] tower [5:3] strip [...
#define NCRYSEE
bool setPulse(double *)
Definition: TAPDPulse.cc:86
static int side(SuperCrysCoord iX, SuperCrysCoord iY, int iz)
Definition: MEEEGeom.cc:1155
T const * product() const
Definition: Handle.h:70
std::vector< T >::const_iterator const_iterator
const unsigned int _timingcuthigh
const double _ratiomincutlow
void computeShape(std::string namefile, TTree *)
const unsigned int _firstsample
void putAllVals(int, double *, int, int)
Log< level::Error, false > LogError
Definition: TMom.h:7
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
assert(be >=bs)
const std::string _ecalPart
double adc[10]
const unsigned int _lastsample
const double _noise
const unsigned int _timingqualhigh
std::string alphafile
int hashedIndex(int ieta, int iphi)
Definition: EcalPyUtils.cc:36
~EcalABAnalyzer() override
const unsigned int _nsamples
int iEvent
Definition: GenABIO.cc:224
static int electronic_channel(EBLocalCoord ix, EBLocalCoord iy)
Definition: MEEBGeom.cc:326
const double _presamplecut
const std::string resdir_
#define NCRYSEB
const int _fedid
int iChannelID[1700]
int towerId() const
get the tower id
const edm::ESGetToken< EcalElectronicsMapping, EcalMappingRcd > mappingToken_
edm::EDGetTokenT< EBDigiCollection > ebDigiToken_
const double _alpha
int channelId() const
so far for EndCap only :
void beginJob() override
int iTowerID[1700]
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
int nEvtTot[1700]
const unsigned int _timingquallow
const_iterator begin() const
EcalABAnalyzer(const edm::ParameterSet &iConfig)
edm::EDGetTokenT< EEDigiCollection > eeDigiToken_
const edm::EDGetTokenT< EcalRawDataCollection > rawDataToken_
TShapeAnalysis * shapana
unsigned int nevtAB[1700]
const_iterator end() const
static int side(EBGlobalCoord ieta, EBGlobalCoord iphi)
Definition: MEEBGeom.cc:105
bool isTimingQualOK()
Definition: TAPDPulse.cc:145
int stripId() const
get the tower id
const unsigned int _timingcutlow
std::map< int, int > channelMapEE
TAPDPulse * APDPulse
boost::transform_iterator< IterHelp, boost::counting_iterator< int > > const_iterator
bool isValid() const
Definition: HandleBase.h:70
void set_const(int, int, int, int, int, double, double)
void analyze(const edm::Event &e, const edm::EventSetup &c) override
int xtalId() const
get the channel id
void setPresamples(int)
Definition: TAPDPulse.cc:251
HLT enums.
bool isPulseOK()
Definition: TAPDPulse.cc:162
unsigned int _presample
void endJob() override
Definition: colors.py:1
void set_presample(int)
const double _beta
const std::string eventHeaderProducer_
bool wasTimingOK[1700]
const std::string eventHeaderCollection_
EcalLogicID towerID(EcalElectronicsId const &)
double getMean()
Definition: TMom.cc:121
const std::string digiProducer_
const double _ratiomaxcutlow
bool wasGainOK[1700]
Definition: event.py:1
const double _chi2cut
int nEvtBadTiming[1700]