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) :
57 fPeakMinusPedLowGain(),
58 fPeakMinusPedHighGain(),
59 fPedestalLowGainDiff(),
60 fPedestalHighGainDiff(),
61 fPeakMinusPedLowGainDiff(),
62 fPeakMinusPedHighGainDiff(),
63 fPedestalLowGainRatio(),
64 fPedestalHighGainRatio(),
65 fPeakMinusPedLowGainRatio(),
66 fPeakMinusPedHighGainRatio(),
70 fResurrectedTowers(0),
78 //Default constructor. First we set the detector-type related constants.
79 if (detectorType == kPhos) {
80 fColumns = fgkPhosCols;
82 fModules = fgkPhosModules;
85 //We'll just trust the enum to keep everything in line, so that if detectorType
86 //isn't kPhos then it is kEmCal. Note, however, that this is not necessarily the
87 //case, if someone intentionally gives another number
88 fColumns = fgkEmCalCols;
90 fModules = fgkEmCalModules;
92 fDetType = detectorType;
94 //Then, loop for the requested number of modules
96 for (int i = 0; i < fModules; i++) {
100 title = "Pedestals, low gain, module ";
102 fPedestalLowGain.Add(new TProfile2D(name, title,
103 fColumns, 0.0, fColumns,
104 fRows, -fRows, 0.0));
106 //Pedestals, high gain
107 name = "hPedhighgain";
109 title = "Pedestals, high gain, module ";
111 fPedestalHighGain.Add(new TProfile2D(name, title,
112 fColumns, 0.0, fColumns,
113 fRows, -fRows, 0.0));
115 //Peak-Pedestals, low gain
116 name = "hPeakMinusPedlowgain";
118 title = "Peak-Pedestal, low gain, module ";
120 fPeakMinusPedLowGain.Add(new TProfile2D(name, title,
121 fColumns, 0.0, fColumns,
122 fRows, -fRows, 0.0));
124 //Peak-Pedestals, high gain
125 name = "hPeakMinusPedhighgain";
127 title = "Peak-Pedestal, high gain, module ";
129 fPeakMinusPedHighGain.Add(new TProfile2D(name, title,
130 fColumns, 0.0, fColumns,
131 fRows, -fRows, 0.0));
135 title = "Dead map, module ";
137 fDeadMap.Add(new TH2D(name, title, fColumns, 0.0, fColumns,
138 fRows, -fRows, 0.0));
140 }//end for nModules create the histograms
142 //Compress the arrays, in order to remove the empty objects (a 16 slot array is created by default)
143 fPedestalLowGain.Compress();
144 fPedestalHighGain.Compress();
145 fPeakMinusPedLowGain.Compress();
146 fPeakMinusPedHighGain.Compress();
148 //Make them the owners of the profiles, so we don't need to care about deleting them
149 //fPedestalLowGain.SetOwner();
150 //fPedestalHighGain.SetOwner();
151 //fPeakMinusPedLowGain.SetOwner();
152 //fPeakMinusPedHighGain.SetOwner();
157 //_____________________________________________________________________
158 AliCaloCalibPedestal::~AliCaloCalibPedestal()
160 if (fReference) delete fReference;//Delete the reference object, if it has been loaded
161 //TObjArray will delete the histos/profiles when it is deleted.
165 //_____________________________________________________________________
166 AliCaloCalibPedestal::AliCaloCalibPedestal(const AliCaloCalibPedestal &ped) :
170 fPeakMinusPedLowGain(),
171 fPeakMinusPedHighGain(),
172 fPedestalLowGainDiff(),
173 fPedestalHighGainDiff(),
174 fPeakMinusPedLowGainDiff(),
175 fPeakMinusPedHighGainDiff(),
176 fPedestalLowGainRatio(),
177 fPedestalHighGainRatio(),
178 fPeakMinusPedLowGainRatio(),
179 fPeakMinusPedHighGainRatio(),
181 fDeadTowers(ped.GetDeadTowerCount()),
182 fNewDeadTowers(ped.GetDeadTowerNew()),
183 fResurrectedTowers(ped.GetDeadTowerResurrected()),
184 fReference( 0 ), //! note that we do not try to copy the reference info here
185 fDetType(ped.GetDetectorType()),
186 fColumns(ped.GetColumns()),
187 fRows(ped.GetRows()),
188 fModules(ped.GetModules()),
189 fRunNumber(ped.GetRunNumber())
191 // Then the ObjArray ones; we add the histograms rather than trying TObjArray = assignment
192 //DS: this has not really been tested yet..
193 for (int i = 0; i < fModules; i++) {
194 fPedestalLowGain.Add( ped.GetPedProfileLowGain(i) );
195 fPedestalHighGain.Add( ped.GetPedProfileHighGain(i) );
196 fPeakMinusPedLowGain.Add( ped.GetPeakProfileLowGain(i) );
197 fPeakMinusPedHighGain.Add( ped.GetPeakProfileHighGain(i) );
199 fDeadMap.Add( ped.GetDeadMap(i) );
202 //Compress the arrays, in order to remove the empty objects (a 16 slot array is created by default)
203 fPedestalLowGain.Compress();
204 fPedestalHighGain.Compress();
205 fPeakMinusPedLowGain.Compress();
206 fPeakMinusPedHighGain.Compress();
210 // assignment operator; use copy ctor to make life easy..
211 //_____________________________________________________________________
212 AliCaloCalibPedestal& AliCaloCalibPedestal::operator = (const AliCaloCalibPedestal &source)
214 // assignment operator; use copy ctor
215 if (&source == this) return *this;
217 new (this) AliCaloCalibPedestal(source);
221 //_____________________________________________________________________
222 void AliCaloCalibPedestal::Reset()
224 // Reset all arrays/histograms
225 for (int i = 0; i < fModules; i++) {
226 GetPedProfileLowGain(i)->Reset();
227 GetPedProfileHighGain(i)->Reset();
228 GetPeakProfileLowGain(i)->Reset();
229 GetPeakProfileHighGain(i)->Reset();
230 GetDeadMap(i)->Reset();
232 if (!fPedestalLowGainDiff.IsEmpty()) {
233 //This means that the comparison profiles have been created.
235 GetPedProfileLowGainDiff(i)->Reset();
236 GetPedProfileHighGainDiff(i)->Reset();
237 GetPeakProfileLowGainDiff(i)->Reset();
238 GetPeakProfileHighGainDiff(i)->Reset();
240 GetPedProfileLowGainRatio(i)->Reset();
241 GetPedProfileHighGainRatio(i)->Reset();
242 GetPeakProfileLowGainRatio(i)->Reset();
243 GetPeakProfileHighGainRatio(i)->Reset();
248 fResurrectedTowers = 0;
250 //To think about: should fReference be deleted too?... let's not do it this time, at least...
253 //_____________________________________________________________________
254 Bool_t AliCaloCalibPedestal::ProcessEvent(AliCaloRawStream *in)
256 // Method to process=analyze one event in the data stream
257 if (!in) return kFALSE; //Return right away if there's a null pointer
259 in->SetOldRCUFormat(kTRUE);
261 int sample, i = 0; //The sample temp, and the sample number in current event.
262 int max = fgkSampleMin, min = fgkSampleMax;//Use these for picking the pedestal
266 sample = in->GetSignal(); //Get the adc signal
267 if (sample < min) min = sample;
268 if (sample > max) max = sample;
270 if ( i >= in->GetTimeLength()) {
271 //If we're here then we're done with this tower
272 gain = 1 - in->IsLowGain();
274 int arrayPos = in->GetModule(); //The modules are numbered starting from 0
275 if (arrayPos >= fModules) {
276 //TODO: return an error message, if appopriate (perhaps if debug>0?)
281 if (arrayPos < 0 || arrayPos >= fModules) {
282 printf("Oh no: arrayPos = %i.\n", arrayPos);
285 //NOTE: coordinates are (column, row) for the profiles
287 //fill the low gain histograms
288 ((TProfile2D*)fPedestalLowGain[arrayPos])->Fill(in->GetColumn(), -in->GetRow() - 1, min);
289 ((TProfile2D*)fPeakMinusPedLowGain[arrayPos])->Fill(in->GetColumn(), -in->GetRow() - 1, max - min);
291 else {//fill the high gain ones
292 ((TProfile2D*)fPedestalHighGain[arrayPos])->Fill(in->GetColumn(), -in->GetRow() - 1, min);
293 ((TProfile2D*)fPeakMinusPedHighGain[arrayPos])->Fill(in->GetColumn(), -in->GetRow() - 1, max - min);
296 max = fgkSampleMin; min = fgkSampleMax;
299 }//End if end of tower
301 }//end while, of stream
306 //_____________________________________________________________________
307 Bool_t AliCaloCalibPedestal::SaveHistograms(TString fileName, Bool_t saveEmptyHistos)
309 //Saves all the histograms (or profiles, to be accurate) to the designated file
311 TFile destFile(fileName, "recreate");
313 if (destFile.IsZombie()) {
319 for (int i = 0; i < fModules; i++) {
320 if( ((TProfile2D *)fPeakMinusPedLowGain[i])->GetEntries() || saveEmptyHistos) {
321 fPeakMinusPedLowGain[i]->Write();
323 if( ((TProfile2D *)fPeakMinusPedHighGain[i])->GetEntries() || saveEmptyHistos) {
324 fPeakMinusPedHighGain[i]->Write();
326 if( ((TProfile2D *)fPedestalLowGain[i])->GetEntries() || saveEmptyHistos) {
327 fPedestalLowGain[i]->Write();
329 if( ((TProfile2D *)fPedestalHighGain[i])->GetEntries() || saveEmptyHistos) {
330 fPedestalHighGain[i]->Write();
339 //_____________________________________________________________________
340 Bool_t AliCaloCalibPedestal::LoadReferenceCalib(TString fileName, TString objectName)
343 //Make sure that the histograms created when loading the object are not destroyed as the file object is destroyed
344 TH1::AddDirectory(kFALSE);
346 TFile *sourceFile = new TFile(fileName);
347 if (sourceFile->IsZombie()) {
348 return kFALSE;//We couldn't load the reference
351 if (fReference) delete fReference;//Delete the reference object, if it already exists
354 fReference = (AliCaloCalibPedestal*)sourceFile->Get(objectName);
356 if (!fReference || !(fReference->InheritsFrom(AliCaloCalibPedestal::Class())) || (fReference->GetDetectorType() != fDetType)) {
357 if (fReference) delete fReference;//Delete the object, in case we had an object of the wrong type
364 //Reset the histogram ownership behaviour. NOTE: a better workaround would be good, since this may accidentally set AddDirectory to true, even
365 //if we are called by someone who has set it to false...
366 TH1::AddDirectory(kTRUE);
368 return kTRUE;//We succesfully loaded the object
371 //_____________________________________________________________________
372 void AliCaloCalibPedestal::ValidateComparisonProfiles()
374 //Make sure the comparison histos exist
375 if (!fPedestalLowGainDiff.IsEmpty()) return; //The profiles already exist. We just check one, because they're all created at
379 //Then, loop for the requested number of modules
381 for (int i = 0; i < fModules; i++) {
382 //Pedestals, low gain
383 name = "hPedlowgainDiff";
385 title = "Pedestals difference, low gain, module ";
387 fPedestalLowGainDiff.Add(new TProfile2D(name, title,
388 fColumns, 0.0, fColumns,
389 fRows, -fRows, 0.0));
391 //Pedestals, high gain
392 name = "hPedhighgainDiff";
394 title = "Pedestals difference, high gain, module ";
396 fPedestalHighGainDiff.Add(new TProfile2D(name, title,
397 fColumns, 0.0, fColumns,
398 fRows, -fRows, 0.0));
400 //Peak-Pedestals, low gain
401 name = "hPeakMinusPedlowgainDiff";
403 title = "Peak-Pedestal difference, low gain, module ";
405 fPeakMinusPedLowGainDiff.Add(new TProfile2D(name, title,
406 fColumns, 0.0, fColumns,
407 fRows, -fRows, 0.0));
409 //Peak-Pedestals, high gain
410 name = "hPeakMinusPedhighgainDiff";
412 title = "Peak-Pedestal difference, high gain, module ";
414 fPeakMinusPedHighGainDiff.Add(new TProfile2D(name, title,
415 fColumns, 0.0, fColumns,
416 fRows, -fRows, 0.0));
418 //Pedestals, low gain
419 name = "hPedlowgainRatio";
421 title = "Pedestals ratio, low gain, module ";
423 fPedestalLowGainRatio.Add(new TProfile2D(name, title,
424 fColumns, 0.0, fColumns,
425 fRows, -fRows, 0.0));
427 //Pedestals, high gain
428 name = "hPedhighgainRatio";
430 title = "Pedestals ratio, high gain, module ";
432 fPedestalHighGainRatio.Add(new TProfile2D(name, title,
433 fColumns, 0.0, fColumns,
434 fRows, -fRows, 0.0));
436 //Peak-Pedestals, low gain
437 name = "hPeakMinusPedlowgainRatio";
439 title = "Peak-Pedestal ratio, low gain, module ";
441 fPeakMinusPedLowGainRatio.Add(new TProfile2D(name, title,
442 fColumns, 0.0, fColumns,
443 fRows, -fRows, 0.0));
445 //Peak-Pedestals, high gain
446 name = "hPeakMinusPedhighgainRatio";
448 title = "Peak-Pedestal ratio, high gain, module ";
450 fPeakMinusPedHighGainRatio.Add(new TProfile2D(name, title,
451 fColumns, 0.0, fColumns,
452 fRows, -fRows, 0.0));
454 }//end for nModules create the histograms
457 //_____________________________________________________________________
458 void AliCaloCalibPedestal::ComputeDiffAndRatio()
460 // calculate differences and ratios relative to a reference
461 ValidateComparisonProfiles();//Make sure the comparison histos exist
464 return;//Return if the reference object isn't loaded
467 for (int i = 0; i < fModules; i++) {
468 //Compute the ratio of the histograms
470 ((TProfile2D*)fPedestalLowGainRatio[i])->Divide(GetPedProfileLowGain(i), fReference->GetPedProfileLowGain(i), 1.0, 1.0);
471 ((TProfile2D*)fPedestalHighGainRatio[i])->Divide(GetPedProfileHighGain(i), fReference->GetPedProfileHighGain(i), 1.0, 1.0);
472 ((TProfile2D*)fPeakMinusPedLowGainRatio[i])->Divide(GetPeakProfileLowGain(i), fReference->GetPeakProfileLowGain(i), 1.0, 1.0);
473 ((TProfile2D*)fPeakMinusPedHighGainRatio[i])->Divide(GetPeakProfileHighGain(i), fReference->GetPeakProfileHighGain(i), 1.0, 1.0);
475 //For computing the difference, we cannot simply do TProfile2D->Add(), because that subtracts the sum of all entries,
476 //which means that the mean of the new profile will not be the difference of the means. So do it by hand:
477 for (int j = 0; j <= fColumns; j++) {
478 for (int k = 0; k <= fRows; k++) {
479 int bin = ((TProfile2D*)fPeakMinusPedHighGainDiff[i])->GetBin(j+1, k+1);//Note that we assume here that all histos have the same structure...
480 double diff = fReference->GetPeakProfileHighGain(i)->GetBinContent(bin) - GetPeakProfileHighGain(i)->GetBinContent(bin);
481 ((TProfile2D*)fPeakMinusPedHighGainDiff[i])->SetBinContent(j+1, k+1, diff);
482 ((TProfile2D*)fPeakMinusPedHighGainDiff[i])->SetBinEntries(bin, 1);
484 diff = fReference->GetPeakProfileLowGain(i)->GetBinContent(bin) - GetPeakProfileLowGain(i)->GetBinContent(bin);
485 ((TProfile2D*)fPeakMinusPedLowGainDiff[i])->SetBinContent(j+1, k+1, diff);
486 ((TProfile2D*)fPeakMinusPedLowGainDiff[i])->SetBinEntries(bin, 1);
488 diff = fReference->GetPedProfileHighGain(i)->GetBinContent(bin) - GetPedProfileHighGain(i)->GetBinContent(bin);
489 ((TProfile2D*)fPedestalHighGainDiff[i])->SetBinContent(j+1, k+1, diff);
490 ((TProfile2D*)fPedestalHighGainDiff[i])->SetBinEntries(bin, 1);
492 diff = fReference->GetPedProfileLowGain(i)->GetBinContent(bin) - GetPedProfileLowGain(i)->GetBinContent(bin);
493 ((TProfile2D*)fPedestalLowGainDiff[i])->SetBinContent(j+1, k+1, diff);
494 ((TProfile2D*)fPedestalLowGainDiff[i])->SetBinEntries(bin, 1);
503 //_____________________________________________________________________
504 void AliCaloCalibPedestal::ComputeDeadTowers(int threshold, const char * deadMapFile)
506 //Computes the number of dead towers etc etc into memory, after this you can call the GetDead... -functions
512 char name[512];//Quite a long temp buffer, just in case the filename includes a path
515 snprintf(name, 512, "%s.txt", deadMapFile);
516 fout = new ofstream(name);
517 snprintf(name, 512, "%sdiff.txt", deadMapFile);
518 diff = new ofstream(name);
519 if (!fout->is_open()) {
521 fout = 0;//Set the pointer to empty if the file was not opened
523 if (!diff->is_open()) {
525 fout = 0;//Set the pointer to empty if the file was not opened
529 for (int i = 0; i < fModules; i++) {
530 if (GetPeakProfileHighGain(i)->GetEntries() > 0) { //don't care about empty histos
531 for (int j = 1; j <= fColumns; j++) {
532 for (int k = 1; k <= fRows; k++) {
534 if (GetPeakProfileHighGain(i)->GetBinContent(j, k) < threshold) {//It's dead
535 countTot++;//One more dead total
538 << (fRows - k) << " "
541 << "0" << endl;//Write the status to the deadmap file, if the file is open.
544 if (fReference && fReference->GetPeakProfileHighGain(i)->GetBinContent(j, k) >= threshold) {
545 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kRecentlyDeceased);
546 countNew++;//This tower wasn't dead before!
549 << (fRows - k) << " "
552 << "0" << endl;//Write the status to the deadmap difference file, if the file is open.
556 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kDead);//This has been dead before. Nothing new
559 else { //It's ALIVE!!
560 //Don't bother with writing the live ones.
562 // (*fout) << i << " "
563 // << (fRows - k) << " "
566 // << "1" << endl;//Write the status to the deadmap file, if the file is open.
567 if (fReference && fReference->GetPeakProfileHighGain(i)->GetBinContent(j, k) < threshold) {
568 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kResurrected);
569 countRes++; //This tower was dead before => it's a miracle! :P
572 << (fRows - k) << " "
575 << "1" << endl;//Write the status to the deadmap difference file, if the file is open.
579 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kAlive);
585 }//end if GetEntries >= 0
594 fDeadTowers = countTot;
595 fNewDeadTowers = countNew;
596 fResurrectedTowers = countRes;