1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 //________________________________________________________________________
19 // A help class for monitoring and calibration tools: MOOD, AMORE etc.,
20 // It can be created and used a la (ctor):
22 //Create the object for making the histograms
23 fPedestals = new AliCaloCalibPedestal( fDetType );
24 // AliCaloCalibPedestal knows how many modules we have for PHOS or EMCAL
25 fNumModules = fPedestals->GetModules();
28 // fPedestals->ProcessEvent(fCaloRawStream);
29 // asked to draw histograms:
30 // fPedestals->GetDeadMap(i)->Draw("col");
32 // fPedestals->GetPeakProfileHighGainRatio((i < fNumModules) ? i : fVisibleModule)->Draw("colz");
34 // The pseudo-code examples above were from the first implementation in MOOD (summer 2007).
35 //________________________________________________________________________
43 #include "AliCaloRawStream.h"
46 #include "AliCaloCalibPedestal.h"
48 ClassImp(AliCaloCalibPedestal)
52 // ctor; initialize everything in order to avoid compiler warnings
53 AliCaloCalibPedestal::AliCaloCalibPedestal(kDetType detectorType) :
59 fPeakMinusPedLowGain(),
60 fPeakMinusPedHighGain(),
61 fPedestalLowGainDiff(),
62 fPedestalHighGainDiff(),
63 fPeakMinusPedLowGainDiff(),
64 fPeakMinusPedHighGainDiff(),
65 fPedestalLowGainRatio(),
66 fPedestalHighGainRatio(),
67 fPeakMinusPedLowGainRatio(),
68 fPeakMinusPedHighGainRatio(),
74 fResurrectedTowers(0),
87 //Default constructor. First we set the detector-type related constants.
88 if (detectorType == kPhos) {
89 fColumns = fgkPhosCols;
91 fModules = fgkPhosModules;
98 //We'll just trust the enum to keep everything in line, so that if detectorType
99 //isn't kPhos then it is kEmCal. Note, however, that this is not necessarily the
100 //case, if someone intentionally gives another number
101 fColumns = fgkEmCalCols;
102 fRows = fgkEmCalRows;
103 fModules = fgkEmCalModules;
104 fCaloString = "EMCAL";
109 fDetType = detectorType;
111 //Then, loop for the requested number of modules
113 for (int i = 0; i < fModules; i++) {
114 //Pedestals, low gain
115 name = "hPedlowgain";
117 title = "Pedestals, low gain, module ";
119 fPedestalLowGain.Add(new TProfile2D(name, title,
120 fColumns, 0.0, fColumns,
121 fRows, fRowMin, fRowMax,"s"));
123 //Pedestals, high gain
124 name = "hPedhighgain";
126 title = "Pedestals, high gain, module ";
128 fPedestalHighGain.Add(new TProfile2D(name, title,
129 fColumns, 0.0, fColumns,
130 fRows, fRowMin, fRowMax,"s"));
131 //All Samples, low gain
132 name = "hSamplelowgain";
134 title = "All Samples, low gain, module ";
136 fSampleLowGain.Add(new TProfile2D(name, title,
137 fColumns, 0.0, fColumns,
138 fRows, fRowMin, fRowMax,"s"));
140 //All Samples, high gain
141 name = "hSamplehighgain";
143 title = "All Samples, high gain, module ";
145 fSampleHighGain.Add(new TProfile2D(name, title,
146 fColumns, 0.0, fColumns,
147 fRows, fRowMin, fRowMax,"s"));
149 //Peak-Pedestals, low gain
150 name = "hPeakMinusPedlowgain";
152 title = "Peak-Pedestal, low gain, module ";
154 fPeakMinusPedLowGain.Add(new TProfile2D(name, title,
155 fColumns, 0.0, fColumns,
156 fRows, fRowMin, fRowMax,"s"));
158 //Peak-Pedestals, high gain
159 name = "hPeakMinusPedhighgain";
161 title = "Peak-Pedestal, high gain, module ";
163 fPeakMinusPedHighGain.Add(new TProfile2D(name, title,
164 fColumns, 0.0, fColumns,
165 fRows, fRowMin, fRowMax,"s"));
169 title = "Dead map, module ";
171 fDeadMap.Add(new TH2D(name, title, fColumns, 0.0, fColumns,
172 fRows, fRowMin, fRowMax));
174 }//end for nModules create the histograms
176 //Compress the arrays, in order to remove the empty objects (a 16 slot array is created by default)
177 fPedestalLowGain.Compress();
178 fPedestalHighGain.Compress();
179 fSampleLowGain.Compress();
180 fSampleHighGain.Compress();
181 fPeakMinusPedLowGain.Compress();
182 fPeakMinusPedHighGain.Compress();
184 //Make them the owners of the profiles, so we don't need to care about deleting them
185 //fPedestalLowGain.SetOwner();
186 //fPedestalHighGain.SetOwner();
187 //fPeakMinusPedLowGain.SetOwner();
188 //fPeakMinusPedHighGain.SetOwner();
193 //_____________________________________________________________________
194 AliCaloCalibPedestal::~AliCaloCalibPedestal()
196 if (fReference) delete fReference;//Delete the reference object, if it has been loaded
197 //TObjArray will delete the histos/profiles when it is deleted.
201 //_____________________________________________________________________
202 AliCaloCalibPedestal::AliCaloCalibPedestal(const AliCaloCalibPedestal &ped) :
208 fPeakMinusPedLowGain(),
209 fPeakMinusPedHighGain(),
210 fPedestalLowGainDiff(),
211 fPedestalHighGainDiff(),
212 fPeakMinusPedLowGainDiff(),
213 fPeakMinusPedHighGainDiff(),
214 fPedestalLowGainRatio(),
215 fPedestalHighGainRatio(),
216 fPeakMinusPedLowGainRatio(),
217 fPeakMinusPedHighGainRatio(),
219 fNEvents(ped.GetNEvents()),
220 fNChanFills(ped.GetNChanFills()),
221 fDeadTowers(ped.GetDeadTowerCount()),
222 fNewDeadTowers(ped.GetDeadTowerNew()),
223 fResurrectedTowers(ped.GetDeadTowerResurrected()),
224 fReference( 0 ), //! note that we do not try to copy the reference info here
225 fDetType(ped.GetDetectorType()),
226 fColumns(ped.GetColumns()),
227 fRows(ped.GetRows()),
228 fModules(ped.GetModules()),
229 fRowMin(ped.GetRowMin()),
230 fRowMax(ped.GetRowMax()),
231 fRowMultiplier(ped.GetRowMultiplier()),
232 fCaloString(ped.GetCaloString()),
233 fMapping(NULL), //! note that we are not copying the map info
234 fRunNumber(ped.GetRunNumber())
236 // Then the ObjArray ones; we add the histograms rather than trying TObjArray = assignment
237 //DS: this has not really been tested yet..
238 for (int i = 0; i < fModules; i++) {
239 fPedestalLowGain.Add( ped.GetPedProfileLowGain(i) );
240 fPedestalHighGain.Add( ped.GetPedProfileHighGain(i) );
241 fSampleLowGain.Add( ped.GetSampleProfileLowGain(i) );
242 fSampleHighGain.Add( ped.GetSampleProfileHighGain(i) );
243 fPeakMinusPedLowGain.Add( ped.GetPeakProfileLowGain(i) );
244 fPeakMinusPedHighGain.Add( ped.GetPeakProfileHighGain(i) );
246 fDeadMap.Add( ped.GetDeadMap(i) );
249 //Compress the arrays, in order to remove the empty objects (a 16 slot array is created by default)
250 fPedestalLowGain.Compress();
251 fPedestalHighGain.Compress();
252 fSampleLowGain.Compress();
253 fSampleHighGain.Compress();
254 fPeakMinusPedLowGain.Compress();
255 fPeakMinusPedHighGain.Compress();
259 // assignment operator; use copy ctor to make life easy..
260 //_____________________________________________________________________
261 AliCaloCalibPedestal& AliCaloCalibPedestal::operator = (const AliCaloCalibPedestal &source)
263 // assignment operator; use copy ctor
264 if (&source == this) return *this;
266 new (this) AliCaloCalibPedestal(source);
270 //_____________________________________________________________________
271 void AliCaloCalibPedestal::Reset()
273 // Reset all arrays/histograms
274 for (int i = 0; i < fModules; i++) {
275 GetPedProfileLowGain(i)->Reset();
276 GetPedProfileHighGain(i)->Reset();
277 GetPeakProfileLowGain(i)->Reset();
278 GetPeakProfileHighGain(i)->Reset();
279 GetDeadMap(i)->Reset();
281 if (!fPedestalLowGainDiff.IsEmpty()) {
282 //This means that the comparison profiles have been created.
284 GetPedProfileLowGainDiff(i)->Reset();
285 GetPedProfileHighGainDiff(i)->Reset();
286 GetPeakProfileLowGainDiff(i)->Reset();
287 GetPeakProfileHighGainDiff(i)->Reset();
289 GetPedProfileLowGainRatio(i)->Reset();
290 GetPedProfileHighGainRatio(i)->Reset();
291 GetPeakProfileLowGainRatio(i)->Reset();
292 GetPeakProfileHighGainRatio(i)->Reset();
299 fResurrectedTowers = 0;
301 //To think about: should fReference be deleted too?... let's not do it this time, at least...
304 //_____________________________________________________________________
305 Bool_t AliCaloCalibPedestal::AddInfo(const AliCaloCalibPedestal *ped)
307 // just do this for the basic histograms/profiles that get filled in ProcessEvent
308 // may not have data for all modules, but let's just Add everything..
309 for (int i = 0; i < fModules; i++) {
310 GetPedProfileLowGain(i)->Add( ped->GetPedProfileLowGain(i) );
311 GetPedProfileHighGain(i)->Add( ped->GetPedProfileHighGain(i) );
312 GetPeakProfileLowGain(i)->Add( ped->GetPeakProfileLowGain(i) );
313 GetPeakProfileHighGain(i)->Add( ped->GetPeakProfileHighGain(i) );
316 // DeadMap; Diff profiles etc would need to be redone after this operation
318 return kTRUE;//We succesfully added info from the supplied object
321 //_____________________________________________________________________
322 Bool_t AliCaloCalibPedestal::ProcessEvent(AliRawReader *rawReader)
324 // if fMapping is NULL the rawstream will crate its own mapping
325 AliCaloRawStream rawStream(rawReader, fCaloString, (AliAltroMapping**)fMapping);
326 return ProcessEvent(&rawStream);
329 //_____________________________________________________________________
330 Bool_t AliCaloCalibPedestal::ProcessEvent(AliCaloRawStream *in)
332 // Method to process=analyze one event in the data stream
333 if (!in) return kFALSE; //Return right away if there's a null pointer
335 fNEvents++; // one more event
336 int sample, i = 0; //The sample temp, and the sample number in current event.
337 int max = fgkSampleMin, min = fgkSampleMax;//Use these for picking the pedestal
341 sample = in->GetSignal(); //Get the adc signal
342 if (sample < min) min = sample;
343 if (sample > max) max = sample;
345 if ( i >= in->GetTimeLength()) {
346 //If we're here then we're done with this tower
347 gain = -1; // init to not valid value
348 if ( in->IsLowGain() ) {
351 else if ( in->IsHighGain() ) {
355 int arrayPos = in->GetModule(); //The modules are numbered starting from 0
356 if (arrayPos >= fModules) {
357 //TODO: return an error message, if appopriate (perhaps if debug>0?)
362 if (arrayPos < 0 || arrayPos >= fModules) {
363 printf("Oh no: arrayPos = %i.\n", arrayPos);
366 fNChanFills++; // one more channel found, and profile to be filled
367 //NOTE: coordinates are (column, row) for the profiles
369 //fill the low gain histograms
370 ((TProfile2D*)fPedestalLowGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), min);
371 ((TProfile2D*)fPeakMinusPedLowGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), max - min);
372 ((TProfile2D*)fSampleLowGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), sample);
374 else if (gain == 1) {//fill the high gain ones
375 ((TProfile2D*)fPedestalHighGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), min);
376 ((TProfile2D*)fPeakMinusPedHighGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), max - min);
377 ((TProfile2D*)fSampleHighGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), sample);
380 max = fgkSampleMin; min = fgkSampleMax;
383 }//End if end of tower
385 }//end while, of stream
390 //_____________________________________________________________________
391 Bool_t AliCaloCalibPedestal::SaveHistograms(TString fileName, Bool_t saveEmptyHistos)
393 //Saves all the histograms (or profiles, to be accurate) to the designated file
395 TFile destFile(fileName, "recreate");
397 if (destFile.IsZombie()) {
403 for (int i = 0; i < fModules; i++) {
404 if( ((TProfile2D *)fPeakMinusPedLowGain[i])->GetEntries() || saveEmptyHistos) {
405 fPeakMinusPedLowGain[i]->Write();
407 if( ((TProfile2D *)fPeakMinusPedHighGain[i])->GetEntries() || saveEmptyHistos) {
408 fPeakMinusPedHighGain[i]->Write();
410 if( ((TProfile2D *)fPedestalLowGain[i])->GetEntries() || saveEmptyHistos) {
411 fPedestalLowGain[i]->Write();
413 if( ((TProfile2D *)fPedestalHighGain[i])->GetEntries() || saveEmptyHistos) {
414 fPedestalHighGain[i]->Write();
416 if( ((TProfile2D *)fSampleLowGain[i])->GetEntries() || saveEmptyHistos) {
417 fSampleLowGain[i]->Write();
419 if( ((TProfile2D *)fSampleHighGain[i])->GetEntries() || saveEmptyHistos) {
420 fSampleHighGain[i]->Write();
429 //_____________________________________________________________________
430 Bool_t AliCaloCalibPedestal::LoadReferenceCalib(TString fileName, TString objectName)
433 //Make sure that the histograms created when loading the object are not destroyed as the file object is destroyed
434 TH1::AddDirectory(kFALSE);
436 TFile *sourceFile = new TFile(fileName);
437 if (sourceFile->IsZombie()) {
438 return kFALSE;//We couldn't load the reference
441 if (fReference) delete fReference;//Delete the reference object, if it already exists
444 fReference = (AliCaloCalibPedestal*)sourceFile->Get(objectName);
446 if (!fReference || !(fReference->InheritsFrom(AliCaloCalibPedestal::Class())) || (fReference->GetDetectorType() != fDetType)) {
447 if (fReference) delete fReference;//Delete the object, in case we had an object of the wrong type
454 //Reset the histogram ownership behaviour. NOTE: a better workaround would be good, since this may accidentally set AddDirectory to true, even
455 //if we are called by someone who has set it to false...
456 TH1::AddDirectory(kTRUE);
458 return kTRUE;//We succesfully loaded the object
461 //_____________________________________________________________________
462 void AliCaloCalibPedestal::ValidateComparisonProfiles()
464 //Make sure the comparison histos exist
465 if (!fPedestalLowGainDiff.IsEmpty()) return; //The profiles already exist. We just check one, because they're all created at
469 //Then, loop for the requested number of modules
471 for (int i = 0; i < fModules; i++) {
472 //Pedestals, low gain
473 name = "hPedlowgainDiff";
475 title = "Pedestals difference, low gain, module ";
477 fPedestalLowGainDiff.Add(new TProfile2D(name, title,
478 fColumns, 0.0, fColumns,
479 fRows, fRowMin, fRowMax,"s"));
481 //Pedestals, high gain
482 name = "hPedhighgainDiff";
484 title = "Pedestals difference, high gain, module ";
486 fPedestalHighGainDiff.Add(new TProfile2D(name, title,
487 fColumns, 0.0, fColumns,
488 fRows, fRowMin, fRowMax,"s"));
490 //Peak-Pedestals, high gain
491 name = "hPeakMinusPedhighgainDiff";
493 title = "Peak-Pedestal difference, high gain, module ";
495 fPeakMinusPedHighGainDiff.Add(new TProfile2D(name, title,
496 fColumns, 0.0, fColumns,
497 fRows, fRowMin, fRowMax,"s"));
499 //Pedestals, low gain
500 name = "hPedlowgainRatio";
502 title = "Pedestals ratio, low gain, module ";
504 fPedestalLowGainRatio.Add(new TProfile2D(name, title,
505 fColumns, 0.0, fColumns,
506 fRows, fRowMin, fRowMax,"s"));
508 //Pedestals, high gain
509 name = "hPedhighgainRatio";
511 title = "Pedestals ratio, high gain, module ";
513 fPedestalHighGainRatio.Add(new TProfile2D(name, title,
514 fColumns, 0.0, fColumns,
515 fRows, fRowMin, fRowMax,"s"));
517 //Peak-Pedestals, low gain
518 name = "hPeakMinusPedlowgainRatio";
520 title = "Peak-Pedestal ratio, low gain, module ";
522 fPeakMinusPedLowGainRatio.Add(new TProfile2D(name, title,
523 fColumns, 0.0, fColumns,
524 fRows, fRowMin, fRowMax,"s"));
526 //Peak-Pedestals, high gain
527 name = "hPeakMinusPedhighgainRatio";
529 title = "Peak-Pedestal ratio, high gain, module ";
531 fPeakMinusPedHighGainRatio.Add(new TProfile2D(name, title,
532 fColumns, 0.0, fColumns,
533 fRows, fRowMin, fRowMax,"s"));
535 }//end for nModules create the histograms
538 //_____________________________________________________________________
539 void AliCaloCalibPedestal::ComputeDiffAndRatio()
541 // calculate differences and ratios relative to a reference
542 ValidateComparisonProfiles();//Make sure the comparison histos exist
545 return;//Return if the reference object isn't loaded
548 for (int i = 0; i < fModules; i++) {
549 //Compute the ratio of the histograms
551 ((TProfile2D*)fPedestalLowGainRatio[i])->Divide(GetPedProfileLowGain(i), fReference->GetPedProfileLowGain(i), 1.0, 1.0);
552 ((TProfile2D*)fPedestalHighGainRatio[i])->Divide(GetPedProfileHighGain(i), fReference->GetPedProfileHighGain(i), 1.0, 1.0);
553 ((TProfile2D*)fPeakMinusPedLowGainRatio[i])->Divide(GetPeakProfileLowGain(i), fReference->GetPeakProfileLowGain(i), 1.0, 1.0);
554 ((TProfile2D*)fPeakMinusPedHighGainRatio[i])->Divide(GetPeakProfileHighGain(i), fReference->GetPeakProfileHighGain(i), 1.0, 1.0);
556 //For computing the difference, we cannot simply do TProfile2D->Add(), because that subtracts the sum of all entries,
557 //which means that the mean of the new profile will not be the difference of the means. So do it by hand:
558 for (int j = 0; j <= fColumns; j++) {
559 for (int k = 0; k <= fRows; k++) {
560 int bin = ((TProfile2D*)fPeakMinusPedHighGainDiff[i])->GetBin(j+1, k+1);//Note that we assume here that all histos have the same structure...
561 double diff = fReference->GetPeakProfileHighGain(i)->GetBinContent(bin) - GetPeakProfileHighGain(i)->GetBinContent(bin);
562 ((TProfile2D*)fPeakMinusPedHighGainDiff[i])->SetBinContent(j+1, k+1, diff);
563 ((TProfile2D*)fPeakMinusPedHighGainDiff[i])->SetBinEntries(bin, 1);
565 diff = fReference->GetPeakProfileLowGain(i)->GetBinContent(bin) - GetPeakProfileLowGain(i)->GetBinContent(bin);
566 ((TProfile2D*)fPeakMinusPedLowGainDiff[i])->SetBinContent(j+1, k+1, diff);
567 ((TProfile2D*)fPeakMinusPedLowGainDiff[i])->SetBinEntries(bin, 1);
569 diff = fReference->GetPedProfileHighGain(i)->GetBinContent(bin) - GetPedProfileHighGain(i)->GetBinContent(bin);
570 ((TProfile2D*)fPedestalHighGainDiff[i])->SetBinContent(j+1, k+1, diff);
571 ((TProfile2D*)fPedestalHighGainDiff[i])->SetBinEntries(bin, 1);
573 diff = fReference->GetPedProfileLowGain(i)->GetBinContent(bin) - GetPedProfileLowGain(i)->GetBinContent(bin);
574 ((TProfile2D*)fPedestalLowGainDiff[i])->SetBinContent(j+1, k+1, diff);
575 ((TProfile2D*)fPedestalLowGainDiff[i])->SetBinEntries(bin, 1);
584 //_____________________________________________________________________
585 void AliCaloCalibPedestal::ComputeDeadTowers(int threshold, const char * deadMapFile)
587 //Computes the number of dead towers etc etc into memory, after this you can call the GetDead... -functions
593 char name[512];//Quite a long temp buffer, just in case the filename includes a path
596 snprintf(name, 512, "%s.txt", deadMapFile);
597 fout = new ofstream(name);
598 snprintf(name, 512, "%sdiff.txt", deadMapFile);
599 diff = new ofstream(name);
600 if (!fout->is_open()) {
602 fout = 0;//Set the pointer to empty if the file was not opened
604 if (!diff->is_open()) {
606 fout = 0;//Set the pointer to empty if the file was not opened
610 for (int i = 0; i < fModules; i++) {
611 if (GetPeakProfileHighGain(i)->GetEntries() > 0) { //don't care about empty histos
612 for (int j = 1; j <= fColumns; j++) {
613 for (int k = 1; k <= fRows; k++) {
615 if (GetPeakProfileHighGain(i)->GetBinContent(j, k) < threshold) {//It's dead
616 countTot++;//One more dead total
619 << (fRows - k) << " "
622 << "0" << endl;//Write the status to the deadmap file, if the file is open.
625 if (fReference && fReference->GetPeakProfileHighGain(i)->GetBinContent(j, k) >= threshold) {
626 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kRecentlyDeceased);
627 countNew++;//This tower wasn't dead before!
630 << (fRows - k) << " "
633 << "0" << endl;//Write the status to the deadmap difference file, if the file is open.
637 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kDead);//This has been dead before. Nothing new
640 else { //It's ALIVE!!
641 //Don't bother with writing the live ones.
643 // (*fout) << i << " "
644 // << (fRows - k) << " "
647 // << "1" << endl;//Write the status to the deadmap file, if the file is open.
648 if (fReference && fReference->GetPeakProfileHighGain(i)->GetBinContent(j, k) < threshold) {
649 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kResurrected);
650 countRes++; //This tower was dead before => it's a miracle! :P
653 << (fRows - k) << " "
656 << "1" << endl;//Write the status to the deadmap difference file, if the file is open.
660 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kAlive);
666 }//end if GetEntries >= 0
675 fDeadTowers = countTot;
676 fNewDeadTowers = countNew;
677 fResurrectedTowers = countRes;