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 //________________________________________________________________________
37 //#include "TCanvas.h"
46 #include "AliRawReader.h"
47 #include "AliCaloRawStreamV3.h"
50 #include "AliCaloCalibPedestal.h"
52 ClassImp(AliCaloCalibPedestal)
56 // ctor; initialize everything in order to avoid compiler warnings
57 AliCaloCalibPedestal::AliCaloCalibPedestal(kDetType detectorType) :
61 fPedestalRMSLowGain(),
62 fPedestalRMSHighGain(),
63 fPeakMinusPedLowGain(),
64 fPeakMinusPedHighGain(),
65 fPeakMinusPedHighGainHisto(),
66 fPedestalLowGainDiff(),
67 fPedestalHighGainDiff(),
68 fPeakMinusPedLowGainDiff(),
69 fPeakMinusPedHighGainDiff(),
70 fPedestalLowGainRatio(),
71 fPedestalHighGainRatio(),
72 fPeakMinusPedLowGainRatio(),
73 fPeakMinusPedHighGainRatio(),
79 fResurrectedTowers(0),
91 fSelectPedestalSamples(kTRUE),
92 fFirstPedestalSample(0),
93 fLastPedestalSample(15),
95 fWarningThreshold(50),
96 fWarningFraction(0.002),
99 //Default constructor. First we set the detector-type related constants.
100 if (detectorType == kPhos) {
101 fColumns = fgkPhosCols;
103 fModules = fgkPhosModules;
104 fCaloString = "PHOS";
110 //We'll just trust the enum to keep everything in line, so that if detectorType
111 //isn't kPhos then it is kEmCal. Note, however, that this is not necessarily the
112 //case, if someone intentionally gives another number
113 fColumns = AliEMCALGeoParams::fgkEMCALCols;
114 fRows = AliEMCALGeoParams::fgkEMCALRows;
115 fModules = AliEMCALGeoParams::fgkEMCALModules;
116 fCaloString = "EMCAL";
121 fDetType = detectorType;
123 //Then, loop for the requested number of modules
125 for (int i = 0; i < fModules; i++) {
126 //Pedestals, low gain
127 name = "hPedlowgain";
129 title = "Pedestals, low gain, module ";
131 fPedestalLowGain.Add(new TProfile2D(name, title,
132 fColumns, 0.0, fColumns,
133 fRows, fRowMin, fRowMax,"s"));
135 //Pedestals, high gain
136 name = "hPedhighgain";
138 title = "Pedestals, high gain, module ";
140 fPedestalHighGain.Add(new TProfile2D(name, title,
141 fColumns, 0.0, fColumns,
142 fRows, fRowMin, fRowMax,"s"));
143 //All Samples, low gain
144 name = "hPedestalRMSlowgain";
146 title = "Pedestal RMS, low gain, module ";
148 fPedestalRMSLowGain.Add(new TProfile2D(name, title,
149 fColumns, 0.0, fColumns,
150 fRows, fRowMin, fRowMax,"s"));
152 //All Samples, high gain
153 name = "hPedestalRMShighgain";
155 title = "Pedestal RMS, high gain, module ";
157 fPedestalRMSHighGain.Add(new TProfile2D(name, title,
158 fColumns, 0.0, fColumns,
159 fRows, fRowMin, fRowMax,"s"));
161 //Peak-Pedestals, low gain
162 name = "hPeakMinusPedlowgain";
164 title = "Peak-Pedestal, low gain, module ";
166 fPeakMinusPedLowGain.Add(new TProfile2D(name, title,
167 fColumns, 0.0, fColumns,
168 fRows, fRowMin, fRowMax,"s"));
170 //Peak-Pedestals, high gain
171 name = "hPeakMinusPedhighgain";
173 title = "Peak-Pedestal, high gain, module ";
175 fPeakMinusPedHighGain.Add(new TProfile2D(name, title,
176 fColumns, 0.0, fColumns,
177 fRows, fRowMin, fRowMax,"s"));
179 //Peak-Pedestals, high gain - TH2F histo
180 name = "hPeakMinusPedhighgainHisto";
182 title = "Peak-Pedestal, high gain, module ";
184 fPeakMinusPedHighGainHisto.Add(new TH2F(name, title,
185 fColumns*fRows, 0.0, fColumns*fRows,
190 title = "Dead map, module ";
192 fDeadMap.Add(new TH2D(name, title, fColumns, 0.0, fColumns,
193 fRows, fRowMin, fRowMax));
195 }//end for nModules create the histograms
197 //Compress the arrays, in order to remove the empty objects (a 16 slot array is created by default)
198 fPedestalLowGain.Compress();
199 fPedestalHighGain.Compress();
200 fPedestalRMSLowGain.Compress();
201 fPedestalRMSHighGain.Compress();
202 fPeakMinusPedLowGain.Compress();
203 fPeakMinusPedHighGain.Compress();
204 fPeakMinusPedHighGainHisto.Compress();
206 //Make them the owners of the profiles, so we don't need to care about deleting them
207 //fPedestalLowGain.SetOwner();
208 //fPedestalHighGain.SetOwner();
209 //fPeakMinusPedLowGain.SetOwner();
210 //fPeakMinusPedHighGain.SetOwner();
215 //_____________________________________________________________________
216 AliCaloCalibPedestal::~AliCaloCalibPedestal()
218 if (fReference) delete fReference;//Delete the reference object, if it has been loaded
219 //TObjArray will delete the histos/profiles when it is deleted.
223 //_____________________________________________________________________
224 AliCaloCalibPedestal::AliCaloCalibPedestal(const AliCaloCalibPedestal &ped) :
228 fPedestalRMSLowGain(),
229 fPedestalRMSHighGain(),
230 fPeakMinusPedLowGain(),
231 fPeakMinusPedHighGain(),
232 fPeakMinusPedHighGainHisto(),
233 fPedestalLowGainDiff(),
234 fPedestalHighGainDiff(),
235 fPeakMinusPedLowGainDiff(),
236 fPeakMinusPedHighGainDiff(),
237 fPedestalLowGainRatio(),
238 fPedestalHighGainRatio(),
239 fPeakMinusPedLowGainRatio(),
240 fPeakMinusPedHighGainRatio(),
242 fNEvents(ped.GetNEvents()),
243 fNChanFills(ped.GetNChanFills()),
244 fDeadTowers(ped.GetDeadTowerCount()),
245 fNewDeadTowers(ped.GetDeadTowerNew()),
246 fResurrectedTowers(ped.GetDeadTowerResurrected()),
247 fReference( 0 ), //! note that we do not try to copy the reference info here
248 fDetType(ped.GetDetectorType()),
249 fColumns(ped.GetColumns()),
250 fRows(ped.GetRows()),
251 fModules(ped.GetModules()),
252 fRowMin(ped.GetRowMin()),
253 fRowMax(ped.GetRowMax()),
254 fRowMultiplier(ped.GetRowMultiplier()),
255 fCaloString(ped.GetCaloString()),
256 fMapping(NULL), //! note that we are not copying the map info
257 fRunNumber(ped.GetRunNumber()),
258 fSelectPedestalSamples(ped.GetSelectPedestalSamples()),
259 fFirstPedestalSample(ped.GetFirstPedestalSample()),
260 fLastPedestalSample(ped.GetLastPedestalSample()),
261 fDeadThreshold(ped.GetDeadThreshold()),
262 fWarningThreshold(ped.GetWarningThreshold()),
263 fWarningFraction(ped.GetWarningFraction()),
264 fHotSigma(ped.GetHotSigma())
266 // Then the ObjArray ones; we add the histograms rather than trying TObjArray = assignment
267 //DS: this has not really been tested yet..
268 for (int i = 0; i < fModules; i++) {
269 fPedestalLowGain.Add( ped.GetPedProfileLowGain(i) );
270 fPedestalHighGain.Add( ped.GetPedProfileHighGain(i) );
271 fPedestalRMSLowGain.Add( ped.GetPedRMSProfileLowGain(i) );
272 fPedestalRMSHighGain.Add( ped.GetPedRMSProfileHighGain(i) );
273 fPeakMinusPedLowGain.Add( ped.GetPeakProfileLowGain(i) );
274 fPeakMinusPedHighGain.Add( ped.GetPeakProfileHighGain(i) );
275 fPeakMinusPedHighGainHisto.Add( ped.GetPeakHighGainHisto(i) );
277 fDeadMap.Add( ped.GetDeadMap(i) );
280 //Compress the arrays, in order to remove the empty objects (a 16 slot array is created by default)
281 fPedestalLowGain.Compress();
282 fPedestalHighGain.Compress();
283 fPedestalRMSLowGain.Compress();
284 fPedestalRMSHighGain.Compress();
285 fPeakMinusPedLowGain.Compress();
286 fPeakMinusPedHighGain.Compress();
287 fPeakMinusPedHighGainHisto.Compress();
292 // assignment operator; use copy ctor to make life easy..
293 //_____________________________________________________________________
294 AliCaloCalibPedestal& AliCaloCalibPedestal::operator = (const AliCaloCalibPedestal &source)
296 // assignment operator; use copy ctor
297 if (&source == this) return *this;
299 new (this) AliCaloCalibPedestal(source);
303 //_____________________________________________________________________
304 void AliCaloCalibPedestal::Reset()
306 // Reset all arrays/histograms
307 for (int i = 0; i < fModules; i++) {
308 GetPedProfileLowGain(i)->Reset();
309 GetPedProfileHighGain(i)->Reset();
310 GetPeakProfileLowGain(i)->Reset();
311 GetPeakProfileHighGain(i)->Reset();
312 GetPeakHighGainHisto(i)->Reset();
313 GetDeadMap(i)->Reset();
315 if (!fPedestalLowGainDiff.IsEmpty()) {
316 //This means that the comparison profiles have been created.
318 GetPedProfileLowGainDiff(i)->Reset();
319 GetPedProfileHighGainDiff(i)->Reset();
320 GetPeakProfileLowGainDiff(i)->Reset();
321 GetPeakProfileHighGainDiff(i)->Reset();
323 GetPedProfileLowGainRatio(i)->Reset();
324 GetPedProfileHighGainRatio(i)->Reset();
325 GetPeakProfileLowGainRatio(i)->Reset();
326 GetPeakProfileHighGainRatio(i)->Reset();
333 fResurrectedTowers = 0;
335 //To think about: should fReference be deleted too?... let's not do it this time, at least...
338 // Parameter/cut handling
339 //_____________________________________________________________________
340 void AliCaloCalibPedestal::SetParametersFromFile(const char *parameterFile)
342 // Note: this method is a bit more complicated than it really has to be
343 // - allowing for multiple entries per line, arbitrary order of the
344 // different variables etc. But I wanted to try and do this in as
345 // correct a C++ way as I could (as an exercise).
347 static const string delimitor("::");
349 // open, check input file
350 ifstream in( parameterFile );
352 printf("in AliCaloCalibPedestal::SetParametersFromFile - Using default/run_time parameters.\n");
359 while ((in.rdstate() & ios::failbit) == 0 ) {
361 // Read into the raw char array and then construct a string
362 // to do the searching
363 in.getline(readline, 1024);
364 istringstream s(readline);
366 while ( ( s.rdstate() & ios::failbit ) == 0 ) {
371 // check stream status
372 if( s.rdstate() & ios::failbit ) break;
374 // skip rest of line if comments found
375 if( keyValue.substr( 0, 2 ) == "//" ) break;
377 // look for "::" in keyValue pair
378 size_t position = keyValue.find( delimitor );
379 if( position == string::npos ) {
380 printf("wrong format for key::value pair: %s\n", keyValue.c_str());
383 // split keyValue pair
384 string key( keyValue.substr( 0, position ) );
385 string value( keyValue.substr( position+delimitor.size(),
386 keyValue.size()-delimitor.size() ) );
388 // check value does not contain a new delimitor
389 if( value.find( delimitor ) != string::npos ) {
390 printf("wrong format for key::value pair: %s\n", keyValue.c_str());
393 // debug: check key value pair
394 // printf("AliCaloCalibPedestal::SetParametersFromFile - key %s value %s\n", key.c_str(), value.c_str());
396 // if the key matches with something we expect, we assign the new value
397 istringstream iss(value);
398 // the comparison strings defined at the beginning of this method
399 if ( (key == "fFirstPedestalSample") || (key == "fLastPedestalSample") || (key == "fDeadThreshold") || (key == "fWarningThreshold") || (key == "fWarningFraction") || (key == "fHotSigma") ) {
400 printf("AliCaloCalibPedestal::SetParametersFromFile - key %s value %s\n", key.c_str(), value.c_str());
402 if (key == "fFirstPedestalSample") {
403 iss >> fFirstPedestalSample;
405 else if (key == "fLastPedestalSample") {
406 iss >> fLastPedestalSample;
408 else if (key == "fDeadThreshold") {
409 iss >> fDeadThreshold;
411 else if (key == "fWarningThreshold") {
412 iss >> fWarningThreshold;
414 else if (key == "fWarningFraction") {
415 iss >> fWarningFraction;
417 else if (key == "fHotSigma") {
431 //_____________________________________________________________________
432 void AliCaloCalibPedestal::WriteParametersToFile(const char *parameterFile)
434 //Write parameters in file.
436 static const string delimitor("::");
437 ofstream out( parameterFile );
438 out << "// " << parameterFile << endl;
439 out << "fFirstPedestalSample" << "::" << fFirstPedestalSample << endl;
440 out << "fLastPedestalSample" << "::" << fLastPedestalSample << endl;
441 out << "fDeadThreshold" << "::" << fDeadThreshold << endl;
442 out << "fWarningThreshold" << "::" << fWarningThreshold << endl;
443 out << "fWarningFraction" << "::" << fWarningFraction << endl;
444 out << "fHotSigma" << "::" << fHotSigma << endl;
450 //_____________________________________________________________________
451 Bool_t AliCaloCalibPedestal::AddInfo(const AliCaloCalibPedestal *ped)
453 // just do this for the basic histograms/profiles that get filled in ProcessEvent
454 // may not have data for all modules, but let's just Add everything..
455 for (int i = 0; i < fModules; i++) {
456 GetPedProfileLowGain(i)->Add( ped->GetPedProfileLowGain(i) );
457 GetPedProfileHighGain(i)->Add( ped->GetPedProfileHighGain(i) );
458 GetPeakProfileLowGain(i)->Add( ped->GetPeakProfileLowGain(i) );
459 GetPeakProfileHighGain(i)->Add( ped->GetPeakProfileHighGain(i) );
460 GetPeakHighGainHisto(i)->Add( ped->GetPeakHighGainHisto(i) );
464 // DeadMap; Diff profiles etc would need to be redone after this operation
466 return kTRUE;//We succesfully added info from the supplied object
469 //_____________________________________________________________________
470 Bool_t AliCaloCalibPedestal::ProcessEvent(AliRawReader *rawReader)
472 // if fMapping is NULL the rawstream will crate its own mapping
473 AliCaloRawStreamV3 rawStream(rawReader, fCaloString, (AliAltroMapping**)fMapping);
474 if (fDetType == kEmCal) {
475 rawReader->Select("EMCAL", 0, AliEMCALGeoParams::fgkLastAltroDDL) ; //select EMCAL DDL range
477 return ProcessEvent(&rawStream);
480 //_____________________________________________________________________
481 Bool_t AliCaloCalibPedestal::ProcessEvent(AliCaloRawStreamV3 *in)
483 // Method to process=analyze one event in the data stream
484 if (!in) return kFALSE; //Return right away if there's a null pointer
485 fNEvents++; // one more event
487 // indices for the reading
491 int i = 0; // sample counter
494 // start loop over input stream
495 while (in->NextDDL()) {
496 while (in->NextChannel()) {
499 int max = AliEMCALGeoParams::fgkSampleMin, min = AliEMCALGeoParams::fgkSampleMax; // min and max sample values
502 // for the pedestal calculation
503 int sampleSum = 0; // sum of samples
504 int squaredSampleSum = 0; // sum of samples squared
505 int nSum = 0; // number of samples in sum
507 double mean = 0, squaredMean = 0, rms = 0;
509 while (in->NextBunch()) {
510 const UShort_t *sig = in->GetSignals();
511 startBin = in->GetStartTimeBin();
512 nsamples += in->GetBunchLength();
513 for (i = 0; i < in->GetBunchLength(); i++) {
517 // check if it's a min or max value
518 if (sample < min) min = sample;
519 if (sample > max) max = sample;
521 // should we add it for the pedestal calculation?
522 if ( (fFirstPedestalSample<=time && time<=fLastPedestalSample) || // sample time in range
523 !fSelectPedestalSamples ) { // or we don't restrict the sample range.. - then we'll take all
525 squaredSampleSum += sample*sample;
529 } // loop over samples in bunch
530 } // loop over bunches
532 if (nsamples > 0) { // this check is needed for when we have zero-supp. on, but not sparse readout
534 // calculate pedesstal estimate: mean of possibly selected samples
536 mean = sampleSum / (1.0 * nSum);
537 squaredMean = squaredSampleSum / (1.0 * nSum);
538 // The variance (rms squared) is equal to the mean of the squares minus the square of the mean..
539 rms = sqrt(squaredMean - mean*mean);
547 // we're done with the calc. for this channel; let's prepare to fill histo
548 gain = -1; // init to not valid value
549 if ( in->IsLowGain() ) {
552 else if ( in->IsHighGain() ) {
556 // it should be enough to check the SuperModule info for each DDL really, but let's keep it here for now
557 int arrayPos = in->GetModule(); //The modules are numbered starting from 0
558 if (arrayPos >= fModules) {
559 //TODO: return an error message, if appopriate (perhaps if debug>0?)
563 if (arrayPos < 0 || arrayPos >= fModules) {
564 printf("Oh no: arrayPos = %i.\n", arrayPos);
567 fNChanFills++; // one more channel found, and profile to be filled
568 //NOTE: coordinates are (column, row) for the profiles
570 //fill the low gain histograms
571 ((TProfile2D*)fPeakMinusPedLowGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), max - min);
572 if (nSum>0) { // only fill pedestal info in case it could be calculated
573 ((TProfile2D*)fPedestalLowGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), mean);
574 ((TProfile2D*)fPedestalRMSLowGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), rms);
577 else if (gain == 1) {
578 //fill the high gain ones
579 ((TProfile2D*)fPeakMinusPedHighGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), max - min);
580 if (nSum>0) { // only fill pedestal info in case it could be calculated
581 ((TProfile2D*)fPedestalHighGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), mean);
582 ((TProfile2D*)fPedestalRMSHighGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), rms);
584 // for warning checks
585 int idx = in->GetRow() + fRows * in->GetColumn();
586 ((TH2F*)fPeakMinusPedHighGainHisto[arrayPos])->Fill(idx, max - min);
589 } // nsamples>0 check, some data found for this channel; not only trailer/header
590 }// end while over channel
591 }//end while over DDL's, of input stream
593 in->Reset(); // just in case the next customer forgets to check if the stream was reset..
598 //_____________________________________________________________________
599 Bool_t AliCaloCalibPedestal::SaveHistograms(TString fileName, Bool_t saveEmptyHistos)
601 //Saves all the histograms (or profiles, to be accurate) to the designated file
603 TFile destFile(fileName, "recreate");
605 if (destFile.IsZombie()) {
611 for (int i = 0; i < fModules; i++) {
612 if( ((TProfile2D *)fPeakMinusPedLowGain[i])->GetEntries() || saveEmptyHistos) {
613 fPeakMinusPedLowGain[i]->Write();
615 if( ((TProfile2D *)fPeakMinusPedHighGain[i])->GetEntries() || saveEmptyHistos) {
616 fPeakMinusPedHighGain[i]->Write();
618 if( ((TProfile2D *)fPedestalLowGain[i])->GetEntries() || saveEmptyHistos) {
619 fPedestalLowGain[i]->Write();
621 if( ((TProfile2D *)fPedestalHighGain[i])->GetEntries() || saveEmptyHistos) {
622 fPedestalHighGain[i]->Write();
624 if( ((TProfile2D *)fPedestalRMSLowGain[i])->GetEntries() || saveEmptyHistos) {
625 fPedestalRMSLowGain[i]->Write();
627 if( ((TProfile2D *)fPedestalRMSHighGain[i])->GetEntries() || saveEmptyHistos) {
628 fPedestalRMSHighGain[i]->Write();
630 if( ((TH2F *)fPeakMinusPedHighGainHisto[i])->GetEntries() || saveEmptyHistos) {
631 fPeakMinusPedHighGainHisto[i]->Write();
641 //_____________________________________________________________________
642 Bool_t AliCaloCalibPedestal::LoadReferenceCalib(TString fileName, TString objectName)
645 //Make sure that the histograms created when loading the object are not destroyed as the file object is destroyed
646 TH1::AddDirectory(kFALSE);
648 TFile *sourceFile = new TFile(fileName);
649 if (sourceFile->IsZombie()) {
650 return kFALSE;//We couldn't load the reference
653 if (fReference) delete fReference;//Delete the reference object, if it already exists
656 fReference = (AliCaloCalibPedestal*)sourceFile->Get(objectName);
658 if (!fReference || !(fReference->InheritsFrom(AliCaloCalibPedestal::Class())) || (fReference->GetDetectorType() != fDetType)) {
659 if (fReference) delete fReference;//Delete the object, in case we had an object of the wrong type
666 //Reset the histogram ownership behaviour. NOTE: a better workaround would be good, since this may accidentally set AddDirectory to true, even
667 //if we are called by someone who has set it to false...
668 TH1::AddDirectory(kTRUE);
670 return kTRUE;//We succesfully loaded the object
673 //_____________________________________________________________________
674 void AliCaloCalibPedestal::ValidateComparisonProfiles()
676 //Make sure the comparison histos exist
677 if (!fPedestalLowGainDiff.IsEmpty()) return; //The profiles already exist. We just check one, because they're all created at
681 //Then, loop for the requested number of modules
683 for (int i = 0; i < fModules; i++) {
684 //Pedestals, low gain
685 name = "hPedlowgainDiff";
687 title = "Pedestals difference, low gain, module ";
689 fPedestalLowGainDiff.Add(new TProfile2D(name, title,
690 fColumns, 0.0, fColumns,
691 fRows, fRowMin, fRowMax,"s"));
693 //Pedestals, high gain
694 name = "hPedhighgainDiff";
696 title = "Pedestals difference, high gain, module ";
698 fPedestalHighGainDiff.Add(new TProfile2D(name, title,
699 fColumns, 0.0, fColumns,
700 fRows, fRowMin, fRowMax,"s"));
702 //Peak-Pedestals, high gain
703 name = "hPeakMinusPedhighgainDiff";
705 title = "Peak-Pedestal difference, high gain, module ";
707 fPeakMinusPedHighGainDiff.Add(new TProfile2D(name, title,
708 fColumns, 0.0, fColumns,
709 fRows, fRowMin, fRowMax,"s"));
711 //Pedestals, low gain
712 name = "hPedlowgainRatio";
714 title = "Pedestals ratio, low gain, module ";
716 fPedestalLowGainRatio.Add(new TProfile2D(name, title,
717 fColumns, 0.0, fColumns,
718 fRows, fRowMin, fRowMax,"s"));
720 //Pedestals, high gain
721 name = "hPedhighgainRatio";
723 title = "Pedestals ratio, high gain, module ";
725 fPedestalHighGainRatio.Add(new TProfile2D(name, title,
726 fColumns, 0.0, fColumns,
727 fRows, fRowMin, fRowMax,"s"));
729 //Peak-Pedestals, low gain
730 name = "hPeakMinusPedlowgainRatio";
732 title = "Peak-Pedestal ratio, low gain, module ";
734 fPeakMinusPedLowGainRatio.Add(new TProfile2D(name, title,
735 fColumns, 0.0, fColumns,
736 fRows, fRowMin, fRowMax,"s"));
738 //Peak-Pedestals, high gain
739 name = "hPeakMinusPedhighgainRatio";
741 title = "Peak-Pedestal ratio, high gain, module ";
743 fPeakMinusPedHighGainRatio.Add(new TProfile2D(name, title,
744 fColumns, 0.0, fColumns,
745 fRows, fRowMin, fRowMax,"s"));
747 }//end for nModules create the histograms
750 //_____________________________________________________________________
751 void AliCaloCalibPedestal::ComputeDiffAndRatio()
753 // calculate differences and ratios relative to a reference
754 ValidateComparisonProfiles();//Make sure the comparison histos exist
757 return;//Return if the reference object isn't loaded
760 for (int i = 0; i < fModules; i++) {
761 //Compute the ratio of the histograms
763 ((TProfile2D*)fPedestalLowGainRatio[i])->Divide(GetPedProfileLowGain(i), fReference->GetPedProfileLowGain(i), 1.0, 1.0);
764 ((TProfile2D*)fPedestalHighGainRatio[i])->Divide(GetPedProfileHighGain(i), fReference->GetPedProfileHighGain(i), 1.0, 1.0);
765 ((TProfile2D*)fPeakMinusPedLowGainRatio[i])->Divide(GetPeakProfileLowGain(i), fReference->GetPeakProfileLowGain(i), 1.0, 1.0);
766 ((TProfile2D*)fPeakMinusPedHighGainRatio[i])->Divide(GetPeakProfileHighGain(i), fReference->GetPeakProfileHighGain(i), 1.0, 1.0);
768 //For computing the difference, we cannot simply do TProfile2D->Add(), because that subtracts the sum of all entries,
769 //which means that the mean of the new profile will not be the difference of the means. So do it by hand:
770 for (int j = 0; j <= fColumns; j++) {
771 for (int k = 0; k <= fRows; k++) {
772 int bin = ((TProfile2D*)fPeakMinusPedHighGainDiff[i])->GetBin(j+1, k+1);//Note that we assume here that all histos have the same structure...
773 double diff = fReference->GetPeakProfileHighGain(i)->GetBinContent(bin) - GetPeakProfileHighGain(i)->GetBinContent(bin);
774 ((TProfile2D*)fPeakMinusPedHighGainDiff[i])->SetBinContent(j+1, k+1, diff);
775 ((TProfile2D*)fPeakMinusPedHighGainDiff[i])->SetBinEntries(bin, 1);
777 diff = fReference->GetPeakProfileLowGain(i)->GetBinContent(bin) - GetPeakProfileLowGain(i)->GetBinContent(bin);
778 ((TProfile2D*)fPeakMinusPedLowGainDiff[i])->SetBinContent(j+1, k+1, diff);
779 ((TProfile2D*)fPeakMinusPedLowGainDiff[i])->SetBinEntries(bin, 1);
781 diff = fReference->GetPedProfileHighGain(i)->GetBinContent(bin) - GetPedProfileHighGain(i)->GetBinContent(bin);
782 ((TProfile2D*)fPedestalHighGainDiff[i])->SetBinContent(j+1, k+1, diff);
783 ((TProfile2D*)fPedestalHighGainDiff[i])->SetBinEntries(bin, 1);
785 diff = fReference->GetPedProfileLowGain(i)->GetBinContent(bin) - GetPedProfileLowGain(i)->GetBinContent(bin);
786 ((TProfile2D*)fPedestalLowGainDiff[i])->SetBinContent(j+1, k+1, diff);
787 ((TProfile2D*)fPedestalLowGainDiff[i])->SetBinEntries(bin, 1);
796 //_____________________________________________________________________
797 void AliCaloCalibPedestal::ComputeHotAndWarningTowers(const char * hotMapFile)
798 { // look for hot/noisy towers
800 char name[512];//Quite a long temp buffer, just in case the filename includes a path
803 snprintf(name, 512, "%s.txt", hotMapFile);
804 fout = new ofstream(name);
805 if (!fout->is_open()) {
807 fout = 0;//Set the pointer to empty if the file was not opened
811 for(int i = 0; i < fModules; i++){
813 //first we compute the peak-pedestal distribution for each supermodule...
814 if( GetPeakHighGainHisto(i)->GetEntries() > 0 ) {
815 double min = GetPeakProfileHighGain(i)->GetBinContent(GetPeakProfileHighGain(i)->GetMinimumBin());
816 double max = GetPeakProfileHighGain(i)->GetBinContent(GetPeakProfileHighGain(i)->GetMaximumBin());
817 TH1D *hPeakFit = new TH1D(Form("hFit_%d", i), Form("hFit_%d", i), (int)((max-min)*10), min-1, max+1);
819 for (int j = 1; j <= fColumns; j++) {
820 for (int k = 1; k <= fRows; k++) {
821 hPeakFit->Fill(GetPeakProfileHighGain(i)->GetBinContent(j, k));
825 //...and then we fit it
826 hPeakFit->Fit("gaus", "OQ", "", hPeakFit->GetMean() - 3*hPeakFit->GetRMS(),
827 hPeakFit->GetMean() + 3*hPeakFit->GetRMS());
829 double mean = hPeakFit->GetFunction("gaus")->GetParameter(1);
830 double sigma = hPeakFit->GetFunction("gaus")->GetParameter(2);
834 //Then we look for warm/hot towers
835 TH2F * hPeak2D = GetPeakHighGainHisto(i);
836 hPeak2D->GetYaxis()->SetRangeUser( fWarningThreshold, hPeak2D->GetYaxis()->GetBinUpEdge(hPeak2D->GetNbinsY()) );
840 for (int j = 1; j <= fColumns; j++) {
841 for (int k = 1; k <= fRows; k++) {
842 //we start looking for warm/warning towers...
843 // histogram x-axis index
844 idx = k-1 + fRows*(j-1); // this is what is used in the Fill call
845 hPeak2D->GetXaxis()->SetRangeUser(idx, idx);
846 warnCounter = (int) hPeak2D->Integral();
847 if(warnCounter > fNEvents * fWarningFraction) {
848 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kWarning);
849 /* printf("mod %d col %d row %d warnCounter %d - status %d\n",
850 i, j-1, k-1, warnCounter, (int) (kWarning)); */
852 //...then we look for hot ones (towers whose values are greater than mean + X*sigma)
853 if(GetPeakProfileHighGain(i)->GetBinContent(j, k) > mean + fHotSigma*sigma ) {
854 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kHot);
855 /* printf("mod %d col %d row %d binc %d - status %d\n",
856 i, j-1, k-1, (int)(GetPeakProfileHighGain(i)->GetBinContent(j, k)), (int) (kHot)); */
859 //Write the status to the hot/warm map file, if the file is open.
860 // module - column - row - status (1=dead, 2= warm/warning , 3 = hot, see .h file enum)
861 if (fout && ((TH2D*)fDeadMap[i])->GetBinContent(j, k) > 1) {
866 << ((TH2D*)fDeadMap[i])->GetBinContent(j, k) << endl; }
876 //_____________________________________________________________________
877 void AliCaloCalibPedestal::ComputeDeadTowers(const char * deadMapFile)
879 //Computes the number of dead towers etc etc into memory, after this you can call the GetDead... -functions
885 char name[512];//Quite a long temp buffer, just in case the filename includes a path
888 snprintf(name, 512, "%s.txt", deadMapFile);
889 fout = new ofstream(name);
890 snprintf(name, 512, "%sdiff.txt", deadMapFile);
891 diff = new ofstream(name);
892 if (!fout->is_open()) {
894 fout = 0;//Set the pointer to empty if the file was not opened
896 if (!diff->is_open()) {
898 fout = 0;//Set the pointer to empty if the file was not opened
902 for (int i = 0; i < fModules; i++) {
903 if (GetPeakProfileHighGain(i)->GetEntries() > 0) { //don't care about empty histos
904 for (int j = 1; j <= fColumns; j++) {
905 for (int k = 1; k <= fRows; k++) {
907 if (GetPeakProfileHighGain(i)->GetBinContent(j, k) < fDeadThreshold) {//It's dead
908 countTot++;//One more dead total
914 << "0" << endl;//Write the status to the deadmap file, if the file is open.
917 if (fReference && fReference->GetPeakProfileHighGain(i)->GetBinContent(j, k) >= fDeadThreshold) {
918 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kRecentlyDeceased);
919 countNew++;//This tower wasn't dead before!
925 << "0" << endl;//Write the status to the deadmap difference file, if the file is open.
929 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kDead);//This has been dead before. Nothing new
932 else { //It's ALIVE!!
933 //Don't bother with writing the live ones.
934 if (fReference && fReference->GetPeakProfileHighGain(i)->GetBinContent(j, k) < fDeadThreshold) {
935 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kResurrected);
936 countRes++; //This tower was dead before => it's a miracle! :P
942 << "1" << endl;//Write the status to the deadmap difference file, if the file is open.
946 ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kAlive);
952 }//end if GetEntries >= 0
961 fDeadTowers = countTot;
962 fNewDeadTowers = countNew;
963 fResurrectedTowers = countRes;
966 //_____________________________________________________________________
967 Bool_t AliCaloCalibPedestal::IsBadChannel(int imod, int icol, int irow) const
969 //Check if channel is dead or hot.
970 Int_t status = (Int_t) ( ((TH2D*)fDeadMap[imod])->GetBinContent(icol,irow) );
978 //_____________________________________________________________________
979 void AliCaloCalibPedestal::SetChannelStatus(int imod, int icol, int irow, int status)
981 //Set status of channel dead, hot, alive ...
982 ((TH2D*)fDeadMap[imod])->SetBinContent(icol, irow, status);