]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EMCAL/AliCaloCalibPedestal.cxx
- Anti nuclei added
[u/mrichter/AliRoot.git] / EMCAL / AliCaloCalibPedestal.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15 //* $Id$ */
16
17 //________________________________________________________________________
18 //
19 // A help class for monitoring and calibration tools: MOOD, AMORE etc.,
20 // It can be created and used a la (ctor):
21 /*
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();
26 */
27 // fed an event:
28 //  fPedestals->ProcessEvent(fCaloRawStream);
29 // asked to draw histograms:
30 //  fPedestals->GetDeadMap(i)->Draw("col");
31 // or
32 //  fPedestals->GetPeakProfileHighGainRatio((i < fNumModules) ? i : fVisibleModule)->Draw("colz");
33 // etc.
34 // The pseudo-code examples above were from the first implementation in MOOD (summer 2007).
35 //________________________________________________________________________
36
37 //#include "TCanvas.h"
38 #include "TH1.h"
39 #include "TF1.h"
40 #include "TFile.h"
41 #include <fstream>
42 #include <sstream>
43 #include <iostream>
44 #include <stdexcept>
45 #include <cmath>
46
47 #include "AliRawReader.h"
48 #include "AliCaloRawStreamV3.h"
49
50 //The include file
51 #include "AliCaloCalibPedestal.h"
52
53 ClassImp(AliCaloCalibPedestal)
54
55 using namespace std;
56
57 // ctor; initialize everything in order to avoid compiler warnings
58 AliCaloCalibPedestal::AliCaloCalibPedestal(kDetType detectorType) :  
59   TObject(),
60   fPedestalLowGain(),
61   fPedestalHighGain(),
62   fPedestalLEDRefLowGain(),
63   fPedestalLEDRefHighGain(),
64   fPeakMinusPedLowGain(),
65   fPeakMinusPedHighGain(),
66   fPeakMinusPedHighGainHisto(),
67   fPedestalLowGainDiff(),
68   fPedestalHighGainDiff(),
69   fPedestalLEDRefLowGainDiff(),
70   fPedestalLEDRefHighGainDiff(),
71   fPeakMinusPedLowGainDiff(),
72   fPeakMinusPedHighGainDiff(),
73   fPedestalLowGainRatio(),
74   fPedestalHighGainRatio(),
75   fPedestalLEDRefLowGainRatio(),
76   fPedestalLEDRefHighGainRatio(),
77   fPeakMinusPedLowGainRatio(),
78   fPeakMinusPedHighGainRatio(),
79   fDeadMap(),
80   fNEvents(0),
81   fNChanFills(0),
82   fDeadTowers(0),
83   fNewDeadTowers(0),
84   fResurrectedTowers(0),
85   fReference(0),
86   fDetType(kNone),
87   fColumns(0),
88   fRows(0),
89   fLEDRefs(0),
90   fModules(0),
91   fRowMin(0),
92   fRowMax(0),
93   fRowMultiplier(0),
94   fCaloString(),
95   fMapping(NULL),
96   fRunNumber(-1),
97   fSelectPedestalSamples(kTRUE), 
98   fFirstPedestalSample(0),
99   fLastPedestalSample(15),
100   fDeadThreshold(5),
101   fWarningThreshold(50),
102   fWarningFraction(0.002),
103   fHotSigma(5)
104 {
105   //Default constructor. First we set the detector-type related constants.
106   if (detectorType == kPhos) {
107     fColumns = fgkPhosCols;
108     fRows = fgkPhosRows;
109     fLEDRefs = fgkPhosLEDRefs;
110     fModules = fgkPhosModules;
111     fCaloString = "PHOS";
112     fRowMin = -1*fRows;
113     fRowMax = 0;
114     fRowMultiplier = -1;
115   } 
116   else {
117     //We'll just trust the enum to keep everything in line, so that if detectorType
118     //isn't kPhos then it is kEmCal. Note, however, that this is not necessarily the
119     //case, if someone intentionally gives another number
120     fColumns = AliEMCALGeoParams::fgkEMCALCols;
121     fRows = AliEMCALGeoParams::fgkEMCALRows;
122     fLEDRefs = AliEMCALGeoParams::fgkEMCALLEDRefs;
123     fModules = AliEMCALGeoParams::fgkEMCALModules;
124     fCaloString = "EMCAL";
125     fRowMin = 0;
126     fRowMax = fRows;
127     fRowMultiplier = 1;
128   } 
129   fDetType = detectorType;
130  
131   //Then, loop for the requested number of modules
132   TString title, name;
133   for (int i = 0; i < fModules; i++) {
134     //Pedestals, low gain
135     name = "hPedlowgain";
136     name += i;
137     title = "Pedestals, low gain, module ";
138     title += i; 
139     fPedestalLowGain.Add(new TProfile2D(name, title,
140                                         fColumns, 0.0, fColumns, 
141                                         fRows, fRowMin, fRowMax,"s"));
142   
143     //Pedestals, high gain
144     name = "hPedhighgain";
145     name += i;
146     title = "Pedestals, high gain, module ";
147     title += i; 
148     fPedestalHighGain.Add(new TProfile2D(name, title,
149                                          fColumns, 0.0, fColumns, 
150                                          fRows, fRowMin, fRowMax,"s"));
151
152     //LED Ref/Mon pedestals, low gain
153     name = "hPedestalLEDReflowgain";
154     name += i;
155     title = "Pedestal LEDRef, low gain, module ";
156     title += i; 
157     fPedestalLEDRefLowGain.Add(new TProfile(name, title,
158                                             fLEDRefs, 0.0, fLEDRefs, "s"));
159     
160     //LED Ref/Mon pedestals, high gain
161     name = "hPedestalLEDRefhighgain";
162     name += i;
163     title = "Pedestal LEDRef, high gain, module ";
164     title += i; 
165     fPedestalLEDRefHighGain.Add(new TProfile(name, title,
166                                              fLEDRefs, 0.0, fLEDRefs, "s"));
167   
168     //Peak-Pedestals, low gain
169     name = "hPeakMinusPedlowgain";
170     name += i;
171     title = "Peak-Pedestal, low gain, module ";
172     title += i; 
173     fPeakMinusPedLowGain.Add(new TProfile2D(name, title,
174                                             fColumns, 0.0, fColumns, 
175                                             fRows, fRowMin, fRowMax,"s"));
176   
177     //Peak-Pedestals, high gain
178     name = "hPeakMinusPedhighgain";
179     name += i;
180     title = "Peak-Pedestal, high gain, module ";
181     title += i; 
182     fPeakMinusPedHighGain.Add(new TProfile2D(name, title,
183                                              fColumns, 0.0, fColumns, 
184                                              fRows, fRowMin, fRowMax,"s"));
185
186     //Peak-Pedestals, high gain - TH2F histo
187     name = "hPeakMinusPedhighgainHisto";
188     name += i;
189     title = "Peak-Pedestal, high gain, module ";
190     title += i; 
191     fPeakMinusPedHighGainHisto.Add(new TH2F(name, title,
192                                             fColumns*fRows, 0.0, fColumns*fRows, 
193                                             100, 0, 1000));
194  
195     name = "hDeadMap";
196     name += i;
197     title = "Dead map, module ";
198     title += i;
199     fDeadMap.Add(new TH2D(name, title, fColumns, 0.0, fColumns, 
200                           fRows, fRowMin, fRowMax));
201   
202   }//end for nModules create the histograms
203  
204   //Compress the arrays, in order to remove the empty objects (a 16 slot array is created by default)
205   fPedestalLowGain.Compress();
206   fPedestalHighGain.Compress();
207   fPedestalLEDRefLowGain.Compress();
208   fPedestalLEDRefHighGain.Compress();
209   fPeakMinusPedLowGain.Compress();
210   fPeakMinusPedHighGain.Compress();
211   fPeakMinusPedHighGainHisto.Compress();
212   fDeadMap.Compress();
213
214 }
215
216 // dtor
217 //_____________________________________________________________________
218 AliCaloCalibPedestal::~AliCaloCalibPedestal()
219 {
220   if (fReference) delete fReference;//Delete the reference object, if it has been loaded
221   //TObjArray will delete the histos/profiles when it is deleted.
222 }
223
224 // copy ctor
225 //_____________________________________________________________________
226 AliCaloCalibPedestal::AliCaloCalibPedestal(const AliCaloCalibPedestal &ped) :
227   TObject(ped),
228   fPedestalLowGain(),
229   fPedestalHighGain(),
230   fPedestalLEDRefLowGain(),
231   fPedestalLEDRefHighGain(),
232   fPeakMinusPedLowGain(),
233   fPeakMinusPedHighGain(),
234   fPeakMinusPedHighGainHisto(),
235   fPedestalLowGainDiff(),
236   fPedestalHighGainDiff(),
237   fPedestalLEDRefLowGainDiff(),
238   fPedestalLEDRefHighGainDiff(),
239   fPeakMinusPedLowGainDiff(),
240   fPeakMinusPedHighGainDiff(),
241   fPedestalLowGainRatio(),
242   fPedestalHighGainRatio(),
243   fPedestalLEDRefLowGainRatio(),
244   fPedestalLEDRefHighGainRatio(),
245   fPeakMinusPedLowGainRatio(),
246   fPeakMinusPedHighGainRatio(),
247   fDeadMap(),
248   fNEvents(ped.GetNEvents()),
249   fNChanFills(ped.GetNChanFills()),
250   fDeadTowers(ped.GetDeadTowerCount()),
251   fNewDeadTowers(ped.GetDeadTowerNew()),
252   fResurrectedTowers(ped.GetDeadTowerResurrected()),
253   fReference( 0 ), //! note that we do not try to copy the reference info here
254   fDetType(ped.GetDetectorType()),
255   fColumns(ped.GetColumns()),
256   fRows(ped.GetRows()),
257   fLEDRefs(ped.GetLEDRefs()),
258   fModules(ped.GetModules()),
259   fRowMin(ped.GetRowMin()),
260   fRowMax(ped.GetRowMax()),
261   fRowMultiplier(ped.GetRowMultiplier()),
262   fCaloString(ped.GetCaloString()),
263   fMapping(NULL), //! note that we are not copying the map info
264   fRunNumber(ped.GetRunNumber()),
265   fSelectPedestalSamples(ped.GetSelectPedestalSamples()),
266   fFirstPedestalSample(ped.GetFirstPedestalSample()),
267   fLastPedestalSample(ped.GetLastPedestalSample()),
268   fDeadThreshold(ped.GetDeadThreshold()),
269   fWarningThreshold(ped.GetWarningThreshold()),
270   fWarningFraction(ped.GetWarningFraction()),
271   fHotSigma(ped.GetHotSigma())
272 {
273   // Then the ObjArray ones; we add the histograms rather than trying TObjArray = assignment
274   //DS: this has not really been tested yet..
275   for (int i = 0; i < fModules; i++) {
276     fPedestalLowGain.Add( ped.GetPedProfileLowGain(i) );
277     fPedestalHighGain.Add( ped.GetPedProfileHighGain(i) );
278     fPedestalLEDRefLowGain.Add( ped.GetPedLEDRefProfileLowGain(i) );
279     fPedestalLEDRefHighGain.Add( ped.GetPedLEDRefProfileHighGain(i) );
280     fPeakMinusPedLowGain.Add( ped.GetPeakProfileLowGain(i) );
281     fPeakMinusPedHighGain.Add( ped.GetPeakProfileHighGain(i) );
282     fPeakMinusPedHighGainHisto.Add( ped.GetPeakHighGainHisto(i) );
283
284     fDeadMap.Add( ped.GetDeadMap(i) );  
285   }//end for nModules 
286  
287   //Compress the arrays, in order to remove the empty objects (a 16 slot array is created by default)
288   fPedestalLowGain.Compress();
289   fPedestalHighGain.Compress();
290   fPedestalLEDRefLowGain.Compress();
291   fPedestalLEDRefHighGain.Compress();
292   fPeakMinusPedLowGain.Compress();
293   fPeakMinusPedHighGain.Compress();
294   fPeakMinusPedHighGainHisto.Compress();
295
296   fDeadMap.Compress();
297 }
298
299 // assignment operator; use copy ctor to make life easy..
300 //_____________________________________________________________________
301 AliCaloCalibPedestal& AliCaloCalibPedestal::operator = (const AliCaloCalibPedestal &source)
302 {
303   // assignment operator; use copy ctor
304   if (&source == this) return *this;
305
306   new (this) AliCaloCalibPedestal(source);
307   return *this;
308 }
309
310 //_____________________________________________________________________
311 void AliCaloCalibPedestal::Reset()
312 {
313   // Reset all arrays/histograms
314   for (int i = 0; i < fModules; i++) {
315     GetPedProfileLowGain(i)->Reset();
316     GetPedProfileHighGain(i)->Reset();
317     GetPedLEDRefProfileLowGain(i)->Reset();
318     GetPedLEDRefProfileHighGain(i)->Reset();
319     GetPeakProfileLowGain(i)->Reset();
320     GetPeakProfileHighGain(i)->Reset();
321     GetPeakHighGainHisto(i)->Reset();
322     GetDeadMap(i)->Reset();
323     
324     if (!fPedestalLowGainDiff.IsEmpty()) {
325       //This means that the comparison profiles have been created.
326   
327       GetPedProfileLowGainDiff(i)->Reset();
328       GetPedProfileHighGainDiff(i)->Reset();
329       GetPedLEDRefProfileLowGainDiff(i)->Reset();
330       GetPedLEDRefProfileHighGainDiff(i)->Reset();
331       GetPeakProfileLowGainDiff(i)->Reset();
332       GetPeakProfileHighGainDiff(i)->Reset();
333       
334       GetPedProfileLowGainRatio(i)->Reset();
335       GetPedProfileHighGainRatio(i)->Reset();
336       GetPedLEDRefProfileLowGainRatio(i)->Reset();
337       GetPedLEDRefProfileHighGainRatio(i)->Reset();
338       GetPeakProfileLowGainRatio(i)->Reset();
339       GetPeakProfileHighGainRatio(i)->Reset();
340     }
341   }
342   fNEvents = 0;
343   fNChanFills = 0;
344   fDeadTowers = 0;
345   fNewDeadTowers = 0;
346   fResurrectedTowers = 0;
347  
348   //To think about: should fReference be deleted too?... let's not do it this time, at least...
349 }
350
351 // Parameter/cut handling
352 //_____________________________________________________________________
353 void AliCaloCalibPedestal::SetParametersFromFile(const char *parameterFile)
354 {  
355   // Note: this method is a bit more complicated than it really has to be
356   // - allowing for multiple entries per line, arbitrary order of the
357   // different variables etc. But I wanted to try and do this in as
358   // correct a C++ way as I could (as an exercise).
359
360   static const string delimitor("::");
361         
362   // open, check input file
363   ifstream in( parameterFile );
364   if( !in ) {
365     printf("in AliCaloCalibPedestal::SetParametersFromFile - Using default/run_time parameters.\n");
366     return;
367   } 
368
369
370   // read in
371   char readline[1024];
372   while ((in.rdstate() & ios::failbit) == 0 ) {
373     
374     // Read into the raw char array and then construct a string
375     // to do the searching
376     in.getline(readline, 1024);
377     istringstream s(readline);          
378                 
379     while ( ( s.rdstate() & ios::failbit ) == 0 ) {
380                         
381       string keyValue; 
382       s >> keyValue;
383       
384       // check stream status
385       if( s.rdstate() & ios::failbit ) break;
386                         
387       // skip rest of line if comments found
388       if( keyValue.substr( 0, 2 ) == "//" ) break;
389                         
390       // look for "::" in keyValue pair
391       size_t position = keyValue.find( delimitor );
392       if( position == string::npos ) {
393         printf("wrong format for key::value pair: %s\n", keyValue.c_str());
394       }
395                                 
396       // split keyValue pair
397       string key( keyValue.substr( 0, position ) );
398       string value( keyValue.substr( position+delimitor.size(), 
399                                       keyValue.size()-delimitor.size() ) );
400                         
401       // check value does not contain a new delimitor
402       if( value.find( delimitor ) != string::npos ) {
403         printf("wrong format for key::value pair: %s\n", keyValue.c_str());
404       }
405       
406       // debug: check key value pair
407       // printf("AliCaloCalibPedestal::SetParametersFromFile - key %s value %s\n", key.c_str(), value.c_str());
408
409       // if the key matches with something we expect, we assign the new value
410       istringstream iss(value);
411       // the comparison strings defined at the beginning of this method
412       if ( (key == "fFirstPedestalSample") || (key == "fLastPedestalSample") || (key == "fDeadThreshold") || (key == "fWarningThreshold") || (key == "fWarningFraction") || (key == "fHotSigma") ) {
413         printf("AliCaloCalibPedestal::SetParametersFromFile - key %s value %s\n", key.c_str(), value.c_str());
414
415         if (key == "fFirstPedestalSample") { 
416           iss >> fFirstPedestalSample; 
417         }
418         else if (key == "fLastPedestalSample") { 
419           iss >> fLastPedestalSample; 
420         }
421         else if (key == "fDeadThreshold") { 
422           iss >> fDeadThreshold; 
423         }
424         else if (key == "fWarningThreshold") { 
425           iss >> fWarningThreshold; 
426         }
427         else if (key == "fWarningFraction") { 
428           iss >> fWarningFraction; 
429         }
430         else if (key == "fHotSigma") { 
431           iss >> fHotSigma; 
432         }
433
434       } // some match
435
436     }           
437   }
438
439   in.close();
440   return;
441         
442 }
443
444 //_____________________________________________________________________
445 void AliCaloCalibPedestal::WriteParametersToFile(const char *parameterFile)
446 {
447   //Write parameters in file.
448         
449   static const string delimitor("::");
450   ofstream out( parameterFile );
451   out << "// " << parameterFile << endl;
452   out << "fFirstPedestalSample" << "::" << fFirstPedestalSample << endl;
453   out << "fLastPedestalSample" << "::" << fLastPedestalSample << endl;
454   out << "fDeadThreshold" << "::" << fDeadThreshold << endl;
455   out << "fWarningThreshold" << "::" << fWarningThreshold << endl;
456   out << "fWarningFraction" << "::" << fWarningFraction << endl;
457   out << "fHotSigma" << "::" << fHotSigma << endl;
458
459   out.close();
460   return;
461 }
462
463 //_____________________________________________________________________
464 Bool_t AliCaloCalibPedestal::AddInfo(const AliCaloCalibPedestal *ped)
465 {
466   // just do this for the basic histograms/profiles that get filled in ProcessEvent
467   // may not have data for all modules, but let's just Add everything..
468   for (int i = 0; i < fModules; i++) {
469     GetPedProfileLowGain(i)->Add( ped->GetPedProfileLowGain(i) );
470     GetPedProfileHighGain(i)->Add( ped->GetPedProfileHighGain(i) );
471     GetPeakProfileLowGain(i)->Add( ped->GetPeakProfileLowGain(i) );
472     GetPeakProfileHighGain(i)->Add( ped->GetPeakProfileHighGain(i) );
473     GetPeakHighGainHisto(i)->Add( ped->GetPeakHighGainHisto(i) );
474
475   }//end for nModules 
476
477   // DeadMap; Diff profiles etc would need to be redone after this operation
478
479   return kTRUE;//We succesfully added info from the supplied object
480 }
481
482 //_____________________________________________________________________
483 Bool_t AliCaloCalibPedestal::ProcessEvent(AliRawReader *rawReader)
484
485   // if fMapping is NULL the rawstream will crate its own mapping
486   AliCaloRawStreamV3 rawStream(rawReader, fCaloString, (AliAltroMapping**)fMapping);
487   if (fDetType == kEmCal) {
488     rawReader->Select("EMCAL", 0, AliEMCALGeoParams::fgkLastAltroDDL) ; //select EMCAL DDL range 
489   }
490   return ProcessEvent(&rawStream);
491 }
492
493 //_____________________________________________________________________
494 Bool_t AliCaloCalibPedestal::ProcessEvent(AliCaloRawStreamV3 *in)
495
496   // Method to process=analyze one event in the data stream
497   if (!in) return kFALSE; //Return right away if there's a null pointer
498   fNEvents++; // one more event
499   
500   // indices for the reading
501   int sample = 0;
502   int time = 0;
503   int i = 0; // sample counter
504   int startBin = 0;
505
506   // start loop over input stream 
507   while (in->NextDDL()) {
508     while (in->NextChannel()) {
509
510       // counters
511       int max = AliEMCALGeoParams::fgkSampleMin, min = AliEMCALGeoParams::fgkSampleMax; // min and max sample values
512       int nsamples = 0;
513
514       // pedestal samples
515       int nPed = 0;
516       vector<int> pedSamples; 
517
518       while (in->NextBunch()) {
519         const UShort_t *sig = in->GetSignals();
520         startBin = in->GetStartTimeBin();
521         nsamples += in->GetBunchLength();
522         for (i = 0; i < in->GetBunchLength(); i++) {
523           sample = sig[i];
524           time = startBin--;
525
526           // check if it's a min or max value
527           if (sample < min) min = sample;
528           if (sample > max) max = sample;
529           
530           // should we add it for the pedestal calculation?
531           if ( (fFirstPedestalSample<=time && time<=fLastPedestalSample) || // sample time in range
532                !fSelectPedestalSamples ) { // or we don't restrict the sample range.. - then we'll take all 
533             pedSamples.push_back( sig[i] );
534             nPed++;
535           }
536           
537         } // loop over samples in bunch
538       } // loop over bunches
539
540       if (nsamples > 0) { // this check is needed for when we have zero-supp. on, but not sparse readout
541
542       // it should be enough to check the SuperModule info for each DDL really, but let's keep it here for now
543       int arrayPos = in->GetModule(); //The modules are numbered starting from 0
544       if (arrayPos >= fModules) {
545         //TODO: return an error message, if appopriate (perhaps if debug>0?)
546         return kFALSE;
547       }     
548       //Debug
549       if (arrayPos < 0 || arrayPos >= fModules) {
550         printf("Oh no: arrayPos = %i.\n", arrayPos); 
551       }
552       
553       fNChanFills++; // one more channel found, and profile to be filled
554       //NOTE: coordinates are (column, row) for the profiles
555       if ( in->IsLowGain() ) {
556         //fill the low gain histograms
557         ((TProfile2D*)fPeakMinusPedLowGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), max - min);
558         if (nPed>0) { // only fill pedestal info in case it could be calculated
559           for ( i=0; i<nPed; i++) {
560             ((TProfile2D*)fPedestalLowGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), pedSamples[i]); 
561           }
562         }
563       } 
564       else if ( in->IsHighGain() ) {    
565         //fill the high gain ones
566         ((TProfile2D*)fPeakMinusPedHighGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), max - min);
567         if (nPed>0) { // only fill pedestal info in case it could be calculated
568           for ( i=0; i<nPed; i++) {
569             ((TProfile2D*)fPedestalHighGain[arrayPos])->Fill(in->GetColumn(), fRowMultiplier*in->GetRow(), pedSamples[i]); 
570           }       
571         }
572         // for warning checks
573         int idx = in->GetRow() + fRows * in->GetColumn();
574         ((TH2F*)fPeakMinusPedHighGainHisto[arrayPos])->Fill(idx, max - min);
575       } 
576       else if ( in->IsLEDMonData() ) {
577         // for LED Mon data, the mapping class holds the gain info in the Row variable
578         // and the Strip number in the Column..
579         int gain = in->GetRow(); 
580         int stripId = in->GetColumn();
581         if (nPed>0 && stripId<fLEDRefs) {
582           if (gain == 0) {
583             for ( i=0; i<nPed; i++) {
584               ((TProfile*)fPedestalLEDRefLowGain[arrayPos])->Fill(stripId, pedSamples[i]);
585             }
586           }
587           else {
588             for ( i=0; i<nPed; i++) {
589               ((TProfile*)fPedestalLEDRefHighGain[arrayPos])->Fill(stripId, pedSamples[i]);
590             }
591           }
592         }
593       }
594
595       } // nsamples>0 check, some data found for this channel; not only trailer/header
596     }// end while over channel   
597   }//end while over DDL's, of input stream 
598
599   in->Reset(); // just in case the next customer forgets to check if the stream was reset..
600  
601   return kTRUE;
602 }
603
604 //_____________________________________________________________________
605 Bool_t AliCaloCalibPedestal::SaveHistograms(TString fileName, Bool_t saveEmptyHistos)
606 {
607   //Saves all the histograms (or profiles, to be accurate) to the designated file
608   
609   TFile destFile(fileName, "recreate");
610   
611   if (destFile.IsZombie()) {
612     return kFALSE;
613   }
614   
615   destFile.cd();
616   
617   for (int i = 0; i < fModules; i++) {
618     if( ((TProfile2D *)fPeakMinusPedLowGain[i])->GetEntries() || saveEmptyHistos) {
619       fPeakMinusPedLowGain[i]->Write();
620     }
621     if( ((TProfile2D *)fPeakMinusPedHighGain[i])->GetEntries() || saveEmptyHistos) { 
622       fPeakMinusPedHighGain[i]->Write();
623     }
624     if( ((TProfile2D *)fPedestalLowGain[i])->GetEntries() || saveEmptyHistos) {
625       fPedestalLowGain[i]->Write();
626     }
627     if( ((TProfile2D *)fPedestalHighGain[i])->GetEntries() || saveEmptyHistos) {
628       fPedestalHighGain[i]->Write();
629     }
630     if( ((TProfile *)fPedestalLEDRefLowGain[i])->GetEntries() || saveEmptyHistos) {
631       fPedestalLEDRefLowGain[i]->Write();
632     }
633     if( ((TProfile *)fPedestalLEDRefHighGain[i])->GetEntries() || saveEmptyHistos) {
634       fPedestalLEDRefHighGain[i]->Write();
635     }
636     if( ((TH2F *)fPeakMinusPedHighGainHisto[i])->GetEntries() || saveEmptyHistos) { 
637       fPeakMinusPedHighGainHisto[i]->Write();
638     }
639
640   } 
641   
642   destFile.Close();
643   
644   return kTRUE;
645 }
646
647 //_____________________________________________________________________
648 Bool_t AliCaloCalibPedestal::LoadReferenceCalib(TString fileName, TString objectName)
649 {
650   
651   //Make sure that the histograms created when loading the object are not destroyed as the file object is destroyed
652   TH1::AddDirectory(kFALSE);
653   
654   TFile *sourceFile = new TFile(fileName);
655   if (sourceFile->IsZombie()) {
656     return kFALSE;//We couldn't load the reference
657   }
658
659   if (fReference) delete fReference;//Delete the reference object, if it already exists
660   fReference = 0;
661   
662   fReference = (AliCaloCalibPedestal*)sourceFile->Get(objectName);
663  
664   if (!fReference || !(fReference->InheritsFrom(AliCaloCalibPedestal::Class())) || (fReference->GetDetectorType() != fDetType)) {
665     if (fReference) delete fReference;//Delete the object, in case we had an object of the wrong type
666     fReference = 0;
667     return kFALSE;
668   }
669         
670   delete sourceFile;
671
672   //Reset the histogram ownership behaviour. NOTE: a better workaround would be good, since this may accidentally set AddDirectory to true, even
673   //if we are called by someone who has set it to false...
674   TH1::AddDirectory(kTRUE);
675  
676   return kTRUE;//We succesfully loaded the object
677 }
678
679
680 //_____________________________________________________________________
681 Bool_t AliCaloCalibPedestal::SetReference(AliCaloCalibPedestal *ref)
682 {
683   if (fReference) delete fReference;//Delete the reference object, if it already exists
684   fReference = 0;
685   
686   fReference = ref;
687  
688   if (!fReference || (fReference->GetDetectorType() != fDetType)) {
689     if (fReference) delete fReference;//Delete the object, in case we had an object of the wrong type
690     fReference = 0;
691     return kFALSE;
692   }
693
694   return kTRUE;//We succesfully loaded the object
695 }
696
697 //_____________________________________________________________________
698 void AliCaloCalibPedestal::ValidateComparisonProfiles()
699 {
700   //Make sure the comparison histos exist
701   if (!fPedestalLowGainDiff.IsEmpty()) return; //The profiles already exist. We just check one, because they're all created at
702   //the same time
703                                                 
704                                                 
705   //Then, loop for the requested number of modules
706   TString title, name;
707   for (int i = 0; i < fModules; i++) {
708     //Pedestals, low gain
709     name = "hPedlowgainDiff";
710     name += i;
711     title = "Pedestals difference, low gain, module ";
712     title += i; 
713     fPedestalLowGainDiff.Add(new TProfile2D(name, title,
714                                             fColumns, 0.0, fColumns, 
715                                             fRows, fRowMin, fRowMax,"s"));
716   
717     //Pedestals, high gain
718     name = "hPedhighgainDiff";
719     name += i;
720     title = "Pedestals difference, high gain, module ";
721     title += i; 
722     fPedestalHighGainDiff.Add(new TProfile2D(name, title,
723                                              fColumns, 0.0, fColumns, 
724                                              fRows, fRowMin, fRowMax,"s"));
725
726     //LED Ref/Mon pedestals, low gain
727     name = "hPedestalLEDReflowgainDiff";
728     name += i;
729     title = "Pedestal difference LEDRef, low gain, module ";
730     title += i; 
731     fPedestalLEDRefLowGainDiff.Add(new TProfile(name, title,
732                                                 fLEDRefs, 0.0, fLEDRefs, "s"));
733     
734     //LED Ref/Mon pedestals, high gain
735     name = "hPedestalLEDRefhighgainDiff";
736     name += i;
737     title = "Pedestal difference LEDRef, high gain, module ";
738     title += i; 
739     fPedestalLEDRefHighGainDiff.Add(new TProfile(name, title,
740                                                  fLEDRefs, 0.0, fLEDRefs, "s"));
741
742     //Peak-Pedestals, high gain
743     name = "hPeakMinusPedhighgainDiff";
744     name += i;
745     title = "Peak-Pedestal difference, high gain, module ";
746     title += i; 
747     fPeakMinusPedHighGainDiff.Add(new TProfile2D(name, title,
748                                                  fColumns, 0.0, fColumns, 
749                                                  fRows, fRowMin, fRowMax,"s"));
750
751     //Peak-Pedestals, low gain
752     name = "hPeakMinusPedlowgainDiff";
753     name += i;
754     title = "Peak-Pedestal difference, low gain, module ";
755     title += i; 
756     fPeakMinusPedLowGainDiff.Add(new TProfile2D(name, title,
757                                                 fColumns, 0.0, fColumns, 
758                                                 fRows, fRowMin, fRowMax,"s"));
759   
760     //Pedestals, low gain
761     name = "hPedlowgainRatio";
762     name += i;
763     title = "Pedestals ratio, low gain, module ";
764     title += i; 
765     fPedestalLowGainRatio.Add(new TProfile2D(name, title,
766                                              fColumns, 0.0, fColumns, 
767                                              fRows, fRowMin, fRowMax,"s"));
768   
769     //Pedestals, high gain
770     name = "hPedhighgainRatio";
771     name += i;
772     title = "Pedestals ratio, high gain, module ";
773     title += i; 
774     fPedestalHighGainRatio.Add(new TProfile2D(name, title,
775                                               fColumns, 0.0, fColumns, 
776                                               fRows, fRowMin, fRowMax,"s"));
777
778     //LED Ref/Mon pedestals, low gain
779     name = "hPedestalLEDReflowgainRatio";
780     name += i;
781     title = "Pedestal ratio LEDRef, low gain, module ";
782     title += i; 
783     fPedestalLEDRefLowGainRatio.Add(new TProfile(name, title,
784                                                  fLEDRefs, 0.0, fLEDRefs, "s"));
785     
786     //LED Ref/Mon pedestals, high gain
787     name = "hPedestalLEDRefhighgainRatio";
788     name += i;
789     title = "Pedestal ratio LEDRef, high gain, module ";
790     title += i; 
791     fPedestalLEDRefHighGainRatio.Add(new TProfile(name, title,
792                                                   fLEDRefs, 0.0, fLEDRefs, "s"));
793   
794     //Peak-Pedestals, low gain
795     name = "hPeakMinusPedlowgainRatio";
796     name += i;
797     title = "Peak-Pedestal ratio, low gain, module ";
798     title += i; 
799     fPeakMinusPedLowGainRatio.Add(new TProfile2D(name, title,
800                                                  fColumns, 0.0, fColumns, 
801                                                  fRows, fRowMin, fRowMax,"s"));
802   
803     //Peak-Pedestals, high gain
804     name = "hPeakMinusPedhighgainRatio";
805     name += i;
806     title = "Peak-Pedestal ratio, high gain, module ";
807     title += i; 
808     fPeakMinusPedHighGainRatio.Add(new TProfile2D(name, title,
809                                                   fColumns, 0.0, fColumns, 
810                                                   fRows, fRowMin, fRowMax,"s"));
811     
812   }//end for nModules create the histograms
813 }
814
815 //_____________________________________________________________________
816 void AliCaloCalibPedestal::ComputeDiffAndRatio()
817 {
818   // calculate differences and ratios relative to a reference
819   ValidateComparisonProfiles();//Make sure the comparison histos exist
820  
821   if (!fReference) {
822     return;//Return if the reference object isn't loaded
823   }
824
825   int bin = 0;
826   double diff = 0;
827   double ratio = 1;
828   for (int i = 0; i < fModules; i++) {
829     //For computing the difference, we cannot simply do TProfile2D->Add(), because that subtracts the sum of all entries,
830     //which means that the mean of the new profile will not be the difference of the means. So do it by hand:
831     for (int j = 0; j < fColumns; j++) {
832       for (int k = 0; k < fRows; k++) {
833         bin = ((TProfile2D*)fPeakMinusPedHighGainDiff[i])->GetBin(j+1, k+1);//Note that we assume here that all histos have the same structure...
834
835         if (fReference->GetPeakProfileHighGain(i)->GetBinContent(bin) > 0) {
836           diff = GetPeakProfileHighGain(i)->GetBinContent(bin) - fReference->GetPeakProfileHighGain(i)->GetBinContent(bin);
837           ((TProfile2D*)fPeakMinusPedHighGainDiff[i])->SetBinContent(bin, diff);
838           ((TProfile2D*)fPeakMinusPedHighGainDiff[i])->SetBinEntries(bin, 1);
839           ratio = GetPeakProfileHighGain(i)->GetBinContent(bin) / fReference->GetPeakProfileHighGain(i)->GetBinContent(bin);  
840           ((TProfile2D*)fPeakMinusPedHighGainRatio[i])->SetBinContent(bin, ratio);
841           ((TProfile2D*)fPeakMinusPedHighGainRatio[i])->SetBinEntries(bin, 1);
842         }
843
844         if (fReference->GetPeakProfileLowGain(i)->GetBinContent(bin) > 0) {
845           diff = GetPeakProfileLowGain(i)->GetBinContent(bin) - fReference->GetPeakProfileLowGain(i)->GetBinContent(bin);
846           ((TProfile2D*)fPeakMinusPedLowGainDiff[i])->SetBinContent(bin, diff);
847           ((TProfile2D*)fPeakMinusPedLowGainDiff[i])->SetBinEntries(bin, 1);
848           ratio = GetPeakProfileLowGain(i)->GetBinContent(bin) / fReference->GetPeakProfileLowGain(i)->GetBinContent(bin);  
849           ((TProfile2D*)fPeakMinusPedLowGainRatio[i])->SetBinContent(bin, ratio);
850           ((TProfile2D*)fPeakMinusPedLowGainRatio[i])->SetBinEntries(bin, 1);
851         }
852
853         if (fReference->GetPedProfileHighGain(i)->GetBinContent(bin) > 0) {
854           diff = GetPedProfileHighGain(i)->GetBinContent(bin) - fReference->GetPedProfileHighGain(i)->GetBinContent(bin);
855           ((TProfile2D*)fPedestalHighGainDiff[i])->SetBinContent(bin, diff);
856           ((TProfile2D*)fPedestalHighGainDiff[i])->SetBinEntries(bin, 1);
857           ratio = GetPedProfileHighGain(i)->GetBinContent(bin) / fReference->GetPedProfileHighGain(i)->GetBinContent(bin);  
858           ((TProfile2D*)fPedestalHighGainRatio[i])->SetBinContent(bin, ratio);
859           ((TProfile2D*)fPedestalHighGainRatio[i])->SetBinEntries(bin, 1);
860         }
861
862         if (fReference->GetPedProfileLowGain(i)->GetBinContent(bin) > 0) {
863           diff = GetPedProfileLowGain(i)->GetBinContent(bin) - fReference->GetPedProfileLowGain(i)->GetBinContent(bin);
864           ((TProfile2D*)fPedestalLowGainDiff[i])->SetBinContent(bin, diff);
865           ((TProfile2D*)fPedestalLowGainDiff[i])->SetBinEntries(bin, 1);
866           ratio = GetPedProfileLowGain(i)->GetBinContent(bin) / fReference->GetPedProfileLowGain(i)->GetBinContent(bin);  
867           ((TProfile2D*)fPedestalLowGainRatio[i])->SetBinContent(bin, ratio);
868           ((TProfile2D*)fPedestalLowGainRatio[i])->SetBinEntries(bin, 1);
869         }
870
871       } // rows
872     } // columns
873
874     // same for LED Ref/Mon channels
875     for (int j = 0; j <= fLEDRefs; j++) {    
876       bin = j+1;//Note that we assume here that all histos have the same structure...
877
878       if (fReference->GetPedLEDRefProfileHighGain(i)->GetBinContent(bin) > 0) {
879         diff = GetPedLEDRefProfileHighGain(i)->GetBinContent(bin) - fReference->GetPedLEDRefProfileHighGain(i)->GetBinContent(bin);
880         ((TProfile*)fPedestalLEDRefHighGainDiff[i])->SetBinContent(bin, diff);
881         ((TProfile*)fPedestalLEDRefHighGainDiff[i])->SetBinEntries(bin, 1);
882         ratio = GetPedLEDRefProfileHighGain(i)->GetBinContent(bin) / fReference->GetPedLEDRefProfileHighGain(i)->GetBinContent(bin);  
883         ((TProfile*)fPedestalLEDRefHighGainRatio[i])->SetBinContent(bin, ratio);
884         ((TProfile*)fPedestalLEDRefHighGainRatio[i])->SetBinEntries(bin, 1);
885       }
886
887       if (fReference->GetPedLEDRefProfileLowGain(i)->GetBinContent(bin) > 0) {
888         diff = GetPedLEDRefProfileLowGain(i)->GetBinContent(bin) - fReference->GetPedLEDRefProfileLowGain(i)->GetBinContent(bin);
889         ((TProfile*)fPedestalLEDRefLowGainDiff[i])->SetBinContent(bin, diff);
890         ((TProfile*)fPedestalLEDRefLowGainDiff[i])->SetBinEntries(bin, 1);
891         ratio = GetPedLEDRefProfileLowGain(i)->GetBinContent(bin) / fReference->GetPedLEDRefProfileLowGain(i)->GetBinContent(bin);  
892         ((TProfile*)fPedestalLEDRefLowGainRatio[i])->SetBinContent(bin, ratio);
893         ((TProfile*)fPedestalLEDRefLowGainRatio[i])->SetBinEntries(bin, 1);
894       } 
895      
896     }
897
898   } // modules
899  
900 }
901
902 //_____________________________________________________________________
903 void AliCaloCalibPedestal::ComputeHotAndWarningTowers(const char * hotMapFile)
904 { // look for hot/noisy towers
905   ofstream * fout = 0;
906   char name[512];//Quite a long temp buffer, just in case the filename includes a path
907
908   if (hotMapFile) {
909     snprintf(name, 512, "%s.txt", hotMapFile);
910     fout = new ofstream(name);
911     if (!fout->is_open()) {
912       delete fout;
913       fout = 0;//Set the pointer to empty if the file was not opened
914     }
915   }
916  
917   for(int i = 0; i < fModules; i++){
918                 
919     //first we compute the peak-pedestal distribution for each supermodule...
920     if( GetPeakHighGainHisto(i)->GetEntries() > 0 ) {
921       double min = GetPeakProfileHighGain(i)->GetBinContent(GetPeakProfileHighGain(i)->GetMinimumBin());
922       double max = GetPeakProfileHighGain(i)->GetBinContent(GetPeakProfileHighGain(i)->GetMaximumBin());
923       TH1D *hPeakFit = new TH1D(Form("hFit_%d", i), Form("hFit_%d", i), (int)((max-min)*10), min-1, max+1);
924
925       for (int j = 1; j <= fColumns; j++) {
926         for (int k = 1; k <= fRows; k++) {        
927           hPeakFit->Fill(GetPeakProfileHighGain(i)->GetBinContent(j, k));
928         }
929       }
930
931       //...and then we try to fit it
932       double mean  = hPeakFit->GetMean();
933       double sigma = hPeakFit->GetRMS();
934       try {
935         hPeakFit->Fit("gaus", "OQ", "",  mean - 3*sigma, mean + 3*sigma);
936         mean  = hPeakFit->GetFunction("gaus")->GetParameter(1);
937         sigma = hPeakFit->GetFunction("gaus")->GetParameter(2);
938       }
939       catch (const std::exception & e) {
940         printf("AliCaloCalibPedestal: TH1D PeakFit exception %s", e.what()); 
941       }      
942       //hPeakFit->Draw();
943
944       delete hPeakFit;
945
946       //Then we look for warm/hot towers
947       TH2F * hPeak2D = GetPeakHighGainHisto(i);
948       hPeak2D->GetYaxis()->SetRangeUser( fWarningThreshold, hPeak2D->GetYaxis()->GetBinUpEdge(hPeak2D->GetNbinsY()) );
949
950       int idx = 0 ;
951       int warnCounter = 0;
952       for (int j = 1; j <= fColumns; j++) {
953         for (int k = 1; k <= fRows; k++) {                              
954           //we start looking for warm/warning towers...
955           // histogram x-axis index
956           idx = k-1 + fRows*(j-1); // this is what is used in the Fill call
957           hPeak2D->GetXaxis()->SetRangeUser(idx, idx);
958           warnCounter = (int) hPeak2D->Integral();
959           if(warnCounter > fNEvents * fWarningFraction) {
960             ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kWarning);            
961             /* printf("mod %d col %d row %d warnCounter %d - status %d\n", 
962                i, j-1, k-1, warnCounter, (int) (kWarning)); */  
963           }
964           //...then we look for hot ones (towers whose values are greater than mean + X*sigma)  
965           if(GetPeakProfileHighGain(i)->GetBinContent(j, k) > mean + fHotSigma*sigma ) {
966             ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kHot); 
967             /* printf("mod %d col %d row %d  binc %d - status %d\n", 
968                i, j-1, k-1, (int)(GetPeakProfileHighGain(i)->GetBinContent(j, k)), (int) (kHot)); */      
969           }
970
971           //Write the status to the hot/warm map file, if the file is open.
972           // module - column - row - status (1=dead, 2= warm/warning , 3 = hot, see .h file enum)
973           if (fout && ((TH2D*)fDeadMap[i])->GetBinContent(j, k) > 1) {
974             
975             (*fout) << i << " " 
976                     << (j - 1) << " " 
977                     << (k - 1) << " " 
978                     << ((TH2D*)fDeadMap[i])->GetBinContent(j, k) << endl;               }
979           
980         }
981       }
982
983     } 
984   }
985   return;
986 }
987
988 //_____________________________________________________________________
989 void AliCaloCalibPedestal::ComputeDeadTowers(const char * deadMapFile)
990 {
991   //Computes the number of dead towers etc etc into memory, after this you can call the GetDead... -functions
992   int countTot = 0;
993   int countNew = 0;
994   int countRes = 0;
995   ofstream * fout = 0;
996   ofstream * diff = 0;
997   char name[512];//Quite a long temp buffer, just in case the filename includes a path
998   
999   if (deadMapFile) {
1000     snprintf(name, 512, "%s.txt", deadMapFile);
1001     fout = new ofstream(name);
1002     snprintf(name, 512, "%sdiff.txt", deadMapFile);
1003     diff = new ofstream(name);
1004     if (!fout->is_open()) {
1005       delete fout;
1006       fout = 0;//Set the pointer to empty if the file was not opened
1007     }
1008     if (!diff->is_open()) {
1009       delete diff;
1010       fout = 0;//Set the pointer to empty if the file was not opened
1011     }
1012   }
1013  
1014   for (int i = 0; i < fModules; i++) {
1015     if (GetPeakProfileHighGain(i)->GetEntries() > 0) { //don't care about empty histos
1016       for (int j = 1; j <= fColumns; j++) {
1017         for (int k = 1; k <= fRows; k++) {
1018
1019           if (GetPeakProfileHighGain(i)->GetBinContent(j, k) < fDeadThreshold) {//It's dead
1020             countTot++;//One more dead total
1021             if (fout) {
1022               (*fout) << i << " " 
1023                       << (j - 1) << " " 
1024                       << (k - 1) << " " 
1025                       << "1" << " " 
1026                       << "0" << endl;//Write the status to the deadmap file, if the file is open.
1027             }
1028             
1029             if (fReference && fReference->GetPeakProfileHighGain(i)->GetBinContent(j, k) >= fDeadThreshold) {
1030               ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kRecentlyDeceased); 
1031               countNew++;//This tower wasn't dead before!
1032               if (diff) {
1033                 ( *diff) << i << " " 
1034                          << (j - 1) << " " 
1035                          << (k - 1) << " " 
1036                          << "1" << " " 
1037                          << "0" << endl;//Write the status to the deadmap difference file, if the file is open.
1038               }
1039             } 
1040             else {
1041               ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kDead);//This has been dead before. Nothing new         
1042             }
1043           } 
1044           else { //It's ALIVE!!
1045             //Don't bother with writing the live ones.
1046             if (fReference && fReference->GetPeakProfileHighGain(i)->GetBinContent(j, k) < fDeadThreshold) {
1047               ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kResurrected);
1048               countRes++; //This tower was dead before => it's a miracle! :P
1049               if (diff) {
1050                 (*diff) << i << " " 
1051                         << (j - 1) << " " 
1052                         << (k - 1) << " " 
1053                         << "1" << " " 
1054                         << "1" << endl;//Write the status to the deadmap difference file, if the file is open.
1055               }
1056             } 
1057             else {
1058               ((TH2D*)fDeadMap[i])->SetBinContent(j, k, kAlive);
1059             }
1060           }
1061             
1062         }//end for k/rows
1063       }//end for j/columns
1064     }//end if GetEntries >= 0
1065   
1066   }//end for modules
1067  
1068  if (fout) {
1069    fout->close();
1070    delete fout;
1071  }
1072  
1073  fDeadTowers = countTot;
1074  fNewDeadTowers = countNew;
1075  fResurrectedTowers = countRes;
1076 }
1077
1078 //_____________________________________________________________________
1079 Bool_t AliCaloCalibPedestal::IsBadChannel(int imod, int icol, int irow) const
1080 {
1081   //Check if channel is dead or hot.  
1082   Int_t status =  (Int_t) ( ((TH2D*)fDeadMap[imod])->GetBinContent(icol,irow) );
1083   if(status == kAlive)
1084     return kFALSE;
1085   else 
1086     return kTRUE;
1087   
1088 }
1089
1090 //_____________________________________________________________________
1091 void AliCaloCalibPedestal::SetChannelStatus(int imod, int icol, int irow, int status)
1092 {
1093   //Set status of channel dead, hot, alive ...  
1094   ((TH2D*)fDeadMap[imod])->SetBinContent(icol, irow, status);   
1095 }