CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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  };
181  delete test;
182 
183  TFile* fAB = nullptr;
184  TTree* ABInit = nullptr;
185  if (doesABTreeExist) {
186  fAB = new TFile(nameabinitfile.str().c_str());
187  }
188  if (doesABTreeExist && fAB) {
189  ABInit = (TTree*)fAB->Get("ABCol0");
190  }
191 
192  // 2) Shape analyzer
193 
194  if (doesABTreeExist && fAB && ABInit && ABInit->GetEntries() != 0) {
195  shapana = new TShapeAnalysis(ABInit, _alpha, _beta, 5.5, 1.0);
196  doesABTreeExist = true;
197  } else {
198  shapana = new TShapeAnalysis(_alpha, _beta, 5.5, 1.0);
199  doesABTreeExist = false;
200  _fitab = true;
201  }
203 
204  if (doesABTreeExist && fAB)
205  fAB->Close();
206 
207  if (_fitab) {
208  alphafile = nameabfile.str();
209  } else {
211  link << "ln -s " << resdir_ << "/ABInit.root " << resdir_ << "/AB.root";
212  system(link.str().c_str());
213  }
214 
215  // Define output results files' names
216 
217  std::stringstream namefile;
218  namefile << resdir_ << "/AB.root";
219  alphafile = namefile.str();
220 }
221 
222 //========================================================================
224  //========================================================================
225 
226  ++iEvent;
227 
228  // retrieving DCC header
230  const EcalRawDataCollection* DCCHeader = nullptr;
231  e.getByToken(rawDataToken_, pDCCHeader);
232  if (!pDCCHeader.isValid()) {
233  edm::LogError("nodata") << "Error! can't get the product retrieving DCC header" << eventHeaderCollection_.c_str()
234  << " " << eventHeaderProducer_.c_str();
235  } else {
236  DCCHeader = pDCCHeader.product();
237  }
238 
239  //retrieving crystal data from Event
241  const EBDigiCollection* EBDigi = nullptr;
243  const EEDigiCollection* EEDigi = nullptr;
244  if (_ecalPart == "EB") {
245  e.getByToken(ebDigiToken_, pEBDigi);
246  if (!pEBDigi.isValid()) {
247  edm::LogError("nodata") << "Error! can't get the product retrieving EB crystal data " << digiCollection_.c_str();
248  } else {
249  EBDigi = pEBDigi.product();
250  }
251  } else if (_ecalPart == "EE") {
252  e.getByToken(eeDigiToken_, pEEDigi);
253  if (!pEEDigi.isValid()) {
254  edm::LogError("nodata") << "Error! can't get the product retrieving EE crystal data " << digiCollection_.c_str();
255  } else {
256  EEDigi = pEEDigi.product();
257  }
258  } else {
259  edm::LogError("cfg_error") << " Wrong ecalPart in cfg file";
260  return;
261  }
262 
263  // retrieving electronics mapping
264  const auto& TheMapping = c.getData(mappingToken_);
265 
266  // =============================
267  // Decode DCCHeader Information
268  // =============================
269 
270  for (EcalRawDataCollection::const_iterator headerItr = DCCHeader->begin(); headerItr != DCCHeader->end();
271  ++headerItr) {
272  // Get run type and run number
273 
274  int fed = headerItr->fedId();
275  if (fed != _fedid && _fedid != -999)
276  continue;
277 
278  runType = headerItr->getRunType();
279  runNum = headerItr->getRunNumber();
280  event = headerItr->getLV1();
281 
282  dccID = headerItr->getDccInTCCCommand();
283  fedID = headerItr->fedId();
284  lightside = headerItr->getRtHalf();
285 
286  // Check fed corresponds to the DCC in TCC
287 
288  if (600 + dccID != fedID)
289  continue;
290 
291  // Cut on runType
292 
295  return;
296 
297  // Retrieve laser color and event number
298 
299  EcalDCCHeaderBlock::EcalDCCEventSettings settings = headerItr->getEventSettings();
300  color = settings.wavelength;
301  if (color < 0)
302  return;
303 
304  std::vector<int>::iterator iter = find(colors.begin(), colors.end(), color);
305  if (iter == colors.end()) {
306  colors.push_back(color);
307  }
308  }
309 
310  // Cut on fedID
311 
312  if (fedID != _fedid && _fedid != -999)
313  return;
314 
315  // ===========================
316  // Decode EBDigis Information
317  // ===========================
318 
319  int adcGain = 0;
320 
321  if (EBDigi) {
322  // Loop on crystals
323  //===================
324 
325  for (EBDigiCollection::const_iterator digiItr = EBDigi->begin(); digiItr != EBDigi->end();
326  ++digiItr) { // Loop on crystals
327 
328  // Retrieve geometry
329  //===================
330 
331  EBDetId id_crystal(digiItr->id());
332  EBDataFrame df(*digiItr);
333 
334  int etaG = id_crystal.ieta(); // global
335  int phiG = id_crystal.iphi(); // global
336 
337  int etaL; // local
338  int phiL; // local
339  std::pair<int, int> LocalCoord = MEEBGeom::localCoord(etaG, phiG);
340 
341  etaL = LocalCoord.first;
342  phiL = LocalCoord.second;
343 
344  eta = etaG;
345  phi = phiG;
346 
347  side = MEEBGeom::side(etaG, phiG);
348 
349  // Recover the TT id and the electronic crystal numbering from EcalElectronicsMapping
350 
351  EcalElectronicsId elecid_crystal = TheMapping.getElectronicsId(id_crystal);
352 
353  int towerID = elecid_crystal.towerId();
354  int strip = elecid_crystal.stripId();
355  int xtal = elecid_crystal.xtalId();
356  int channelID = 5 * (strip - 1) + xtal - 1;
357 
358  unsigned int channel = MEEBGeom::electronic_channel(etaL, phiL);
359 
360  assert(channel < nCrys);
361 
362  iEta[channel] = eta;
363  iPhi[channel] = phi;
364  iTowerID[channel] = towerID;
365  iChannelID[channel] = channelID;
366  idccID[channel] = dccID;
367  iside[channel] = side;
368 
369  // APD Pulse
370  //===========
371 
372  // Loop on adc samples
373 
374  for (unsigned int i = 0; i < (*digiItr).size(); ++i) {
375  EcalMGPASample samp_crystal(df.sample(i));
376  adc[i] = samp_crystal.adc();
377  adcG[i] = samp_crystal.gainId();
378  adc[i] *= adcG[i];
379  if (i == 0)
380  adcGain = adcG[i];
381  if (i > 0)
382  adcGain = TMath::Max(adcG[i], adcGain);
383  }
384 
386 
387  // Quality checks
388  //================
389 
390  if (adcGain != 1)
391  nEvtBadGain[channel]++;
392  if (!APDPulse->isTimingQualOK())
393  nEvtBadTiming[channel]++;
394  nEvtTot[channel]++;
395 
396  // Fill if Pulse is fine
397  //=======================
398 
399  if (APDPulse->isPulseOK() && lightside == side) {
402 
403  if (nevtAB[channel] < _nevtmax && _fitab) {
404  if (doesABTreeExist)
405  shapana->putAllVals(channel, adc, eta, phi);
406  else
407  shapana->putAllVals(channel, adc, eta, phi, dccID, side, towerID, channelID);
408  nevtAB[channel]++;
409  }
410  }
411  }
412 
413  } else if (EEDigi) {
414  // Loop on crystals
415  //===================
416 
417  for (EEDigiCollection::const_iterator digiItr = EEDigi->begin(); digiItr != EEDigi->end();
418  ++digiItr) { // Loop on crystals
419 
420  // Retrieve geometry
421  //===================
422 
423  EEDetId id_crystal(digiItr->id());
424  EEDataFrame df(*digiItr);
425 
426  phi = id_crystal.ix();
427  eta = id_crystal.iy();
428 
429  int iX = (phi - 1) / 5 + 1;
430  int iY = (eta - 1) / 5 + 1;
431 
432  side = MEEEGeom::side(iX, iY, iZ);
433  EcalElectronicsId elecid_crystal = TheMapping.getElectronicsId(id_crystal);
434 
435  int towerID = elecid_crystal.towerId();
436  int channelID = elecid_crystal.channelId() - 1;
437 
438  int hashedIndex = 100000 * eta + phi;
439 
440  if (channelMapEE.count(hashedIndex) == 0) {
443  }
444 
445  unsigned int channel = channelMapEE[hashedIndex];
446 
447  assert(channel < nCrys);
448 
449  iEta[channel] = eta;
450  iPhi[channel] = phi;
451  iTowerID[channel] = towerID;
452  iChannelID[channel] = channelID;
453  idccID[channel] = dccID;
454  iside[channel] = side;
455 
456  // APD Pulse
457  //===========
458 
459  if ((*digiItr).size() > 10)
460  edm::LogVerbatim("EcalABAnalyzer") << "SAMPLES SIZE > 10!" << (*digiItr).size();
461 
462  // Loop on adc samples
463 
464  for (unsigned int i = 0; i < (*digiItr).size(); ++i) {
465  EcalMGPASample samp_crystal(df.sample(i));
466  adc[i] = samp_crystal.adc();
467  adcG[i] = samp_crystal.gainId();
468  adc[i] *= adcG[i];
469 
470  if (i == 0)
471  adcGain = adcG[i];
472  if (i > 0)
473  adcGain = TMath::Max(adcG[i], adcGain);
474  }
475 
477 
478  // Quality checks
479  //================
480 
481  if (adcGain != 1)
482  nEvtBadGain[channel]++;
483  if (!APDPulse->isTimingQualOK())
484  nEvtBadTiming[channel]++;
485  nEvtTot[channel]++;
486 
487  // Fill if Pulse is fine
488  //=======================
489 
490  if (APDPulse->isPulseOK() && lightside == side) {
493 
494  if (nevtAB[channel] < _nevtmax && _fitab) {
495  if (doesABTreeExist)
496  shapana->putAllVals(channel, adc, eta, phi);
497  else
498  shapana->putAllVals(channel, adc, eta, phi, dccID, side, towerID, channelID);
499  nevtAB[channel]++;
500  }
501  }
502  }
503  }
504 } // analyze
505 
506 //========================================================================
508  //========================================================================
509 
510  edm::LogVerbatim("EcalABAnalyzer") << "\n\t+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+";
511  edm::LogVerbatim("EcalABAnalyzer") << "\t+=+ Analyzing data: getting (alpha, beta) +=+";
512 
513  // Adjust channel numbers for EE
514  //===============================
515 
516  if (_ecalPart == "EE") {
517  nCrys = channelMapEE.size();
519  }
520 
521  // Set presamples number
522  //======================
523 
524  double delta01 = Delta01->getMean();
525  double delta12 = Delta12->getMean();
526  if (delta12 > _presamplecut) {
527  _presample = 2;
528  if (delta01 > _presamplecut)
529  _presample = 1;
530  }
531 
534 
535  // Get alpha and beta
536  //======================
537 
538  if (_fitab) {
539  edm::LogVerbatim("EcalABAnalyzer") << "\n\t+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+";
540  edm::LogVerbatim("EcalABAnalyzer") << "\t+=+ Analyzing data: getting (alpha, beta) +=+";
541  TFile* fAB = nullptr;
542  TTree* ABInit = nullptr;
543  if (doesABTreeExist) {
544  fAB = new TFile(alphainitfile.c_str());
545  }
546  if (doesABTreeExist && fAB) {
547  ABInit = (TTree*)fAB->Get("ABCol0");
548  }
549  shapana->computeShape(alphafile, ABInit);
550 
551  // Set quality flags for gains and timing
552 
553  double BadGainEvtPercentage = 0.0;
554  double BadTimingEvtPercentage = 0.0;
555 
556  int nChanBadGain = 0;
557  int nChanBadTiming = 0;
558 
559  for (unsigned int i = 0; i < nCrys; i++) {
560  if (nEvtTot[i] != 0) {
561  BadGainEvtPercentage = double(nEvtBadGain[i]) / double(nEvtTot[i]);
562  BadTimingEvtPercentage = double(nEvtBadTiming[i]) / double(nEvtTot[i]);
563  }
564  if (BadGainEvtPercentage > _qualpercent) {
565  wasGainOK[i] = false;
566  nChanBadGain++;
567  }
568  if (BadTimingEvtPercentage > _qualpercent) {
569  wasTimingOK[i] = false;
570  nChanBadTiming++;
571  }
572  }
573 
574  double BadGainChanPercentage = double(nChanBadGain) / double(nCrys);
575  double BadTimingChanPercentage = double(nChanBadTiming) / double(nCrys);
576 
577  if (BadGainChanPercentage > _qualpercent)
578  isGainOK = false;
579  if (BadTimingChanPercentage > _qualpercent)
580  isTimingOK = false;
581 
582  if (!isGainOK)
583  edm::LogVerbatim("EcalABAnalyzer") << "\t+=+ ............................ WARNING! APD GAIN WAS NOT 1 +=+";
584  if (!isTimingOK)
585  edm::LogVerbatim("EcalABAnalyzer") << "\t+=+ ............................ WARNING! TIMING WAS BAD +=+";
586 
587  edm::LogVerbatim("EcalABAnalyzer") << "\t+=+ .................................... done +=+";
588  edm::LogVerbatim("EcalABAnalyzer") << "\t+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+";
589  }
590 }
591 
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
const edm::EventSetup & c
std::string alphainitfile
int xtalId() const
get the channel id
int idccID[1700]
const double _ratiomincuthigh
int stripId() const
get the tower id
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:539
double getDelta(int, int)
Definition: TAPDPulse.cc:116
const unsigned int _nevtmax
const std::string digiCollection_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
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
std::vector< T >::const_iterator const_iterator
const unsigned int _timingcuthigh
const double _ratiomincutlow
tuple runType
Definition: runPedHist.py:37
void computeShape(std::string namefile, TTree *)
int towerId() const
get the tower id
const unsigned int _firstsample
const_iterator begin() const
The iterator returned can not safely be used across threads.
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
std::vector< int > colors
const double _noise
const unsigned int _timingqualhigh
bool getData(T &iHolder) const
Definition: EventSetup.h:128
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]
const edm::ESGetToken< EcalElectronicsMapping, EcalMappingRcd > mappingToken_
edm::EDGetTokenT< EBDigiCollection > ebDigiToken_
const double _alpha
void beginJob() override
int iTowerID[1700]
int nEvtTot[1700]
const unsigned int _timingquallow
EcalABAnalyzer(const edm::ParameterSet &iConfig)
bool isValid() const
Definition: HandleBase.h:70
edm::EDGetTokenT< EEDigiCollection > eeDigiToken_
const edm::EDGetTokenT< EcalRawDataCollection > rawDataToken_
TShapeAnalysis * shapana
unsigned int nevtAB[1700]
const_iterator end() const
T Max(T a, T b)
Definition: MathUtil.h:44
static int side(EBGlobalCoord ieta, EBGlobalCoord iphi)
Definition: MEEBGeom.cc:105
bool isTimingQualOK()
Definition: TAPDPulse.cc:145
T const * product() const
Definition: Handle.h:70
const unsigned int _timingcutlow
std::map< int, int > channelMapEE
TAPDPulse * APDPulse
boost::transform_iterator< IterHelp, boost::counting_iterator< int > > const_iterator
void set_const(int, int, int, int, int, double, double)
const_iterator end() const
void analyze(const edm::Event &e, const edm::EventSetup &c) override
void setPresamples(int)
Definition: TAPDPulse.cc:251
bool isPulseOK()
Definition: TAPDPulse.cc:162
unsigned int _presample
void endJob() override
void set_presample(int)
const double _beta
const std::string eventHeaderProducer_
bool wasTimingOK[1700]
const std::string eventHeaderCollection_
EcalLogicID towerID(EcalElectronicsId const &)
ESGetTokenH3DDVariant esConsumes(std::string const &Reccord, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
double getMean()
Definition: TMom.cc:121
const std::string digiProducer_
int channelId() const
so far for EndCap only :
const double _ratiomaxcutlow
bool wasGainOK[1700]
const_iterator begin() const
const double _chi2cut
int nEvtBadTiming[1700]