ATLAS Offline Software
Loading...
Searching...
No Matches
LArCellsEmptyMonitoring.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// LArCellsEmptyMonitoring
6// -- Basic class aimed at running simple LAr monitoring function on ntuples
7// produced from that very same package.
8//
9// -- Author(s): Emma Kuwertz (KTH), Maud Schwoerer (LAPP), Olivier Simard (CEA-Saclay)
10//
11//
12//
13
14// Base includes
15
16// Package includes
18#include "LArSamplesMon/Data.h"
22#include "LArCafJobs/CellInfo.h"
25#include "LArCafJobs/CaloId.h"
26// ROOT includes
27#include "TObject.h"
28#include "TObjString.h"
29#include "TString.h"
30#include "TH1F.h"
31#include "TH2F.h"
32#include "TH2I.h"
33#include "TH3F.h"
34#include "TProfile.h"
35#include "TProfile2D.h"
36#include "TGraph.h"
37#include "TDirectory.h"
38#include "TFile.h"
39#include "TTree.h"
40#include "TCanvas.h"
41#include "TAxis.h"
42#include "TKey.h"
43
44#include <array>
45#include <map>
46#include <cstdio>//fopen, fprintf
47#include <fstream>
48#include <iostream>
49
50using namespace std;
51using namespace LArSamples;
52
53template <class T>
54using THVec=std::vector<std::unique_ptr<T>>;
55
56template <class T, std::size_t n>
57using THArray = std::array<std::unique_ptr<T>, n >;
58
59using TH1Fp = std::unique_ptr<TH1F>;
60using TH2Fp = std::unique_ptr<TH2F>;
61using TProfilep = std::unique_ptr<TProfile>;
62
64 : m_LarIdTranslator (std::make_unique<LArIdTranslatorHelper>("LarIdTree.root"))
65{
66 // class constructor - set your class variables to default values here
67
68 m_nexpected = 195072; // entries expected from Calo container
69
70
71 m_SaveRootFile = false;
72 m_SaveTextFile = true;
73 m_Algo = 2;
74 m_SetLumiblockRange = false;
75 m_input_lbmin = 0;
76 m_input_lbmax = 0;
77 m_RemoveBadLB = true;
78 m_Qthreshold = 4000;
79 m_nsigma = 4.;
80 m_Ethreshold = 1.;
86 m_nsigmaHits = 10.;
87 m_SaveRootTree = false;
88 m_SetPartition = false;
89}
90
94//____________________________________________________________________________________________________
95void LArCellsEmptyMonitoring::TestRun(const TString& inputfile)
96{
97
98 TString htitle,hname,textfilename,rootfilename;
99 //define cumulative energy cuts here (in GeV)
100 double Ecum_cut_PS = 20.;
101 double Ecum_cut_calo = 10.;
102
103 // define other constants and counters
104 const double GeV = 1/1000.;
105 int index = 0;
106 double nsigmaHits = 10.;
107 const int threshold = 1.;
108 const int qthreshold = m_Qthreshold;
109 int nskipped=0;
110 int nBadCells=0;
111 int noEvdata=0;
112 unsigned int onlid = 0;
113 int ne=0;
114 int emin=0;
115 int emax=0;
116 int nq=0;
117 int qmin=0;
118 int qmax=0;
119 int nlb=0;
120 int lbmin=0;
121 int lbmax=0;
122 int runNumber=0;
123 double MeanEventEnergy_max = -999;
124 double MeanEventEnergy_min = 999;
125
126 int CellCounter=0;
127
128
129 // Deal with bad LBs
130 // @ TODO: Do we still need this option? Not if we are always reading in the defect list at merging...?
131 vector<int, std::allocator<int> > DQLBList;
132 // placeholder
133 vector<int, std::allocator<int> > BadLBList;
134
135 // find minimum and maximum LB, cell energy, q factor...
136 printf("Getting histogram limits... ");
137 GetLimits_EqLB(inputfile,lbmin,lbmax,emin,emax,qmin,qmax,runNumber,BadLBList);
139 lbmin = m_input_lbmin;
140 lbmax = m_input_lbmax;
141 }
142 nlb=lbmax-lbmin;
143 ne=emax-emin;
144 nq=qmax-qmin;
145 printf("Done.\n LBmin: %d LBmax: %d Emin: %d Emax: %d Qmin: %d Qmax: %d\n",lbmin,lbmax,emin,emax,qmin,qmax);
146
147
148 // Declare and open output textfile
149 FILE * pFile=nullptr;
150 if (m_SaveTextFile){
151 if (!m_SetPartition){
152 textfilename.Form("Output/BadCellList_run%d.txt",runNumber);
153 pFile = fopen (textfilename , "w");
154 if (!pFile){
155 printf("Cannot open output text file\n");
156 std::abort();}
157 } else {
158 // placeholder - in case someone wants to look at individual partitions only!
159 if (m_SetPartition){
160 textfilename.Form("Output/BadCellList_%s_run%d.txt",m_LarIdTranslator->GetPartitonLayerName(m_PartitionIndex),runNumber);
161 pFile = fopen (textfilename , "w");
162 if (!pFile){
163 printf("Cannot open output text file\n");
164 std::abort();}
165 }
166 }
167 }
168 // Open output text file to write column titles
169 if (m_SaveTextFile){
170 fprintf(pFile, "onlid // part // FT // SL // CH // # Events E>%d sigma // Mean Event Energy [GeV] (min // max) // # LBs // # LBs affected // fraction events Q>%d \n",(int)nsigmaHits,qthreshold);
171 }
172
173 int EventCount=0., qcount=0.;
174
175 // Declare root file (LAr investigations - not intended to be produced by default)
176 if (m_SetPartition){
177 rootfilename.Form("Output/BadCells_%s_run%d.root",m_LarIdTranslator->GetPartitonLayerName(m_PartitionIndex),runNumber);
178 } else {
179 rootfilename.Form("Output/BadCells_run%d.root",runNumber);
180 }
181
182 auto fout = std::make_unique<TFile>(rootfilename,"RECREATE");
183 Float_t noise = 0;
184 Float_t fr_q4k = 0;
185 TH1Fp h1_lb;
186 TH1Fp h1_elb;
187 TH1Fp h1_qlb;
188 TH1Fp h1_e;
189 TH1Fp h1_q;
190 TH2Fp h2_elb;
191
192
193 // -------------------------------------------------------------------------
194 // create individual cell histos
195 // -------------------------------------------------------------------------
196 printf("Creating histograms (nEbins = %d, nQbins = %d, nLBbins = %d)... ",ne,nq,nlb);
197 TH1F hene = TH1F("hEne","",ne,emin,emax); hene.SetXTitle("Energy [GeV]"); hene.SetYTitle("Events");
198 TH1F hqua = TH1F("hQua","",nq/100.,qmin,qmax); hqua.SetXTitle("Quality"); hqua.SetYTitle("Events");
199 TH1F hlb = TH1F("hLB","",nlb,lbmin,lbmax); hlb.SetXTitle("LB"); hlb.SetYTitle("Events");
200 TH2F henelb = TH2F("hEnelb","",nlb,lbmin,lbmax,ne,emin,emax); henelb.SetXTitle("LB"); henelb.SetYTitle("Energy [GeV]");
201 // -------------------------------------------------------------------------
202 printf("Done.\n");
203
204 // -------------------------------------------------------------------------
205 // New test histos:
206 // -------------------------------------------------------------------------
207 printf("Creating cut test histograms...");
208 static constexpr int npl=4;
209 TH2F tempHist = TH2F("tempNEvLB","",1000,0,1000.,1000,0.,1000.);
210 //THArray, defined at file scope, holds unique_ptr
211 THArray<TH1F, npl> hNoise{};
212 THArray<TH1F, npl> hCellsPerLB{};
213 THArray<TH2F, npl> hNEvVsEMean{};
214 THArray<TH2F, npl> hNEvVsECum{};
215 THArray<TH2F, npl> hECumVsEMean{};
216
217 for (int i=0;i<npl;i++){
218 hname.Form("hNEvVsEMean_Layer%i",i);
219 hNEvVsEMean[i].reset((TH2F*)tempHist.Clone(hname));
220 hNEvVsEMean[i]->GetXaxis()->SetTitle("Number of Events (E > 10 #sigma) / LB");
221 hNEvVsEMean[i]->GetYaxis()->SetTitle("E_{mean} per Event / LB [GeV]");
222
223 hname.Form("hNEvVsECum_Layer%i",i);
224 hNEvVsECum[i].reset((TH2F*)tempHist.Clone(hname));
225 hNEvVsECum[i]->GetXaxis()->SetTitle("Number of Events (E > 10 #sigma) / LB");
226 hNEvVsECum[i]->GetYaxis()->SetTitle("E_{cumulative} per Cell / LB [GeV]");
227
228 hname.Form("hECumVsEMean_Layer%i",i);
229 hECumVsEMean[i].reset((TH2F*)tempHist.Clone(hname));
230 hECumVsEMean[i]->GetXaxis()->SetTitle("E_{cumulative} per Cell / LB [GeV]");
231 hECumVsEMean[i]->GetYaxis()->SetTitle("E_{mean} per Event / LB [GeV]");
232
233 hname.Form("hNoise_Layer%i",i);
234 hNoise[i].reset(new TH1F(hname,"",60,0.,30.));
235 hNoise[i]->GetXaxis()->SetTitle("Noise [GeV]");
236 hNoise[i]->GetYaxis()->SetTitle("Number Of Cells");
237
238 hname.Form("hCellsPerLB_Layer%i",i);
239 hCellsPerLB[i].reset((TH1F*)hlb.Clone(hname));
240 hCellsPerLB[i]->GetXaxis()->SetTitle("LB");
241 hNoise[i]->GetYaxis()->SetTitle("Number Of Cells");
242 }
243 printf("Done\n");
244 // -------------------------------------------------------------------------
245
246
247 // Opening file:
248 std::unique_ptr<LArSamples::Interface> tuple ((LArSamples::Interface*)Interface::open(inputfile));
249 printf("Number of events: %u %u\n",tuple->nEvents(),tuple->nChannels());
250 unsigned int nchannels = tuple->nChannels();
251
252 printf("Begin looping over cells...\n");
253 for(unsigned int ichan = 0; ichan < nchannels; ichan++){
254
255 // pass empty cells
256 if(tuple->historySize(ichan)==0){ nskipped++; continue; }
257
258 // process non empty cells
259 const LArSamples::History* hist = tuple->cellHistory(ichan);
260 const LArSamples::CellInfo* cellInfo = hist->cellInfo();
261
262 // index for partition
263 index = m_LarIdTranslator->GetPartitionLayerIndex(cellInfo->calo(),cellInfo->layer());
264 onlid = cellInfo->onlid();
265
266 // if cell contains less hits than the threshold requirement, skip it
267 unsigned int ndigits = hist->nData();
268 if(ndigits<(unsigned int)threshold){ nskipped++; continue; }
269
271 // set individual cell histos
272 hname.Form("h0x%x_Energy",onlid);
273 h1_e.reset((TH1F*)hene.Clone(hname));
274 hname.Form("h0x%x_Quality",onlid);
275 h1_q.reset((TH1F*)hqua.Clone(hname));
276 hname.Form("h0x%x_LB",onlid);
277 h1_lb.reset((TH1F*)hlb.Clone(hname));
278 hname.Form("h0x%x_hNEvVsEMean",onlid);
279 h1_elb.reset((TH1F*)hlb.Clone(hname));
280 hname.Form("h0x%x_Energy_LB",onlid);
281 h2_elb.reset((TH2F*)henelb.Clone(hname));
282 hname.Form("h0x%x_Quality_LB",onlid);
283 h1_qlb.reset((TH1F*)hlb.Clone(hname));
284 }
285
286 // loop on the events for each cell
287 for(unsigned int idigit = 0; idigit < ndigits; idigit++){
288 const LArSamples::Data* data = hist->data(idigit);
289 double noise = data->noise()*GeV;
290 const LArSamples::EventData* Evdata = data->eventData();
291 if(!Evdata){ noEvdata++; continue; }// avoid crash
292 int lumiBlock = Evdata->lumiBlock();
293 double energy = data->energy()*GeV;
294
295 if (energy > nsigmaHits*noise){ // E>10sigma
296
297 // Fill individual cell histos
299 h1_e->Fill(energy);
300 h1_q->Fill(data->quality());
301 h1_lb->Fill(lumiBlock);
302 h1_elb->Fill(lumiBlock, energy);
303 h2_elb->Fill(lumiBlock, energy);
304 h1_qlb->Fill(lumiBlock, data->quality());
305 }
306
307 // count the number of processed events per cell with a bad q-factor
308 if (data->quality() > qthreshold){
309 qcount = qcount+1;
310 }
311
312 // count the number of events processed per cell
313 EventCount++;
314
315 } // end of E>10sigma
316
317 } // end of event loop
319 hNoise[cellInfo->layer()]->Fill(noise);
320 }
321 CellCounter++;
322 if ( CellCounter%1000 == 0 ) {
323 printf("Scanning Cell No. = %d\n",CellCounter);
324 }
325 MeanEventEnergy_max = -999;
326 MeanEventEnergy_min = 999;
327 bool FlagCell=false;
328 int FlagCount=0;
329 int NFullLB = 0;
330
332 for (int ilb=1;ilb<=nlb;ilb++){
333 if (h1_lb->GetBinContent(ilb) > 0.){
334 double EtotInLB = h1_elb->GetBinContent(ilb);
335 double NEventsInLB = h1_lb->GetBinContent(ilb);
336 //double MeanQ = h1_qlb->GetBinContent(ilb) / NEventsInLB; // change to fraction..
337 int LB_number = h1_lb->GetBinLowEdge(ilb);
338 NFullLB += 1;
339 double MeanEventEnergy = EtotInLB / NEventsInLB;
340
341
342 if (cellInfo->layer()==0){
343 if (EtotInLB>Ecum_cut_PS){
344 hNEvVsEMean[cellInfo->layer()]->Fill(NEventsInLB,MeanEventEnergy);
345 hNEvVsECum[cellInfo->layer()]->Fill(NEventsInLB,EtotInLB);
346 hECumVsEMean[cellInfo->layer()]->Fill(EtotInLB,MeanEventEnergy);
347 hCellsPerLB[cellInfo->layer()]->Fill(LB_number);
348 }
349 }
350 else if (EtotInLB>Ecum_cut_calo){
351 hNEvVsEMean[cellInfo->layer()]->Fill(NEventsInLB,MeanEventEnergy);
352 hNEvVsECum[cellInfo->layer()]->Fill(NEventsInLB,EtotInLB);
353 hECumVsEMean[cellInfo->layer()]->Fill(EtotInLB,MeanEventEnergy);
354 hCellsPerLB[cellInfo->layer()]->Fill(LB_number);
355 }
356
357 if (EtotInLB>Ecum_cut_PS && cellInfo->layer()==0){
358 FlagCell=true; FlagCount++;
359 if (MeanEventEnergy_max<MeanEventEnergy){ MeanEventEnergy_max = MeanEventEnergy; }
360 if (MeanEventEnergy_min>MeanEventEnergy){ MeanEventEnergy_min = MeanEventEnergy; }
361 }
362 else if (EtotInLB>Ecum_cut_calo && cellInfo->layer()==1){
363 FlagCell=true; FlagCount++;
364 if (MeanEventEnergy_max<MeanEventEnergy){ MeanEventEnergy_max = MeanEventEnergy; }
365 if (MeanEventEnergy_min>MeanEventEnergy){ MeanEventEnergy_min = MeanEventEnergy; }
366 }
367 else if (EtotInLB>Ecum_cut_calo && cellInfo->layer()==2){
368 FlagCell=true; FlagCount++;
369 if (MeanEventEnergy_max<MeanEventEnergy){ MeanEventEnergy_max = MeanEventEnergy; }
370 if (MeanEventEnergy_min>MeanEventEnergy){ MeanEventEnergy_min = MeanEventEnergy; }
371 }
372 else if (EtotInLB>Ecum_cut_calo && cellInfo->layer()==3){
373 FlagCell=true; FlagCount++;
374 if (MeanEventEnergy_max<MeanEventEnergy){ MeanEventEnergy_max = MeanEventEnergy; }
375 if (MeanEventEnergy_min>MeanEventEnergy){ MeanEventEnergy_min = MeanEventEnergy; }
376 }
377 }
378 }
379 if (EventCount!=0){
380 fr_q4k = (double)qcount/(double)EventCount;
381 }
382 }
383 // Write bad channel quantities to text file
384 if (m_SaveTextFile){
385 if (FlagCell){
386 nBadCells++;
387 fprintf(pFile, "0x%x \t %7s \t %d \t %d \t %d \t %d \t %4.3f \t %4.3f \t %d \t %d \t %4.3f \n",onlid,m_LarIdTranslator->GetPartitonLayerName(index),cellInfo->feedThrough(),cellInfo->slot(),cellInfo->channel(),EventCount,MeanEventEnergy_min,MeanEventEnergy_max,NFullLB,FlagCount,fr_q4k);
388
389 }
390 }
391
392 qcount = 0.;
393 EventCount = 0.;
394 } // end of cell loop
395
396 int nbad = m_nexpected-nskipped;
397 printf("Skipped %d cells. Cells scanned = %d\n",nskipped,nbad);
398 printf("Cells put in Bad Cell List = %d\n",nBadCells);
399 if (noEvdata>0) printf("No Evdata pointer: %d\n",noEvdata);
400
401 // Write test histos to output rootfile
402 if(m_SaveRootFile){
403 fout->cd();
404 for(int i=0;i<npl;i++){
405 hNEvVsEMean[i]->Write();
406 hNEvVsECum[i]->Write();
407 hECumVsEMean[i]->Write();
408 hNoise[i]->Write();
409 hCellsPerLB[i]->Write();
410 }
411 }
412
413 fout->Close();
414 fclose(pFile);
415 return;
416
417}
418
419
420
421//____________________________________________________________________________________________________
422void LArCellsEmptyMonitoring::Run(const TString& inputfile)
423{
424
425 TString htitle,hname,textfilename,rootfilename;
426
427 // partition/layer indexing entrirely defined by LarIdTranslator
428 const int npl = m_LarIdTranslator->GetNpl();
429
430
431 // ----------------------------------------------------
432 // Setter error messages
433 // ----------------------------------------------------
434
435
437 printf("WARNING: Received instruction to select recurring bad cells only in SetSelectRecurringBadCells(bool flag)\n");
438 printf("-------> Only one algorithm selected for cell selection criteria in SetAlgo(int algoindex)\n");
439 printf("-------> Recurring cell selection overides algorithm specification\n");
440 std::abort();
441 }
442
443 if (m_SetPartition && m_PartitionIndex == -1){
444 printf("ERROR: Partition not specified in SetPartition(bool set_part, std::string partname)\n");
445 std::abort();
446 } else if (m_SetPartition){
447 printf("Running cell selection on %s only.\n",m_LarIdTranslator->GetPartitonLayerName(m_PartitionIndex));
448 }
449 // ----------------------------------------------------
450 //
451 int selectionFlag = -1;
452 const double GeV = 1/1000.;
453 const double ecut = m_Ethreshold; // GeV
454 int index = 0;
455 double nsigma = m_nsigma;
456 double nsigmaHits = m_nsigmaHits;
457 const int threshold = 10.;
458 const int qthreshold = m_Qthreshold;
459 int nskipped=0;
460 int nBadCells=0;
461 int noEvdata=0;
462 unsigned int onlid = 0;
463 int ne=0;
464 int emin=0;
465 int emax=0;
466 int nq=0;
467 int qmin=0;
468 int qmax=0;
469 int nlb=0;
470 int nlb_corr=0; // count only non-empty LBs
471 int lbmin=0;
472 int lbmax=0;
473 int runNumber=0;
474 int nEvents_E_gt_ecut=0;
475 double EventEnergySum=0.;
476 double EventEnergyMean=0.;
477
478 int nBadLBs=0;
479 double MeanHits=0, rmsHits=0;
480 int iMeanCellHitsSelection=0,iEnergyThresholdSelection=0,iOR_selection=0,iAND_selection=0;
481 int CellCounter=0;
482
483
484 // Deal with bad LBs
485 // @ TODO: Do we still need this option? Not if we are always reading in the defect list at merging...?
486 vector<int, std::allocator<int> > DQLBList;
487 vector<int, std::allocator<int> > BadLBList;
489 printf("Reading in DQ Defect LB List...\n");
490 DQLBList=ReadBadLBList(m_LBfile);
491 printf("...Done\n");
492 }
493 if (m_RemoveBadLB){
494 printf("Getting bad LB list...\n");
495 BadLBList=GetBadLBList(inputfile,lbmin,lbmax,nsigma,nlb,DQLBList);
496 printf("...Done.\n");
497 nBadLBs = BadLBList.size();
498 }
499 else if (m_ReadDefectLBList){
500 BadLBList = std::move(DQLBList);
501 nBadLBs = BadLBList.size();
502 }
503
504 // find minimum and maximum LB, cell energy, q factor...
505 printf("Getting histogram limits... ");
506 GetLimits_EqLB(inputfile,lbmin,lbmax,emin,emax,qmin,qmax,runNumber,BadLBList);
508 lbmin = m_input_lbmin;
509 lbmax = m_input_lbmax;
510 }
511
512
513 nlb=lbmax-lbmin;
514 ne=emax-emin;
515 nq=qmax-qmin;
516 printf("Done.\n LBmin: %d LBmax: %d Emin: %d Emax: %d Qmin: %d Qmax: %d\n",lbmin,lbmax,emin,emax,qmin,qmax);
517
518 // Declare and open summary textfile
519 FILE * outputFile=nullptr;
520 if (!m_SetPartition){
521 textfilename.Form("Output/BadCellSelection_run%d.txt",runNumber);
522 outputFile = fopen (textfilename , "w");
523 if (!outputFile){
524 std::cout<<("Cannot open output selection summary file " + textfilename)<< "\n";
525 std::abort();}
526 } else {
527 textfilename.Form("BadCellSelection_%s_run%d.txt",m_LarIdTranslator->GetPartitonLayerName(m_PartitionIndex),runNumber);
528 outputFile = fopen (textfilename , "w");
529 if (!outputFile){
530 std::cout<<("Cannot open output selection summary file " + textfilename)<< "\n";
531 std::abort();}
532 }
533
534
535 // Declare and open output textfile
536 FILE * pFile=nullptr;
537 if (m_SaveTextFile){
538 if (!m_SetPartition){
539 textfilename.Form("Output/BadCellList_run%d.txt",runNumber);
540 pFile = fopen (textfilename , "w");
541 if (!pFile){
542 printf("Cannot open output text file\n");
543 std::abort();}
544 } else {
545 if (m_SetPartition){
546 textfilename.Form("BadCellList_%s_run%d.txt",m_LarIdTranslator->GetPartitonLayerName(m_PartitionIndex),runNumber);
547 pFile = fopen (textfilename , "w");
548 if (!pFile){
549 printf("Cannot open output text file\n");
550 std::abort();}
551 }
552 }
553 }
554
555
556
557
558printf("Determining mean cell hits...\n ");
559 GetMeanCellHits(inputfile, nlb, lbmin, lbmax, nsigmaHits, BadLBList, MeanHits, rmsHits, nlb_corr);
560printf("Done.\n");
561printf("Set threshold at %4.3f counts per cell for LB range. \n",(MeanHits+(nsigmaHits*rmsHits))*((double)nlb_corr-(double)nBadLBs));
562
563
564 if (m_SaveTextFile){
565 fprintf(pFile, "onlid // part // FT // SL // CH // Events (E>%d sigma) // Events E>1GeV // Mean Energy [GeV] // # LBs // fraction events Q>%d // Flagged in LB // selectionFlag\n",(int)nsigmaHits,qthreshold);
566 }
567
568 int EventCount=0., qcount=0.;
569 // ----------------------------------------------------
570 // Prepare output tree listing bad channels
571 // ----------------------------------------------------
572 if (m_SetPartition){
573 rootfilename.Form("Output/BadCells_%s_run%d.root",m_LarIdTranslator->GetPartitonLayerName(m_PartitionIndex),runNumber);
574 } else {
575 rootfilename.Form("Output/BadCells_run%d.root",runNumber);
576 }
577
578 auto fout = std::make_unique<TFile>(rootfilename,"RECREATE");
579 Int_t larid = 0;
580 Int_t t_run =0;
581 Int_t n_ensig = 0;
582 Int_t n_ecut = 0;
583 Float_t fr_LB = 0;
584 Float_t nbrLB = 0;
585 Float_t noise = 0;
586 Float_t meanECell = 0;
587 Float_t fr_q4k = 0;
588 TH1F* h1_lb = nullptr;
589 TH1F* h1_e = nullptr;
590 TH1F* h1_q = nullptr;
591 TH2F* h2_elb = nullptr;
592 TH2D* h2_pulse = nullptr;
593 TH2D* h2_t_LB = nullptr;
594 TProfile* TProf_pulse = nullptr;
595 TH1F* h1_ADCmax = nullptr;
596 std::unique_ptr<TTree> tree_cells;
597 if(m_SaveRootFile){
598 tree_cells.reset(new TTree("BadTree","LAr Tree ordered by OnlID"));
599 tree_cells->Branch("Energy",&h1_e);
600 tree_cells->Branch("Quality",&h1_q);
601 tree_cells->Branch("LB",&h1_lb);
602 tree_cells->Branch("larid",&larid);
603 tree_cells->Branch("onlid",&onlid);
604 tree_cells->Branch("Run",&t_run);
605 tree_cells->Branch("selectionFlag",&selectionFlag);
606 tree_cells->Branch("nhits_ensig",&n_ensig);
607 tree_cells->Branch("nhits_e1GeV",&n_ecut);
608 tree_cells->Branch("Quality_4k",&fr_q4k);
609 tree_cells->Branch("LBfraction",&fr_LB);
610 tree_cells->Branch("EnergyVsLB",&h2_elb);
611 tree_cells->Branch("PulseShape",&h2_pulse);
612 tree_cells->Branch("PulsePeakTimeVsLB",&h2_t_LB);
613 tree_cells->Branch("noise",&noise);
614 tree_cells->Branch("MeanCellEnergy",&meanECell);
615 tree_cells->Branch("PulseShapeTProf",&TProf_pulse);
616 tree_cells->Branch("ADCmax",&h1_ADCmax);
617 }
618
619 Double_t xmin=-4.9,xmax=4.9;
620 Double_t xw=0.1;
621 TH2D NormPulse("Normalised_pulse","",100,-200,200,400,-10,10);
622 NormPulse.SetXTitle("Time [ns]");
623 NormPulse.SetYTitle("Value [ADC counts] / ADCmax");
624 //
625 //THVec, defined at file scope, holds unique_ptr, defined a filescope
626 THVec<TH2D> Pulsemaps(npl);
627 THVec<TH2> Cellmaps(npl);
628 THVec<TH2F> E_LBmaps(npl);
629 THVec<TH2D> t_LBmaps(npl);
630 THVec<TH1F> CellsFlagged_LB_part(npl);
631 THVec<TH1F> Emean_NbrEvents_part(npl);
632 //
633 TH2F E_LB("E_LB","",nlb,lbmin,lbmax,ne,emin,emax);
634 E_LB.SetXTitle("LB");
635 E_LB.SetYTitle("Energy [GeV]");
636 //
637 TH2D t_LB("t_LB","",nlb,lbmin,lbmax,400,-200,200);
638 t_LB.GetXaxis()->SetTitle("LB");
639 t_LB.GetYaxis()->SetTitle("Time(maxSample) + ofcTime [ns]");
640 //
641 TH1F CF_LB("CF_LB","",nlb,lbmin,lbmax);
642 CF_LB.GetXaxis()->SetTitle("LB");
643 CF_LB.GetYaxis()->SetTitle("Number of cells flagged");
644 //
645 TH1F ME_EV("ME_EV","",1000,0,1000);
646 ME_EV.GetXaxis()->SetTitle("Nbr events >1 GeV");
647 ME_EV.GetYaxis()->SetTitle("Mean Energy [GeV]");
648
649
650
651 if(m_SaveRootFile){
652 for (int ii=0;ii<npl;ii++){
653 Cellmaps[ii].reset(m_LarIdTranslator->GetCaloPartitionLayerMap(ii));
654 Cellmaps[ii]->GetXaxis()->SetTitle("#eta"); Cellmaps[ii]->GetYaxis()->SetTitle("#Phi");
655 hname.Form("%s_PulseShape_%dsigma",m_LarIdTranslator->GetPartitonLayerName(ii),(int)nsigmaHits);
656 Pulsemaps[ii].reset((TH2D*)NormPulse.Clone(hname));
657 hname.Form("%s_EvergyVsLB",m_LarIdTranslator->GetPartitonLayerName(ii));
658 E_LBmaps[ii].reset((TH2F*)E_LB.Clone(hname));
659 hname.Form("%s_PulseTimeVsLB",m_LarIdTranslator->GetPartitonLayerName(ii));
660 t_LBmaps[ii].reset((TH2D*)t_LB.Clone(hname));
661 hname.Form("%s_CellsFlaggedVsLB",m_LarIdTranslator->GetPartitonLayerName(ii));
662 CellsFlagged_LB_part[ii].reset((TH1F*)CF_LB.Clone(hname));
663 // en plus
664 hname.Form("%s_EmeanVsNbrEvents",m_LarIdTranslator->GetPartitonLayerName(ii));
665 Emean_NbrEvents_part[ii].reset((TH1F*)ME_EV.Clone(hname));
666 //
667 }
668 }
669 TH2F Eeta("Eeta","",(int)floor((xmax-xmin)/xw),xmin,xmax,ne,emin,emax);
670 Eeta.GetXaxis()->SetTitle("#eta");
671 Eeta.GetYaxis()->SetTitle("Energy [GeV]");
672 //
673 TH1F CellEnergy("CellEnergy","",ne,emin,emax);
674 CellEnergy.GetXaxis()->SetTitle("Cell Mean Energy [GeV]");
675 CellEnergy.GetYaxis()->SetTitle("Cells");
676 //
677 TH1F LBfrac("LBfrac","",100,0.,1.);
678 LBfrac.GetXaxis()->SetTitle("LB fraction");
679 LBfrac.GetYaxis()->SetTitle("Cells");
680 //
681 TH1F Qfrac("Qfrac","",100.,0.,1.);
682 Qfrac.GetXaxis()->SetTitle("Fraction of Events Q>4000");
683 Qfrac.GetYaxis()->SetTitle("Cells");
684 //
685 TH1F CellsFlagged_LB("CellsFlagged_LB","",nlb,lbmin,lbmax);
686 CellsFlagged_LB.GetXaxis()->SetTitle("LB");
687 CellsFlagged_LB.GetYaxis()->SetTitle("Number of cells flagged");
688 //
689 TH1F Emean_NbrEvents("Emean_NEvents_1GeV","",1000,0,1000);
690 Emean_NbrEvents.GetXaxis()->SetTitle("N events > 1 GeV");
691 Emean_NbrEvents.GetYaxis()->SetTitle("Mean Energy [GeV]");
692 //
693 // -------------------------------------------------------------------------
694 // create individual cell histos
695 // -------------------------------------------------------------------------
696 printf("Creating histograms (nEbins = %d, nQbins = %d, nLBbins = %d)... ",ne,nq,nlb);
697 TH1F hene = TH1F("hEne","",ne,emin,emax); hene.SetXTitle("Energy [GeV]");
698 hene.SetYTitle("Events");
699 TH1F hqua = TH1F("hQua","",nq/100.,qmin,qmax); hqua.SetXTitle("Quality");
700 hqua.SetYTitle("Events");
701 TH1F hlb = TH1F("hLB","",nlb,lbmin,lbmax); hlb.SetXTitle("LB");
702 hlb.SetYTitle("Events");
703 TH2F henelb = TH2F("hEnelb","",nlb,lbmin,lbmax,ne,emin,emax); henelb.SetXTitle("LB");
704 henelb.SetYTitle("Energy [GeV]");
705 TH2D hpulse = TH2D("hPulse","",100,-200,200,400, -10,10); hpulse.SetXTitle("Time [ns]");
706 hpulse.SetYTitle("Value [ADC counts] / ADCmax");
707 TProfile TProfpulse = TProfile("", "",5, 0, 5, "s"); TProfpulse.SetXTitle("Sample Number");
708 TProfpulse.SetYTitle("Value [ADC counts]");
709 TH2D ht_LB= TH2D("ht_LB","",nlb,lbmin,lbmax,400,-200,200); ht_LB.GetXaxis()->SetTitle("LB");
710 ht_LB.GetYaxis()->SetTitle("Time(maxSample) + ofcTime [ns]");
711 TH1F hADCmax = TH1F("","",110,-200,2000); hADCmax.SetXTitle("ADCmax [ADC counts]"); hADCmax.SetYTitle("Events");
712 // -------------------------------------------------------------------------
713 printf("Done.\n");
714
715 // Opening file:
717 printf("Number of events: %u %u\n",tuple->nEvents(),tuple->nChannels()); //tuple->ShowEvents("energy>0.");
718 unsigned int nchannels = tuple->nChannels();
719
720 fprintf(outputFile,"Onlid \t MeanCellHitBased \t EnergyThresholdBased \t OR \t AND\n");
721 // -------------------------------------------------------------------------
722
723 printf("Begin looping over cells...\n");
724 for(unsigned int ichan = 0; ichan < nchannels; ichan++){
725 // pass empty cells
726 if(tuple->historySize(ichan)==0){ nskipped++; continue; }
727
728
729 // process non empty cells
730 const LArSamples::History* hist = tuple->cellHistory(ichan);
731 const LArSamples::CellInfo* cellInfo = hist->cellInfo();
732 double eta = cellInfo->eta();
733 double phi = cellInfo->phi();
734
735
736 // index for partition
737 index = m_LarIdTranslator->GetPartitionLayerIndex(cellInfo->calo(),cellInfo->layer());
738 onlid = cellInfo->onlid();
739
740 // if only checking a specific partition, skip any cells not associated with that partition
741 if(m_SetPartition){
742 if (!CheckPartition(index)){ nskipped++; continue; }
743 }
744
745 // if cell contains less hits that the threshold requirement, skip it
746 unsigned int ndigits = hist->nData();
747 if(ndigits<(unsigned int)threshold){ nskipped++; continue; }
748
749
750 // initialise individual cell histograms
752 // set individual cell histos
753 hname.Form("h0x%x_Energy",onlid);
754 h1_e = (TH1F*)hene.Clone(hname);
755 hname.Form("h0x%x_Quality",onlid);
756 h1_q = (TH1F*)hqua.Clone(hname);
757 hname.Form("h0x%x_LB",onlid);
758 h1_lb = (TH1F*)hlb.Clone(hname);
759 hname.Form("h0x%x_Energy_LB",onlid);
760 h2_elb = (TH2F*)henelb.Clone(hname);
761 hname.Form("h0x%x_Pulse",onlid);
762 h2_pulse = (TH2D*)hpulse.Clone(hname);
763 hname.Form("TProf0x%x_Pulse",onlid);
764 TProf_pulse = (TProfile*)TProfpulse.Clone(hname);
765 hname.Form("h0x%x_ADCmax",onlid);
766 h1_ADCmax = (TH1F*)hADCmax.Clone(hname);
767 hname.Form("h0x%x_t_LB",onlid);
768 h2_t_LB = (TH2D*)ht_LB.Clone(hname);
769 }
770
771 bool CellInList = false;
772 int LBFlaggedIn = -1;
773
774// loop on the events for each cell
775 for(unsigned int idigit = 0; idigit < ndigits; idigit++){
776 const LArSamples::Data* data = hist->data(idigit);
777 noise = data->noise()*GeV;
778 const LArSamples::EventData* Evdata = data->eventData();
779 if(!Evdata){ noEvdata++; continue; }// avoid crash
780 int lumiBlock = Evdata->lumiBlock();
781 double energy = data->energy()*GeV;
782
783 // checks whether or not an event is in a bad LB when the bad LB list is read in manually
784 // @ TODO: Do we still need this functionality? Aren't we always going to read in the list at the merging stage now?
785 bool isBadLB = CheckBadLBList(lumiBlock,BadLBList);
786
787 // skip bad LBs
788 if (isBadLB) continue;
789
790 // check the event satisfies selection criteria
791 bool ProcessEvent = CheckEventSelectionCriteria(lumiBlock, nsigmaHits, energy, noise, lbmin, lbmax);
792 if (ProcessEvent){
793
795 h1_e->Fill(data->energy()*GeV);
796 h1_q->Fill(data->quality());
797 h1_lb->Fill(lumiBlock);
798 h2_elb->Fill(lumiBlock, data->energy()*GeV);
799 h1_ADCmax->Fill(data->adcMax());
800 double time = data->maxPosition()*25.0+data->ofcTime();
801 h2_t_LB->Fill(lumiBlock,time);
802 for(unsigned int isample=0;isample<data->nSamples();isample++) {
803 TProf_pulse->Fill(isample, data->value(isample));
804 h2_pulse->Fill(data->time(isample)-time, data->value(isample)/data->adcMax());
805 }
806 }
807
808 // count the number of processed events per cell with a bad q-factor
809 if (data->quality() > qthreshold){
810 qcount = qcount+1;
811 }
812
813 // count the number of events processed per cell
814 EventCount++;
815
816 // count number of processed events with energy > ecut and calculate cumulative energy
817 if (data->energy()*GeV > ecut) {
818 nEvents_E_gt_ecut++;
819 EventEnergySum+=(data->energy()*GeV);
820 }
821
822 // if the cell isn't already in the list check whether or not it should be
823 if(!CellInList){
824 selectionFlag=CheckCellSelectionCriteria(EventCount,nsigmaHits,MeanHits,rmsHits,nEvents_E_gt_ecut,EventEnergySum,nBadLBs,nlb_corr);
825 if(selectionFlag==2){
826 LBFlaggedIn = lumiBlock;
827 CellInList = true;
828 }
829 else if(selectionFlag==1){
830 if(m_Algo==2){
831 LBFlaggedIn = lumiBlock;
832 CellInList = true;
833 }
834 else if(m_Algo==0){
835 LBFlaggedIn = lumiBlock;
836 CellInList = true;
837 }
838 }
839 else if(selectionFlag==0){
840 if(m_Algo==2){
841 LBFlaggedIn = lumiBlock;
842 CellInList = true;
843 }
844 else if(m_Algo==1){
845 LBFlaggedIn = lumiBlock;
846 CellInList = true;
847 }
848 }
849 }
850
851 }
852
853 } // end of event loop
854
855 CellCounter++;
856 if ( CellCounter%1000 == 0 ) {
857 printf("Scanning Cell No. = %d\n",CellCounter);
858 }
859 selectionFlag=CheckCellSelectionCriteria(EventCount,nsigmaHits,MeanHits,rmsHits,nEvents_E_gt_ecut,EventEnergySum,nBadLBs,nlb_corr);
860
861 // check whether or not cell needs to be put in list
862 if (selectionFlag >= 0){
863 bool ListOutput = true;
864 int MeanCellHitsSelection = 0;
865 int EnergyThresholdSelection = 0;
866 int OR_selection = 0;
867 int AND_selection = 0;
868
869 if (selectionFlag == 2){
870 MeanCellHitsSelection = 1;
871 EnergyThresholdSelection = 1;
872 OR_selection = 1;
873 AND_selection = 1;
874 }
875
876
877 else if (selectionFlag == 1){
878 if (m_Algo == 1) ListOutput = false;
879 MeanCellHitsSelection = 1;
880 EnergyThresholdSelection = 0;
881 OR_selection = 1;
882 AND_selection = 0;
883 }
884
885 else if (selectionFlag == 0){
886 if (m_Algo == 0) ListOutput = false;
887 MeanCellHitsSelection = 0;
888 EnergyThresholdSelection = 1;
889 OR_selection = 1;
890 AND_selection = 0;
891 }
892
893 // record number of cells selected by each algorithm
894 iMeanCellHitsSelection += MeanCellHitsSelection;
895 iEnergyThresholdSelection += EnergyThresholdSelection;
896 iOR_selection += OR_selection;
897 iAND_selection += AND_selection;
898
899 // does the cell occur using both algorithms?
900 if (m_SelectRecurringBadCells){ if(AND_selection == 0) ListOutput = false; }
901 if (m_SelectRecurringBadCells){ if(AND_selection == 1) ListOutput = true; }
902
903 if (ListOutput){
904 fprintf(outputFile,"0x%x \t %d \t \t \t %d \t \t %d \t %d\n",onlid,MeanCellHitsSelection,EnergyThresholdSelection,OR_selection,AND_selection);
905
906
907
908 nBadCells++;
909 if(m_SaveTextFile){
910 int nLB = 0;
911 for (int ilb=1;ilb<=nlb;ilb++){
912 if (h1_lb->GetBinContent(ilb) > 0.) nLB++;
913
914 }
915 fr_LB = (double)nLB/(double)(nlb_corr-nBadLBs);
916 nbrLB = (double)nLB;
917 meanECell = h1_e->GetMean();
918 n_ensig = EventCount;
919 if (EventCount!=0){
920 fr_q4k = (double)qcount/(double)EventCount;
921 }
922 n_ecut = nEvents_E_gt_ecut;
923 }
924
925 if (m_SaveRootFile){
926 int nLB = 0;
927 for (int ilb=1;ilb<=nlb;ilb++){
928 if (h1_lb->GetBinContent(ilb) > 0.) nLB++;
929 }
930 fr_LB = (double)nLB/(double)(nlb_corr-nBadLBs);
931 nbrLB = (double)nLB;
932 meanECell = h1_e->GetMean();
933 n_ensig = EventCount;
934 if (EventCount!=0){
935 fr_q4k = (double)qcount/(double)EventCount;
936 }
937 n_ecut = nEvents_E_gt_ecut;
938 Cellmaps[index]->Fill(eta,phi,meanECell);
939 Eeta.Fill(eta,meanECell);
940 CellEnergy.Fill(meanECell);
941 LBfrac.Fill(fr_LB);
942 if (n_ecut>0) {
943 Emean_NbrEvents.Fill(n_ecut,EventEnergySum/n_ecut);
944 Emean_NbrEvents_part[index]->Fill(n_ecut,EventEnergySum/n_ecut);
945 }
946
947 Qfrac.Fill(fr_q4k);
948 Pulsemaps[index]->Add(Pulsemaps[index].get(),h2_pulse);
949 E_LBmaps[index]->Add(E_LBmaps[index].get(),h2_elb);
950 t_LBmaps[index]->Add(t_LBmaps[index].get(),h2_t_LB);
951 CellsFlagged_LB_part[index]->Fill(LBFlaggedIn);
952 CellsFlagged_LB.Fill(LBFlaggedIn);
953 }
954
955 if (m_SaveRootTree){ tree_cells->Fill(); }
956
957
958
959 if (m_SaveTextFile){
960 if (nEvents_E_gt_ecut>0) { EventEnergyMean = EventEnergySum/nEvents_E_gt_ecut; }
961 fprintf(pFile, "0x%x \t %7s \t %d \t %d \t %d \t %d \t %d \t %f \t %4.0f \t %4.3f \t %d \t %d\n",onlid,m_LarIdTranslator->GetPartitonLayerName(index),cellInfo->feedThrough(),cellInfo->slot(),cellInfo->channel(),EventCount,nEvents_E_gt_ecut,EventEnergyMean,nbrLB,fr_q4k,LBFlaggedIn,selectionFlag);
962
963 }
964
965 }
966 }
967
968 qcount = 0.;
969 EventCount = 0.;
970 nEvents_E_gt_ecut = 0.;
971 EventEnergySum = 0.;
972 EventEnergyMean = 0.;
973 } // end of cell loop
974 printf("Cells selected: MeanCellHitsCut \t EnergyThreshodCut \t Either List \t Both Lists\n");
975 printf("\t \t %d \t \t \t \t %d \t \t %d \t %d\n",iMeanCellHitsSelection,iEnergyThresholdSelection,iOR_selection,iAND_selection);
976 if (m_SaveTextFile){
977 fclose (pFile);
978 }
979 fclose (outputFile);
980
981 int nbad = m_nexpected-nskipped;
982 printf("Skipped %d cells. Cells scanned = %d\n",nskipped,nbad);
983 printf("Cells put in Bad Cell List = %d\n",nBadCells);
984 if (noEvdata>0) printf("No Evdata pointer: %d\n",noEvdata);
985
986 if(m_SaveRootFile){
987 fout->cd();
988 for(int i=0;i<npl;i++){
989 if(Cellmaps[i]->GetEntries()>0) Cellmaps[i]->Write();
990 if(E_LBmaps[i]->GetEntries()>0) E_LBmaps[i]->Write();
991 if(t_LBmaps[i]->GetEntries()>0) t_LBmaps[i]->Write();
992 if(Pulsemaps[i]->GetEntries()>0) Pulsemaps[i]->Write();
993 if(CellsFlagged_LB_part[i]->GetEntries()>0) CellsFlagged_LB_part[i]->Write();
994 if( Emean_NbrEvents_part[i]->GetEntries()>0) Emean_NbrEvents_part[i]->Write();
995 }
996 CellsFlagged_LB.Write();
997 Eeta.Write();
998 CellEnergy.Write();
999 Qfrac.Write();
1000 Emean_NbrEvents.Write();
1001 LBfrac.Write();
1002 }
1003 fout->Close();
1004 delete h1_lb;
1005 delete h1_e;
1006 delete h1_q;
1007 delete h2_elb;
1008 delete h2_pulse;
1009 delete h2_t_LB;
1010 delete TProf_pulse;
1011 delete h1_ADCmax;
1012 return;
1013
1014}
1015
1016//____________________________________________________________________________________________________
1017void LArCellsEmptyMonitoring::GetLimits_EqLB(const char* inputfile, int& lbmin, int& lbmax, int& emin, int& emax, int& qmin, int& qmax, int& runNumber, const std::vector<int, std::allocator<int> >& BadLBList){
1018 int lb=0.;
1019
1020 // Opening file:
1022
1023 unsigned int nchannels = tuple->nChannels();
1024
1025 // -------------------------------------------------------------------------
1026 qmin = emin = lbmin = 99999;
1027 qmax = emax = lbmax = -1;
1028 runNumber = 0.;
1029
1030 for(unsigned int ichan = 0; ichan < nchannels; ichan++){
1031 // pass empty cells
1032 if(tuple->historySize(ichan)==0){ continue; }
1033
1034 // process non empty cells
1035 const LArSamples::History* hist = tuple->cellHistory(ichan);
1036
1037 unsigned int ndigits = hist->nData();
1038 if(ndigits==0){ continue; }
1039
1040 // loop on the events for each cells
1041 for(unsigned int idigit = 0; idigit < ndigits; idigit++){
1042 const LArSamples::Data* data = hist->data(idigit);
1043 const LArSamples::EventData* Evdata = data->eventData();
1044 if(!Evdata) continue;
1045 int lumiBlock = Evdata->lumiBlock();
1046
1047
1048 if (data->energy() != 0. && data->noise() != 0.){ // record only events with real energy/noise values
1049 bool isBadLB = CheckBadLBList(lumiBlock,BadLBList);
1050 //skip bad LBs
1051 if (isBadLB) continue;
1052
1053
1054 lb = (int)lumiBlock;
1055 if(lb>lbmax) lbmax = lb;
1056 if(lb<lbmin) lbmin = lb;
1057 double energyGeV = data->energy()/1000.;
1058 if(energyGeV > emax) emax = energyGeV;
1059 if(energyGeV < emin) emin = energyGeV;
1060 if(data->quality() > qmax) qmax = data->quality();
1061 if(data->quality() < qmin) qmin = data->quality();
1062
1063 runNumber = data->run();
1064 }
1065 }
1066 }
1067}
1068
1069//____________________________________________________________________________________________________ USING ALL LBS
1070std::vector<int, std::allocator<int> > LArCellsEmptyMonitoring::GetBadLBList(const char* inputfile, int lbmin, int lbmax, double nsigma, int nlb, const std::vector<int, std::allocator<int> >& DQLBList){
1071 std::map< std::pair<unsigned int, unsigned int>, unsigned int > eventCells_tot;
1072 std::map< std::pair<unsigned int, unsigned int>, double > eventEnergy_tot;
1073 std::map< std::pair<unsigned int, unsigned int>, unsigned int > eventLumiBlock;
1074 std::map< std::pair<std::string, unsigned int>, unsigned int > eventCells;
1075 int lb=0.;
1076 double NSIG = nsigma;
1077
1078 // Opening file:
1080 unsigned int nchannels = tuple->nChannels();
1081
1082 // -------------------------------------------------------------------------
1083 for(unsigned int ichan = 0; ichan < nchannels; ichan++){
1084 // pass empty cells
1085 if(tuple->historySize(ichan)==0){ continue; }
1086
1087 // process non empty cells
1088 const LArSamples::History* hist = tuple->cellHistory(ichan);
1089 const LArSamples::CellInfo* cellInfo = hist->cellInfo();
1090 int index = m_LarIdTranslator->GetPartitionLayerIndex(cellInfo->calo(),cellInfo->layer());
1091 int calo = cellInfo->calo();
1092
1093 if (m_MaskPresampler){
1094 if (CheckForPresamplerCells(index)){ continue; }
1095 }
1096 if (m_MaskCalo){
1097 if (!CheckForPresamplerCells(index)){ continue; }
1098 }
1099
1100 unsigned int ndigits = hist->nData();
1101 if(ndigits==0){ continue; }
1102
1103 // loop on the events for each cell
1104 for(unsigned int idigit = 0; idigit < ndigits; idigit++){
1105 const LArSamples::Data* data = hist->data(idigit);
1106
1107 const LArSamples::EventData* Evdata = data->eventData();
1108 if(!Evdata) continue;
1109 int lumiBlock = Evdata->lumiBlock();
1110 //int lumiBlock = data->lumiBlock();
1111
1112 lb = (int)lumiBlock;
1113 double energyGeV = data->energy()/1000.;
1114
1115
1116 if (lumiBlock <= lbmax && lumiBlock >= lbmin ) { // use only LBs in range
1117 if (data->energy() > sqrt((NSIG*data->noise())*(NSIG*data->noise())) && data->energy() != 0. && data->noise() != 0.){ // record only events with E>NSIG and real energy/noise values
1118 // cell-event mapping
1119 std::pair<unsigned int, unsigned int> ev(data->run(), data->event());
1120 std::pair<std::string, unsigned int> ev_cryo(GetCryostat(calo), data->event());
1121 eventCells_tot[ev]++;
1122 eventEnergy_tot[ev] += energyGeV;
1123 eventLumiBlock[ev] = lb;
1124 eventCells[ev_cryo]++;
1125 }
1126 }
1127 }
1128 }
1129 // -------------------------------------------------------------------------
1130 // Find Bad LBs -> make list (BadLB vector output)
1131 // -------------------------------------------------------------------------
1132 auto hCells_Ev_LB = std::make_unique<TProfile>("","",nlb,lbmin,lbmax,-100,100000);//averaged number of cells per event per LB
1133 std::map< std::string, TProfilep> hCellsEvLB;
1134 std::map< std::string, TH1Fp> hp_cryo;
1135 // -------------------------------------------------------------------------
1136 // loop over events (based on Interface::ShowEvents).
1137 // -------------------------------------------------------------------------
1138 int nCryo = 8;
1139 std::string Cryo[8] = {"EMBA","EMBC","EMECA","EMECC","HECA", "HECC","FCALA","FCALC"};
1140 for(int k = 0; k< nCryo; k++){
1141 hCellsEvLB[Cryo[k]].reset((TProfile*)hCells_Ev_LB->Clone());
1142 }
1143 for(unsigned int ievent = 0; ievent < tuple->nEvents(); ievent++) {
1144 const LArSamples::EventData* evtData = tuple->eventData(ievent);
1145 std::pair<unsigned int, unsigned int> id(evtData->run(), evtData->event());
1146 if(eventCells_tot[id]==0) continue;
1147
1148 for(int j=0; j<nCryo ;j++){
1149 std::pair<std::string, unsigned int> id_cryo(Cryo[j], evtData->event());
1150 hCellsEvLB[Cryo[j]]->Fill(eventLumiBlock[id], eventCells[id_cryo]);
1151 }
1152
1153 hCells_Ev_LB->Fill(eventLumiBlock[id], eventCells_tot[id]);
1154 }
1155
1156 auto hp = std::make_unique<TH1F>("","",(hCells_Ev_LB->GetBinContent(hCells_Ev_LB->GetMaximumBin())),0,hCells_Ev_LB->GetBinContent(hCells_Ev_LB->GetMaximumBin()));// histo to find average number of cells firing per event per LB
1157 for(int k = 0; k< nCryo; k++){
1158 auto hp_temp = std::make_unique< TH1F>("","",(hCellsEvLB[Cryo[k]]->GetBinContent(hCellsEvLB[Cryo[k]]->GetMaximumBin())*10),0,hCellsEvLB[Cryo[k]]->GetBinContent(hCellsEvLB[Cryo[k]]->GetMaximumBin()));// histo to find average number of cells firing per event per LB
1159 std::string name1 = "hp_" + Cryo[k];
1160 hp_cryo[Cryo[k]].reset((TH1F*)hp_temp->Clone(name1.c_str()));
1161 }
1162
1163 for (int p=1;p<=nlb;p++){
1164 for(int j=0; j<nCryo; j++){
1165 double bincont = hCellsEvLB[Cryo[j]]->GetBinContent(p);
1166 hp_cryo[Cryo[j]]->Fill(bincont);
1167 }
1168 double bincont1 = hCells_Ev_LB->GetBinContent(p);
1169 hp->Fill(bincont1);
1170 }
1171
1172 std::map< std::string, double> Mean;
1173 std::map< std::string, double> RMS;
1174 std::map< int, vector<std::string> > BadLB_cryo;
1175
1176 for(int k=0; k<nCryo; k++)
1177 {
1178 Mean[Cryo[k]] = hp_cryo[Cryo[k]]->GetMean();
1179 RMS[Cryo[k]] = hp_cryo[Cryo[k]]->GetRMS();
1180 }
1181
1182 double MEAN2 = hp->GetMean();
1183 double RMS2 = hp->GetRMS();
1184 m_Mean_checkBadLBs = MEAN2;
1185 m_RMS_checkBadLBs = RMS2;
1186 vector<int> BadLB;
1187 // vector<int> BadLB_tot;
1188 vector<int> BadLB_tot=DQLBList;
1189
1190 double value1 = (MEAN2+(RMS2*3.));
1191 int numberFlagged=0;
1192 for (int l=1;l<=nlb;l++){
1193 for(int j=0; j<nCryo; j++){
1194 double value = MEAN2 + (RMS[Cryo[j]]*3);
1195 if(hCellsEvLB[Cryo[j]]->GetBinContent(l) > value){
1196 int badLB = hCellsEvLB[Cryo[j]]->GetBinLowEdge(l);
1197 BadLB_cryo[badLB].push_back(Cryo[j]);
1198 bool isadd = true;
1199 for(unsigned int p=0; p< BadLB_tot.size(); p++) {
1200 if(badLB == BadLB_tot[p]) isadd = false;
1201 }
1202 if(isadd){
1203 BadLB_tot.push_back(badLB);
1204 numberFlagged++;
1205 printf("Removing bad LB %d in %s\n",badLB,Cryo[j].c_str());
1206 }
1207 }
1208 }
1209
1210 if (hCells_Ev_LB->GetBinContent(l) > value1){
1211 BadLB.push_back(hCells_Ev_LB->GetBinLowEdge(l));
1212 }
1213 }
1214 printf("\n");
1215 printf("Number of Bad LBs found: %d\n",numberFlagged);
1216 printf("Number of LBs to be removed: %zu", BadLB_tot.size());
1217 printf("\n");
1218
1219 return BadLB_tot;
1220}
1221
1222
1223//____________________________________________________________________________________________________
1224bool LArCellsEmptyMonitoring::CheckBadLBList(int lumiBlock, const std::vector<int, std::allocator<int> >& BadLBList){
1225 for (unsigned int yy=0;yy<BadLBList.size();yy++){
1226 if (lumiBlock == BadLBList[yy]){
1227 return true;
1228 }
1229 }
1230 return false;
1231}
1232
1233//____________________________________________________________________________________________________
1234void LArCellsEmptyMonitoring::GetMeanCellHits(const char* inputfile, int nlb, int lbmin, int lbmax, int nsigma, const std::vector<int, std::allocator<int> >& BadLBList, double& MeanHits, double& rmsHits, int& nlb_corr)
1235{
1236
1237
1238 int nHits = 0., lumiBlock = 0.,nCells = 0.;
1239 double energy = 0, noise = 0;
1240 std::unique_ptr<LArSamples::Interface> tuple((LArSamples::Interface*)Interface::open(inputfile));
1241 unsigned int nchannels = tuple->nChannels();
1242
1243 double TotalRecordedHits=0;
1244 std::vector<int, std::allocator<int> > HitsPerLB;
1245 double var=0;
1246 TH1Fp th1_Hits = std::make_unique<TH1F>("","",nlb,lbmin,lbmax); // number of events (E>nsig) in each LB for each cell
1247 TH1Fp hNLB = std::make_unique<TH1F>("","",nlb,lbmin,lbmax); // number of lumiblocks
1248
1249 // -------------------------------------------------------------------------
1250 for(unsigned int ichan = 0; ichan < nchannels; ichan++){
1251 // pass empty cells
1252 if(tuple->historySize(ichan)==0){ continue; }
1253
1254
1255 // process non empty cells
1256 const LArSamples::History* hist = tuple->cellHistory(ichan);
1257
1258 unsigned int ndigits = hist->nData();
1259
1260 // loop on the events for each cells
1261 for(unsigned int idigit = 0; idigit < ndigits; idigit++){
1262 const LArSamples::Data* data = hist->data(idigit);
1263 const LArSamples::EventData* Evdata = data->eventData();
1264 if(!Evdata) continue;
1265 lumiBlock = Evdata->lumiBlock();
1266
1267 energy = data->energy();
1268 noise = data->noise();
1269 bool isBadLB = CheckBadLBList(lumiBlock,BadLBList);
1270 if (isBadLB) continue; //skip bad LBs
1271 hNLB->Fill(lumiBlock);
1272
1273 bool ProcessEvent = CheckEventSelectionCriteria(lumiBlock, nsigma, energy, noise, lbmin, lbmax);
1274 if (ProcessEvent){
1275
1276
1277 th1_Hits->Fill(lumiBlock);
1278 nHits++;
1279 }
1280 }
1281 if (nHits > 0.) nCells++;
1282
1283 nHits = 0.;
1284
1285 }
1286
1287
1288 // -------------------------------------------------------------------------
1289 // determine average #hits per cell per LB
1290 // -------------------------------------------------------------------------
1291
1292
1293
1294 TH1Fp tp_ev = std::make_unique<TH1F>("","",th1_Hits->GetBinContent(th1_Hits->GetMaximumBin())*100,0,th1_Hits->GetBinContent(th1_Hits->GetMaximumBin()));
1295
1296 for (int i=1;i<=nlb;i++){
1297 if(hNLB->GetBinContent(i)>0){
1298 nlb_corr++;
1299 tp_ev->Fill(th1_Hits->GetBinContent(i));
1300 TotalRecordedHits+=th1_Hits->GetBinContent(i);
1301 HitsPerLB.push_back(th1_Hits->GetBinContent(i));
1302 }
1303 }
1304
1305 MeanHits = (nCells==0||nlb_corr==0) ? 0 : static_cast<double>(TotalRecordedHits)/(nlb_corr*nCells);
1306 if (nCells > 0){
1307 for (unsigned int j=0;j<HitsPerLB.size();j++){
1308 var += (((double)HitsPerLB[j]/(double)nCells) - MeanHits)*(((double)HitsPerLB[j]/(double)nCells) - MeanHits);
1309 }
1310 } else {
1311 std::cout<<"nCells is " << nCells << " in LArCellsEmptyMonitoring::GetMeanCellHits"<<std::endl;
1312 return;
1313 }
1314 if (nlb_corr > 0){
1315 rmsHits = var/nlb_corr;
1316 }
1317 printf("Mean number of hits/cell for 1 LB = %4.3f, RMS = %4.3f\n",MeanHits,rmsHits);
1318 printf("Number of cells firing at E > %d sigma = %d\n",nsigma,nCells);
1319 printf("Total number of LBs included = %d\n",nlb_corr);
1320
1321
1322}
1323
1324//____________________________________________________________________________________________________
1325bool LArCellsEmptyMonitoring::CheckEventSelectionCriteria(int lumiBlock, int nsigma, double energy, Float_t noise, int lbmin, int lbmax){
1326
1327
1328 if (energy == 0 || noise == 0){
1329 return false;
1330 } else if (lumiBlock <= lbmax && lumiBlock >= lbmin && energy > sqrt((nsigma*noise)*(nsigma*noise)) ) { // use only LBs in range
1331 return true;
1332 }
1333 return false;
1334
1335}
1336
1337
1338//____________________________________________________________________________________________________
1339int LArCellsEmptyMonitoring::CheckCellSelectionCriteria(int EventCount, int nsigmaHits, double MeanHits, double rmsHits, int nEvents_E_gt_ecut, double EventEnergySum, int nBadLBs, int nlb) const{
1340 //FLAG KEY:
1341 //selectionFlag == 0 -> Used EventEnergyCut
1342 //selectionFlag == 1 -> Used MeanCellHitCut
1343 //selectionFlag == 2 -> Used EventEnergyCut && MeanCellHitCut
1344
1345
1346 bool a=false;
1347 bool b=false;
1348 bool c=false;
1349
1350 //pas bon if ((EventCount > (MeanHits[GetSectionIndex(index)]+(nsigmaHits*rmsHits[GetSectionIndex(index)]))*(nlb-nBadLBs[GetCryoIndex(index)]))) a=true;
1351
1352 //original
1353 if ((EventCount > (MeanHits+(nsigmaHits*rmsHits))*((double)nlb-(double)nBadLBs))) a=true;
1354 // reverse cut
1355 // if ((EventCount < (MeanHits+(nsigmaHits*rmsHits))*((double)nlb-(double)nBadLBs))) a=true;
1356
1357 //original
1358 if (nEvents_E_gt_ecut > m_UpperCountThreshold && (EventEnergySum/(double)nEvents_E_gt_ecut) > m_LowerCellEnergyThreshold) b=true;
1359 // reverse cut
1360 // if (nEvents_E_gt_ecut < m_UpperCountThreshold && (EventEnergySum/(double)nEvents_E_gt_ecut) < m_LowerCellEnergyThreshold) b=true;
1361
1362 //original
1363 if (nEvents_E_gt_ecut > m_LowerCountThreshold && (EventEnergySum/(double)nEvents_E_gt_ecut) > m_UpperCellEnergyThreshold) c=true;
1364 // reverse cut
1365 // if (nEvents_E_gt_ecut < m_LowerCountThreshold && (EventEnergySum/(double)nEvents_E_gt_ecut) < m_UpperCellEnergyThreshold) c=true;
1366
1367
1368 if ((a && b) || (a && c)){
1369 return 2;
1370 } else if (a && !b && !c){
1371 return 1;
1372 } else if ((!a && b) || (!a && c)){
1373 return 0;
1374 }
1375
1376 return -1;
1377}
1378
1379//____________________________________________________________________________________________________
1381
1382 return index == 0 || index == 4;
1383}
1384
1385//____________________________________________________________________________________________________
1389
1390//____________________________________________________________________________________________________
1391void LArCellsEmptyMonitoring::SetPartition(bool setpart, const std::string& partname)
1392{
1393 const int npl = m_LarIdTranslator->GetNpl();
1394
1395 m_SetPartition = setpart;
1396
1397 if(!setpart)
1398 {
1399 m_PartitionName = "";
1400 m_PartitionIndex = -1;
1401 }
1402 else if(setpart)
1403 {
1404 bool isFoundPartition = false;
1405 for(int i=0; i< npl; i++){
1406 if(partname == m_LarIdTranslator->GetPartitonLayerName(i)){
1407 m_PartitionName = "_" +partname;
1408 m_PartitionIndex = i;
1409 isFoundPartition = true;
1410 }
1411 }
1412 if(!isFoundPartition){
1413 printf("ERROR: Partition %s does not exist! Invalid input name.\n",partname.c_str());
1414 printf("Possible candidates are:\n");
1415 for (int j=0;j<npl;j++){ printf("%s\n",m_LarIdTranslator->GetPartitonLayerName(j)); }
1416 std::abort();
1417 }
1418 }
1419}
1420//____________________________________________________________________________________________________
1422{
1423 std::string cryostat = "NotGiven";
1424 if(calo == 1) cryostat = "EMBA";
1425 else if(calo == -1) cryostat = "EMBC";
1426 else if(calo == 5) cryostat = "FCALA";
1427 else if(calo == -5) cryostat = "FCALC";
1428 else if(calo == 4) cryostat = "HECA";
1429 else if(calo == -4) cryostat = "HECC";
1430 else if(calo == 2 || calo == 3) cryostat = "EMECA";
1431 else if(calo == -2 || calo == -3) cryostat = "EMECC";
1432 return cryostat;
1433}
1434
1435
1436//____________________________________________________________________________________________________
1437void LArCellsEmptyMonitoring::ReadDefectLBList(bool ReadList, const TString& LBfile)
1438{
1439
1440
1441 if (!ReadList){
1442 m_LBfile="";
1443 m_ReadDefectLBList=false;
1444 }
1445 else{
1446 m_LBfile=LBfile;
1447 m_ReadDefectLBList=true;
1448 }
1449}
1450
1451//____________________________________________________________________________________________________
1452std::vector<int> LArCellsEmptyMonitoring::ReadBadLBList(const TString& LBfile)
1453{
1454 std::vector<int> LBList;
1455
1456 std::ifstream infile(LBfile.Data());
1457 std::string line;
1458
1459 // assume single-line format with coma-separated LBs (from python)
1460 std::getline(infile,line,'\n');
1461 TString filter(line.c_str());
1462 std::unique_ptr<TObjArray> list(filter.Tokenize(", ")); // coma\space delimiters
1463 if(list->GetEntries() == 0){
1464 printf("No LB filtering specified, or bad format. Exiting.\n");
1465 LBList.push_back(0);
1466 return LBList;
1467 }
1468
1469 for(int k = 0; k < list->GetEntries(); k++){
1470 TObjString* tobs = (TObjString*)(list->At(k));
1471 LBList.push_back((int)(tobs->String()).Atoi());
1472 }
1473 printf("LB List: %d\n",(int)LBList.size());
1474 return LBList;
1475}
1476/*
1477
1478std::vector<int, std::allocator<int> > LArCellsEmptyMonitoring::ReadBadLBList(const TString LBfile)
1479{
1480 // Reads in defect LB list if necessary
1481 std::vector<int, std::allocator<int> > tlist;
1482 std::ifstream infile(LBfile);
1483 std::string argStr;
1484 std::getline(infile,argStr);
1485 for (size_t i = 0,n; i <= argStr.length(); i = n+1)
1486 {
1487 n = argStr.find_first_of(',',i);
1488 if (n == std::string::npos) n = argStr.length();
1489 std::string tmp = argStr.substr(i,n-i);
1490 char ctmp[6];
1491 for (int ic=0;ic<6;ic++){
1492 ctmp[ic]=tmp[ic];
1493 }
1494 int temp = atoi (ctmp);
1495 // printf("temp: %d\n",temp);
1496 tlist.push_back(temp);
1497 }
1498 return tlist;
1499
1500
1501
1502}
1503
1504*/
1505//____________________________________________________________________________________________________
1506void LArCellsEmptyMonitoring::ScanOnlids(const TString& inputfile)
1507{
1508 // Scans all channel entries in the ntuple and looks for duplicates onlids.
1509
1510 int index = -1;
1511 ULong64_t onlid = 0;
1512 std::map<ULong64_t,unsigned int> idmap;
1513 std::map<ULong64_t,unsigned int>::iterator idmap_itr;
1514 int nskipped=0,nrepeated=0;
1515
1516 // Opening file:
1517 std::unique_ptr<LArSamples::Interface> tuple((LArSamples::Interface*)Interface::open(inputfile));
1518 printf("Number of events: %u %u\n",tuple->nEvents(),tuple->nChannels()); //tuple->ShowEvents("energy>0.");
1519 unsigned int nchannels = tuple->nChannels();
1520
1521 // -------------------------------------------------------------------------
1522 for(unsigned int ichan = 0; ichan < nchannels; ichan++){
1523 // pass empty cells
1524 if(tuple->historySize(ichan)==0){ nskipped++; continue; }
1525
1526 // process non empty cells
1527 const LArSamples::History* hist = tuple->cellHistory(ichan);
1528 const LArSamples::CellInfo* cellInfo = hist->cellInfo();
1529
1530 // index for partition
1531 index = m_LarIdTranslator->GetPartitionLayerIndex(cellInfo->calo(),cellInfo->layer());
1532 onlid = cellInfo->onlid();
1533 /*
1534 if(m_LarIdTranslator->FindChannel(index,cellInfo->eta(),cellInfo->phi())){
1535 onlid = m_LarIdTranslator->onlid;
1536 } else onlid = 0;
1537 */
1538 if(onlid<=0) printf("%u: Bad Cell Onlid = 0x%x (%+.2f,%+.2f)\n",ichan,(unsigned int)onlid,cellInfo->eta(),cellInfo->phi());
1539
1540 idmap_itr = idmap.find(onlid);
1541
1542 // new onlid
1543 if(idmap_itr == idmap.end()){
1544 idmap[onlid] = ichan;
1545 } else {
1546 nrepeated+=1;
1547 printf("Onlid 0x%x (%d,%s,%+.2f,%+.2f)\n",(unsigned int)onlid,index,m_LarIdTranslator->GetPartitonLayerName(index),
1549 }
1550 }
1551
1552 printf("Skipped %d cells.\n",nskipped);
1553 printf("Number of onlids: Unique=%d, Repeated=%d\n",(int)idmap.size(),nrepeated);
1554
1555 return;
1556}
1557
1558//____________________________________________________________________________________________________
1559void LArCellsEmptyMonitoring::DoEtaPhiMonitoring(const char* inputfile,const char* optionplot,const char* optionsave)
1560{
1561 // Main monitoring function with primary goal to produce simple DQM-equivalent (eta,phi) maps.
1562 // Depending on the argument, the function will put different quantities in the histograms.
1563 // Currently supported options:
1564 //
1565 // - optionplot = "NAbove4Sigma","PercentageAbove4Sigma",
1566 // "NAbove5Sigma","PercentageAbove5Sigma",
1567 // "NQualityAbove4000","PercentageQualityAbove4000"
1568 // - optionsave = "root","png"
1569 //
1570 //
1571
1572 printf("LArCellsEmptyMonitoring::DoEtaPhiMonitoring: Reading options: %s %s.\n",optionplot,optionsave);
1573
1574 bool knormplot = false;
1575 if(strstr(optionplot,"Precentage")) knormplot = true; // needs normalization plots
1576
1577 int kcuttype = 0; // no cut
1578 double nsigmacut = 0.;
1579 double qualitycut = 0.;
1580 if(strstr(optionplot,"Sigma")){
1581 kcuttype = 1; // energy
1582 if(strstr(optionplot,"4Sigma")) nsigmacut = 4.;
1583 if(strstr(optionplot,"5Sigma")) nsigmacut = 5.;
1584 } else if(strstr(optionplot,"Quality")){
1585 kcuttype = 2; // quality
1586 qualitycut = 4000.; // not much control for now
1587 }
1588
1589 Char_t hname[512];
1590 int index = 0;
1591 int nskipped=0;
1592 ULong64_t onlid = 0;
1593
1594 // Opening file:
1595 std::unique_ptr<LArSamples::Interface> tuple((LArSamples::Interface*)Interface::open(inputfile));
1596 printf("Number of events: %u %u\n",tuple->nEvents(),tuple->nChannels());
1597 unsigned int nchannels = tuple->nChannels();
1598
1599 // eta-phi maps
1600 const int nhists = m_LarIdTranslator->GetNpl();
1601 std::vector<TH2*> hmap_counts_all (nhists);
1602 std::vector<TH2*> hmap_energy_cut (nhists);
1603 std::vector<TH2*> hmap_quality_cut (nhists);
1604 for(int j=0;j<nhists;j++){
1605 hmap_counts_all[j] = m_LarIdTranslator->GetCaloPartitionLayerMap(j);
1606 sprintf(hname,"counst_all_%s_%d",m_LarIdTranslator->GetPartitonLayerName(j),j);
1607 hmap_counts_all[j]->SetName(hname);
1608 //
1609 hmap_energy_cut[j] = m_LarIdTranslator->GetCaloPartitionLayerMap(j);
1610 sprintf(hname,"energy_cut_%s_%d",m_LarIdTranslator->GetPartitonLayerName(j),j);
1611 hmap_energy_cut[j]->SetName(hname);
1612 //
1613 hmap_quality_cut[j] = m_LarIdTranslator->GetCaloPartitionLayerMap(j);
1614 sprintf(hname,"quality_cut_%s_%d",m_LarIdTranslator->GetPartitonLayerName(j),j);
1615 hmap_quality_cut[j]->SetName(hname);
1616 }
1617
1618 // -------------------------------------------------------------------------
1619 for(unsigned int ichan = 0; ichan < nchannels; ichan++){
1620 // pass empty cells
1621 if(tuple->historySize(ichan)==0){ nskipped++; continue; }
1622
1623 // process non empty cells
1624 const LArSamples::History* hist = tuple->cellHistory(ichan);
1625 const LArSamples::CellInfo* cellInfo = hist->cellInfo();
1626 unsigned int ndigits = hist->nData();
1627 if(ndigits==0){ nskipped++; continue; }
1628
1629 // index for partition; this can return a negative value in case of error
1630 index = m_LarIdTranslator->GetPartitionLayerIndex(cellInfo->calo(),cellInfo->layer());
1631 if (index<0){
1632 std::cout<<"GetPartitionLayerIndex returned -1 in LArCellsEmptyMonitoring::DoEtaPhiMonitoring"<<std::endl;
1633 continue;
1634 }
1635 onlid = cellInfo->onlid();
1636 if(onlid<=0) printf("%u: Bad Cell Onlid = 0x%x (%+.2f,%+.2f)\n",ichan,(unsigned int)onlid,cellInfo->eta(),cellInfo->phi());
1637
1638 // loop on the events for each cells
1639 for(unsigned int idigit = 0; idigit < ndigits; idigit++){
1640 const LArSamples::Data* data = hist->data(idigit);
1641
1642 // all stats
1643 hmap_counts_all[index]->Fill(m_LarIdTranslator->eta,m_LarIdTranslator->phi);
1644
1645 // energy-like
1646 if(kcuttype==1 && data->noise()>0.){
1647 if((data->energy()/data->noise())>nsigmacut) hmap_energy_cut[index]->Fill(m_LarIdTranslator->eta,m_LarIdTranslator->phi);
1648 }
1649 if(kcuttype==2){
1650 if(data->quality()>qualitycut) hmap_quality_cut[index]->Fill(m_LarIdTranslator->eta,m_LarIdTranslator->phi);
1651 }
1652 }
1653 }
1654
1655 int nbad = m_nexpected-nskipped;
1656 printf("Skipped %d cells. Bad Cells = %d\n",nskipped,nbad);
1657
1658 // normalize, if needed
1659 if(knormplot){
1660 for(int j=0;j<nhists;j++){
1661 hmap_energy_cut[j]->Divide(hmap_counts_all[j]);
1662 hmap_quality_cut[j]->Divide(hmap_counts_all[j]);
1663 }
1664 }
1665
1666 std::unique_ptr<TFile> tout;
1667 TCanvas* c0 = nullptr, *c1 = nullptr;
1668
1669 if(!strcmp(optionsave,"root")){
1670 tout.reset(new TFile("EtaPhiMonitoring.root","recreate"));
1671 c0 = m_LarIdTranslator->CaloPartitionLayerDisplay(hmap_counts_all.data(),"Counts",1);
1672 c0->SetName("Normalization");
1673 c0->Write();
1674 for(int j=0;j<nhists;j++) hmap_counts_all[j]->Write();
1675 if(kcuttype==1){
1676 c0 = m_LarIdTranslator->CaloPartitionLayerDisplay(hmap_energy_cut.data(),"EnergyCut",1);
1677 c0->SetName("EnergyCut");
1678 c0->Write();
1679 for(int j=0;j<nhists;j++) hmap_energy_cut[j]->Write();
1680 }
1681 if(kcuttype==2){
1682 c0 = m_LarIdTranslator->CaloPartitionLayerDisplay(hmap_quality_cut.data(),"QualityCut",1);
1683 c0->SetName("QualityCut");
1684 c0->Write();
1685 for(int j=0;j<nhists;j++) hmap_quality_cut[j]->Write();
1686 }
1687 tout->Close();
1688 } else {
1689 c0 = m_LarIdTranslator->CaloPartitionLayerDisplay(hmap_counts_all.data(),"Counts",1);
1690 c0->SaveAs("Normalization.png");
1691 c1 = new TCanvas("c1","");
1692 for(int j=0;j<nhists;j++){ hmap_counts_all[j]->Draw("colz"); sprintf(hname,"%s.png",hmap_counts_all[j]->GetName()); c1->SaveAs(hname); }
1693 if(kcuttype==1){
1694 c0 = m_LarIdTranslator->CaloPartitionLayerDisplay(hmap_energy_cut.data(),"EnergyCut",1);
1695 c0->SaveAs("EnergyCut.png");
1696 c1->cd();
1697 for(int j=0;j<nhists;j++){ hmap_energy_cut[j]->Draw("colz"); sprintf(hname,"%s.png",hmap_energy_cut[j]->GetName()); c1->SaveAs(hname); }
1698 }
1699 if(kcuttype==2){
1700 c0 = m_LarIdTranslator->CaloPartitionLayerDisplay(hmap_quality_cut.data(),"QualityCut",1);
1701 c0->SaveAs("QualityCut.png");
1702 c1->cd();
1703 for(int j=0;j<nhists;j++){ hmap_quality_cut[j]->Draw("colz"); sprintf(hname,"%s.png",hmap_quality_cut[j]->GetName()); c1->SaveAs(hname); }
1704 }
1705 }
1706 return;
1707}
1708
1709//____________________________________________________________________________________________________
1710void LArCellsEmptyMonitoring::TriggerEfficiency(const char* inputfile,float fractionInPS)
1711{
1712 // Function aimed at extracting the trigger performance of a specific chain
1713 // by emulating its online selection using the calibration stream data.
1714 //
1715 // This is currently used to monitor the rejection performance of the
1716 // PreSampler noise in the physics_CosmicCalo stream (L2_PreS* chains)
1717 // which runs on each family of triggers (EM,TAU,J).
1718 // One needs to set the fraction of energy deposited in the PreSampler with
1719 // fractionInPS.
1720 //
1721
1722
1723 std::map< std::pair<unsigned int, unsigned int>, unsigned int > eventCells;
1724 std::map< std::pair<unsigned int, unsigned int>, double > eventEnergy_PS;
1725 std::map< std::pair<unsigned int, unsigned int>, double > eventEnergy_LAr;
1726 std::map< std::pair<unsigned int, unsigned int>, unsigned int > eventCells_PS;
1727 std::map< std::pair<unsigned int, unsigned int>, unsigned int > eventLayer;
1728 int run=0;
1729 // Opening file:
1730 std::unique_ptr<LArSamples::Interface> tuple((LArSamples::Interface*)Interface::open(inputfile));
1731 unsigned int nchannels = tuple->nChannels();
1732
1733 // -------------------------------------------------------------------------
1734 for(unsigned int ichan = 0; ichan < nchannels; ichan++){
1735 // pass empty cells
1736 if(tuple->historySize(ichan)==0){ continue; }
1737
1738 // process non empty cells
1739 const LArSamples::History* hist = tuple->cellHistory(ichan);
1740 const LArSamples::CellInfo* cellInfo = hist->cellInfo();
1741 unsigned int layer = cellInfo->layer();
1742
1743 unsigned int ndigits = hist->nData();
1744 if(ndigits==0){ continue; }
1745
1746 // loop on the events for each cells
1747 for(unsigned int idigit = 0; idigit < ndigits; idigit++){
1748 const LArSamples::Data* data = hist->data(idigit);
1749 run = data->run();
1750
1751 // convert to GeV
1752 double energyGeV = data->energy()/1000.;
1753
1754 // cell-event mapping
1755 std::pair<unsigned int, unsigned int> ev(data->run(), data->event());
1756 eventCells[ev]++;
1757 eventEnergy_LAr[ev] += energyGeV;
1758 eventLayer[ev] = layer;
1759 if(layer == 0){
1760 eventEnergy_PS[ev] += energyGeV;
1761 eventCells_PS[ev]++;
1762 }
1763 }
1764 }
1765
1766 // non-constant binning for a wider spetrum
1767 //double binE[48]={0,2,4,6,8,10,13,16,19,22,26,30,34,38,42,47,52,57,62,68,75,82,90,100,110,120,130,140,150,160,170,180,195,210,225,240,255,270,285,300,320,340,360,380,400,430,460,500};
1768
1769 constexpr int nbins = 42;
1770 double binE[nbins+1]{};
1771 int i=0,j=0;
1772 int stop=0;
1773 double de = 0.,ene = 0.;
1774 // steps of 2GeV for the first 10 bins [0-20]
1775 de = 2.;
1776 stop = (int)(20./de);
1777 for(i=0;i<stop;i++,j++){
1778 ene = de*(double)i;
1779 binE[j] = ene;
1780 }
1781 // steps of 5GeV for [20-100]
1782 de = 5.;
1783 stop = (int)((100.-20.)/de);
1784 for(i=0;i<stop;i++,j++){
1785 ene += de;
1786 binE[j] = ene;
1787 }
1788 // steps of 25GeV for [100-500]
1789 de = 25.;
1790 stop = (int)((500.-100.)/de);
1791 for(i=0;i<stop;i++,j++){
1792 ene += de;
1793 binE[j] = ene;
1794 }
1795 // add extra bin to cover the rest
1796 binE[j] = 3500.;
1797
1798
1799 TH1F E_LAr_pass("E_LAr_pass","",nbins,binE);
1800 TH1F E_LAr_tot("E_LAr_tot","",nbins,binE);
1801 TH1F E_LAr_EM5_pass("E_LAr_EM5_pass","",nbins,binE);
1802 TH1F E_LAr_EM5_tot("E_LAr_EM5_tot","",nbins,binE);
1803 TH1F E_LAr_TAU8_pass("E_LAr_TAU8_pass","",nbins,binE);
1804 TH1F E_LAr_TAU8_tot("E_LAr_TAU8_tot","",nbins,binE);
1805 TH1F E_LAr_J10_pass("E_LAr_J10_pass","",nbins,binE);
1806 TH1F E_LAr_J10_tot("E_LAr_J10_tot","",nbins,binE);
1807 TH1F nCellsPS_pass("nCellsPS_pass","",100, 0, 100);
1808 TH1F nCellsPS_tot("nCellsPS_tot","",100, 0, 100);
1809 TH1F nCellsPS_EM5_pass("nCellsPS_EM5_pass","",100, 0, 100);
1810 TH1F nCellsPS_EM5_tot("nCellsPS_EM5_tot","",100, 0, 100);
1811 TH1F nCellsPS_TAU8_pass("nCellsPS_TAU8_pass","",100, 0, 100);
1812 TH1F nCellsPS_TAU8_tot("nCellsPS_TAU8_tot","",100, 0, 100);
1813 TH1F nCellsPS_J10_tot("nCellsPS_J10_tot","",100, 0, 100);
1814 TH1F nCellsPS_J10_pass("nCellsPS_J10_pass","",100, 0, 100);
1815
1816 // -------------------------------------------------------------------------
1817 // loop over events (based on Interface::ShowEvents).
1818 // -------------------------------------------------------------------------
1819 for(unsigned int ievent = 0; ievent < tuple->nEvents(); ievent++) {
1820 const LArSamples::EventData* evtData = tuple->eventData(ievent);
1821 std::pair<unsigned int, unsigned int> id(evtData->run(), evtData->event());
1822 if(eventCells[id]==0) continue;
1823 if(eventEnergy_LAr[id]<=0) continue;
1824 bool isEM5 = evtData->isPassed("L1_EM5_EMPTY");
1825 bool isTAU8 = evtData->isPassed("L1_TAU8_EMPTY");
1826 bool isJ10 = evtData->isPassed("L1_J10_EMPTY");
1827
1828 E_LAr_tot.Fill(eventEnergy_LAr[id]);
1829 nCellsPS_tot.Fill(eventCells_PS[id]);
1830 if(isEM5){
1831 E_LAr_EM5_tot.Fill(eventEnergy_LAr[id]);
1832 nCellsPS_EM5_tot.Fill(eventCells_PS[id]);
1833 }
1834 if(isTAU8){
1835 E_LAr_TAU8_tot.Fill(eventEnergy_LAr[id]);
1836 nCellsPS_TAU8_tot.Fill(eventCells_PS[id]);
1837 }
1838 if(isJ10){
1839 E_LAr_J10_tot.Fill(eventEnergy_LAr[id]);
1840 nCellsPS_J10_tot.Fill(eventCells_PS[id]);
1841 }
1842
1843 double ratio = 0;
1844 if((eventEnergy_LAr[id])!=0)
1845 ratio = eventEnergy_PS[id]/(eventEnergy_LAr[id]);
1846 bool isL2_PreS = false;
1847 if(ratio > fractionInPS) isL2_PreS = true;
1848
1849 if(isL2_PreS){
1850 E_LAr_pass.Fill(eventEnergy_LAr[id]);
1851 nCellsPS_pass.Fill(eventCells_PS[id]);
1852 if(isEM5){
1853 E_LAr_EM5_pass.Fill(eventEnergy_LAr[id]);
1854 nCellsPS_EM5_pass.Fill(eventCells_PS[id]);
1855 }
1856 if(isTAU8){
1857 E_LAr_TAU8_pass.Fill(eventEnergy_LAr[id]);
1858 nCellsPS_TAU8_pass.Fill(eventCells_PS[id]);
1859 }
1860 if(isJ10){
1861 E_LAr_J10_pass.Fill(eventEnergy_LAr[id]);
1862 nCellsPS_J10_pass.Fill(eventCells_PS[id]);
1863 }
1864 }
1865 }
1866
1867 char fname[50]{};
1868 sprintf(fname,"TriggerEfficiency_%d.root",run);
1869 auto mfile = std::make_unique<TFile>(fname,"recreate");
1870 E_LAr_pass.Write();
1871 E_LAr_tot.Write();
1872 E_LAr_EM5_pass.Write();
1873 E_LAr_EM5_tot.Write();
1874 E_LAr_TAU8_pass.Write();
1875 E_LAr_TAU8_tot.Write();
1876 E_LAr_J10_pass.Write();
1877 E_LAr_J10_tot.Write();
1878 nCellsPS_pass.Write();
1879 nCellsPS_tot.Write();
1880 nCellsPS_EM5_pass.Write();
1881 nCellsPS_EM5_tot.Write();
1882 nCellsPS_TAU8_pass.Write();
1883 nCellsPS_TAU8_tot.Write();
1884 nCellsPS_J10_pass.Write();
1885 nCellsPS_J10_tot.Write();
1886
1887 mfile->Close();
1888
1889}
1890
1891
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
std::unique_ptr< TProfile > TProfilep
std::vector< std::unique_ptr< T > > THVec
std::unique_ptr< TH2F > TH2Fp
std::unique_ptr< TH1F > TH1Fp
std::array< std::unique_ptr< T >, n > THArray
static Double_t a
static const uint32_t nHits
TGraphErrors * GetEntries(TH2F *histo)
virtual unsigned int nChannels() const
Definition AbsLArCells.h:34
double eta() const
Definition CellInfo.h:93
short slot() const
Definition CellInfo.h:68
short layer() const
Definition CellInfo.h:53
short feedThrough() const
Definition CellInfo.h:65
double phi() const
Definition CellInfo.h:94
ULong64_t onlid() const
Definition CellInfo.h:90
CaloId calo() const
Definition CellInfo.h:50
short channel() const
Definition CellInfo.h:76
bool isPassed(const TString &bitName) const
Definition EventData.cxx:88
static Interface * open(const TString &fileName)
Definition Interface.cxx:35
const EventData * eventData(unsigned int i) const
Definition Interface.h:54
unsigned int nEvents() const
Definition Interface.h:51
unsigned int historySize(unsigned int i) const
Definition Interface.h:57
const History * cellHistory(unsigned int i) const
void SetPartition(bool setpart, const std::string &partname)
void GetLimits_EqLB(const char *inputfile, int &lbmin, int &lbmax, int &emin, int &emax, int &qmin, int &qmax, int &runNumber, const std::vector< int, std::allocator< int > > &BadLBList)
void TriggerEfficiency(const char *inputfile, float fractionInPS=0.8)
void DoEtaPhiMonitoring(const char *inputfile, const char *optionplot, const char *optionsave)
std::unique_ptr< LArIdTranslatorHelper > m_LarIdTranslator
std::vector< int, std::allocator< int > > GetBadLBList(const char *inputfile, int lbmin, int lbmax, double nsigma, int nlb, const std::vector< int, std::allocator< int > > &DQLBList)
bool CheckBadLBList(int lumiBlock, const std::vector< int, std::allocator< int > > &BadLBList)
bool CheckEventSelectionCriteria(int lumiBlock, int nsigma, double energy, Float_t noise, int lbmin, int lbmax)
int CheckCellSelectionCriteria(int EventCount, int nsigmaHits, double MeanHits, double rmsHits, int nEvents_E_gt_ecut, double EventEnergySum, int nBadLBs, int nlb) const
void GetMeanCellHits(const char *inputfile, int nlb, int lbmin, int lbmax, int nsigma, const std::vector< int, std::allocator< int > > &BadLBList, double &MeanHits, double &rmsHits, int &nlb_corr)
void ReadDefectLBList(bool ReadList, const TString &LBfile)
std::vector< int, std::allocator< int > > ReadBadLBList(const TString &LBfile)
int lb
Definition globals.cxx:23
int ev
Definition globals.cxx:25
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
double xmax
Definition listroot.cxx:61
static TFile * fout
Definition listroot.cxx:40
double xmin
Definition listroot.cxx:60
Definition index.py:1
Definition run.py:1
STL namespace.