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