add protection against truncated events + coverity - Rachid
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALCalibReference.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
16 /* $Id: $ */
17
18 // Objects of this class contain basis for reference calibrations
19 //
20
21 #include <fstream>
22 #include <TString.h>
23 #include <TFile.h>
24 #include <TTree.h>
25
26 #include "AliEMCALCalibReference.h"
27
28 using namespace std;
29
30 ClassImp(AliEMCALCalibReference)
31
32 //____________________________________________________________________________
33 AliEMCALCalibReference::AliEMCALCalibReference(const int nSM) : 
34   fNSuperModule(nSM),
35   fSuperModuleData()
36 {
37   //Default constructor.
38   for (int i=0; i<fNSuperModule; i++) {
39     fSuperModuleData.Add(new AliEMCALSuperModuleCalibReference(i));
40   }
41   fSuperModuleData.Compress(); // compress the TObjArray
42   fSuperModuleData.SetOwner(kTRUE); 
43 }
44
45 //____________________________________________________________________________
46 void AliEMCALCalibReference::ReadTextCalibReferenceInfo(Int_t nSM, const TString &txtFileName,
47                                             Bool_t swapSides)
48 {
49   //Read data from txt file. ; coordinates given on SuperModule basis
50
51   std::ifstream inputFile(txtFileName.Data());
52   if (!inputFile) {
53     printf("AliEMCALCalibReference::ReadCalibReferenceInfo - Cannot open the APD info file %s\n", txtFileName.Data());
54     return;
55   }
56
57   fNSuperModule = nSM;
58
59   Int_t iSM = 0; // SuperModule index
60   Int_t iCol = 0;
61   Int_t iRow = 0;
62   Int_t id = 0;
63
64   // list of values to be read
65   // first: overall values for the whole SuperModule
66   Int_t iReferenceTime = 0; 
67   // second: additional info for LED Reference and SM temperature
68   Float_t rLEDRefAmp = 0;
69   Float_t rLEDRefAmpRMS = 0;
70   Int_t iLEDRefHighLow = 0;
71   Float_t temperature = 0;
72   Float_t temperatureRMS = 0;
73   // third: info for each tower
74   Int_t iHighLow = 0; // 
75   Float_t rLEDAmp = 0; // low gain eq. amplitude
76   Float_t rLEDAmpRMS = 0; //
77   // end - all values
78
79   Int_t nAPDPerSM = AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows;
80
81   for (Int_t i = 0; i < fNSuperModule; i++) {
82     AliEMCALSuperModuleCalibReference * t = (AliEMCALSuperModuleCalibReference*) fSuperModuleData[i];
83     if (!inputFile) {
84       printf("AliEMCALCalibReference::ReadCalibReferenceInfo - Error while reading input file; likely EOF..\n");
85       return;
86     }
87     inputFile >> iSM;
88     t->SetSuperModuleNum(iSM);
89
90     // first: overall values for the whole SuperModule
91     inputFile >> iReferenceTime;
92     t->SetReferenceTime(iReferenceTime);
93
94     // second: additional info for LED Reference and SM temperature
95     for (Int_t j=0; j<AliEMCALGeoParams::fgkEMCALLEDRefs; j++) {
96       inputFile >> id >> iLEDRefHighLow >> rLEDRefAmp >> rLEDRefAmpRMS;
97       if (id<0 || id>(AliEMCALGeoParams::fgkEMCALLEDRefs-1) ) {
98         printf("AliEMCALCalibReference::ReadCalibReferenceInfo - Error while reading input file; LEDRef j %d id %d\n", j, id);
99         return;
100       }
101       t->SetLEDRefHighLow(id, iLEDRefHighLow);
102       t->SetLEDRefAmp(id, rLEDRefAmp);
103       t->SetLEDRefAmpRMS(id, rLEDRefAmpRMS);
104     }
105
106     for (Int_t j=0; j<AliEMCALGeoParams::fgkEMCALTempSensors; j++) {
107       inputFile >> id >> temperature >> temperatureRMS;
108       if (id<0 || id>(AliEMCALGeoParams::fgkEMCALTempSensors-1) ) {
109         printf("AliEMCALCalibReference::ReadCalibReferenceInfo - Error while reading input file; TempSensor j %d id %d\n", j, id);
110         return;
111       }
112       t->SetTemperature(id, temperature);
113       t->SetTemperatureRMS(id, temperatureRMS);
114     }
115
116     // third: info for each tower
117     for (Int_t j=0; j<nAPDPerSM; j++) {
118       inputFile >> iCol >> iRow 
119                 >> iHighLow >> rLEDAmp >> rLEDAmpRMS;
120
121       // check that input values are not out bounds
122       if (iCol<0 || iCol>(AliEMCALGeoParams::fgkEMCALCols-1) ||
123           iRow<0 || iRow>(AliEMCALGeoParams::fgkEMCALRows-1) ) {
124         printf("AliEMCALCalibReference::ReadCalibReferenceInfo - Error while reading input file; j %d iCol %d iRow %d\n", j, iCol, iRow);
125       return;
126       }
127
128       // assume that this info is already swapped and done for this basis?
129       if (swapSides) {
130         // C side, oriented differently than A side: swap is requested
131         iCol = AliEMCALGeoParams::fgkEMCALCols-1 - iCol;
132         iRow = AliEMCALGeoParams::fgkEMCALRows-1 - iRow;
133       }
134
135       AliEMCALCalibReferenceVal * v = t->GetAPDVal(iCol, iRow);
136
137       v->SetHighLow(iHighLow);
138       v->SetLEDAmp(rLEDAmp);
139       v->SetLEDAmpRMS(rLEDAmpRMS);
140     }
141
142   } // i, SuperModule
143
144   inputFile.close();
145
146   return;
147 }
148
149 //____________________________________________________________________________
150 void AliEMCALCalibReference::WriteTextCalibReferenceInfo(const TString &txtFileName,
151                                              Bool_t swapSides)
152 {
153   // write data to txt file. ; coordinates given on SuperModule basis
154
155   std::ofstream outputFile(txtFileName.Data());
156   if (!outputFile) {
157     printf("AliEMCALCalibReference::WriteCalibReferenceInfo - Cannot open the APD output file %s\n", txtFileName.Data());
158     return;
159   }
160
161   Int_t iCol = 0;
162   Int_t iRow = 0;
163
164   Int_t nAPDPerSM = AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows;
165
166   for (Int_t i = 0; i < fNSuperModule; i++) {
167     AliEMCALSuperModuleCalibReference * t = (AliEMCALSuperModuleCalibReference*) fSuperModuleData[i];
168
169     // first: overall values for the whole SuperModule
170     outputFile << t->GetSuperModuleNum() << endl;
171     outputFile << t->GetReferenceTime() << endl;
172
173     // second: additional info for LED Reference and SM temperature
174     for (Int_t j=0; j<AliEMCALGeoParams::fgkEMCALLEDRefs; j++) {
175       outputFile << j << " " << t->GetLEDRefHighLow(j) 
176                  << " " << t->GetLEDRefAmp(j) << " " << t->GetLEDRefAmpRMS(j) 
177                  << endl;
178     }
179     for (Int_t j=0; j<AliEMCALGeoParams::fgkEMCALTempSensors; j++) {
180       outputFile << j << " " << t->GetTemperature(j) << " " << t->GetTemperatureRMS(j) << endl;
181     }
182
183     // third: info for each tower
184     for (Int_t j=0; j<nAPDPerSM; j++) {
185       iCol = j / AliEMCALGeoParams::fgkEMCALRows;
186       iRow = j % AliEMCALGeoParams::fgkEMCALRows;
187
188       AliEMCALCalibReferenceVal * v = t->GetAPDVal(iCol, iRow);
189
190       if (swapSides) {
191         // C side, oriented differently than A side: swap is requested
192         iCol = AliEMCALGeoParams::fgkEMCALCols-1 - iCol;
193         iRow = AliEMCALGeoParams::fgkEMCALRows-1 - iRow;
194       }
195
196       outputFile << iCol << " " << iRow 
197                  << " " << v->GetHighLow() 
198                  << " " << v->GetLEDAmp() 
199                  << " " << v->GetLEDAmpRMS() << endl;
200     }
201
202   } // i, SuperModule
203
204   outputFile.close();
205
206   return;
207 }
208
209 //____________________________________________________________________________
210 void AliEMCALCalibReference::ReadRootCalibReferenceInfo(const TString &rootFileName,
211                                             Bool_t swapSides)
212 {
213   //Read data from root file. ; coordinates given on SuperModule basis
214   TFile inputFile(rootFileName, "read");  
215
216   TTree *tree = (TTree*) inputFile.Get("tree");
217
218   ReadTreeCalibReferenceInfo(tree, swapSides);
219
220   inputFile.Close();
221
222   return;
223 }
224
225 //____________________________________________________________________________
226 void AliEMCALCalibReference::ReadTreeCalibReferenceInfo(TTree *tree,
227                                             Bool_t swapSides)
228 {
229   // how many SuperModule's worth of info do we have?
230   Int_t nAPDPerSM = AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows;
231   fNSuperModule = tree->GetEntries();
232
233   Int_t iSM = 0; // SuperModule index
234   // list of values to be read
235   // first: overall values for the whole SuperModule
236   Int_t iReferenceTime= 0; 
237   // second: additional info for LED Reference and SM temperature
238   Float_t rLEDRefAmp[AliEMCALGeoParams::fgkEMCALLEDRefs]= {0};
239   Float_t rLEDRefAmpRMS[AliEMCALGeoParams::fgkEMCALLEDRefs]= {0};
240   Int_t iLEDRefHighLow[AliEMCALGeoParams::fgkEMCALLEDRefs]= {0};
241   Float_t temperature[AliEMCALGeoParams::fgkEMCALTempSensors]= {0};
242   Float_t temperatureRMS[AliEMCALGeoParams::fgkEMCALTempSensors]= {0};
243   // third: info for each tower
244   Int_t iHighLow[AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows]; 
245   Float_t rLEDAmp[AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows]; 
246   Float_t rLEDAmpRMS[AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows]; 
247   // end - all values
248
249   // just to make the initializations of the arrays are done correctly, let's use memset
250   memset(rLEDRefAmp, 0, sizeof(rLEDRefAmp)); 
251   memset(rLEDRefAmpRMS, 0, sizeof(rLEDRefAmpRMS)); 
252   memset(iLEDRefHighLow, 0, sizeof(iLEDRefHighLow)); 
253   memset(temperature, 0, sizeof(temperature)); 
254   memset(temperatureRMS, 0, sizeof(temperatureRMS)); 
255   memset(iHighLow, 0, sizeof(iHighLow)); 
256   memset(rLEDAmp, 0, sizeof(rLEDAmp)); 
257   memset(rLEDAmpRMS, 0, sizeof(rLEDAmpRMS)); 
258
259   // declare the branches
260   tree->SetBranchAddress("iSM", &iSM);
261   tree->SetBranchAddress("ReferenceTime", &iReferenceTime);
262   //
263   tree->SetBranchAddress("LEDRefAmp", rLEDRefAmp);
264   tree->SetBranchAddress("LEDRefAmpRMS", rLEDRefAmpRMS);
265   tree->SetBranchAddress("LEDRefHighLow", iLEDRefHighLow);
266   tree->SetBranchAddress("Temperature", temperature);
267   tree->SetBranchAddress("TemperatureRMS", temperatureRMS);
268   //
269   tree->SetBranchAddress("HighLow", iHighLow);
270   tree->SetBranchAddress("LEDAmp", rLEDAmp);
271   tree->SetBranchAddress("LEDAmpRMS", rLEDAmpRMS);
272
273   // indices for looping over the towers
274   Int_t iCol = 0;
275   Int_t iRow = 0;
276
277   for (int ient=0; ient<tree->GetEntries(); ient++) {
278     tree->GetEntry(ient);
279
280     // assume the index SuperModules come in order: i=iSM
281     AliEMCALSuperModuleCalibReference * t = (AliEMCALSuperModuleCalibReference*) fSuperModuleData[iSM];
282
283     t->SetSuperModuleNum(iSM);
284     // first, overall values
285     t->SetReferenceTime(iReferenceTime);
286
287     // second: additional info for LED references and SM temperatures
288     for (Int_t j=0; j<AliEMCALGeoParams::fgkEMCALLEDRefs; j++) {
289       t->SetLEDRefAmp(j, rLEDRefAmp[j]);
290       t->SetLEDRefAmpRMS(j, rLEDRefAmpRMS[j]);
291       t->SetLEDRefHighLow(j, iLEDRefHighLow[j]);
292     }
293     for (Int_t j=0; j<AliEMCALGeoParams::fgkEMCALTempSensors; j++) {
294       t->SetTemperature(j, temperature[j]);
295       t->SetTemperatureRMS(j, temperatureRMS[j]);
296     }
297
298     // third: info for each tower
299     for (Int_t j=0; j<nAPDPerSM; j++) {
300       iCol = j / AliEMCALGeoParams::fgkEMCALRows;
301       iRow = j % AliEMCALGeoParams::fgkEMCALRows;
302
303       // help variables: possibly modified or swapped indices
304       int iColMod = iCol;
305       int iRowMod = iRow;
306       // assume that this info is already swapped and done for this basis?
307       if (swapSides) {
308         // C side, oriented differently than A side: swap is requested
309         iColMod = AliEMCALGeoParams::fgkEMCALCols-1 - iCol;
310         iRowMod = AliEMCALGeoParams::fgkEMCALRows-1 - iRow;
311       }
312
313       AliEMCALCalibReferenceVal * v = t->GetAPDVal(iColMod, iRowMod);
314
315       v->SetHighLow(iHighLow[iCol][iRow]);
316       v->SetLEDAmp(rLEDAmp[iCol][iRow]);
317       v->SetLEDAmpRMS(rLEDAmpRMS[iCol][iRow]);
318     }
319
320   } // loop over entries
321
322   return;
323 }
324
325 //____________________________________________________________________________
326 void AliEMCALCalibReference::WriteRootCalibReferenceInfo(const TString &rootFileName,
327                                              Bool_t swapSides)
328 {
329   // write data to root file. ; coordinates given on SuperModule basis
330   TFile destFile(rootFileName, "recreate");  
331   if (destFile.IsZombie()) {
332     return;
333   }  
334   destFile.cd();
335
336   TTree *tree = new TTree("tree","");
337
338   // variables for filling the TTree
339   Int_t iSM = 0; // SuperModule index
340   // list of values to be written
341   // first: overall values for the whole SuperModule
342   Int_t iReferenceTime = 0; 
343   // second: additional info for LED Reference and SM temperature
344   Float_t rLEDRefAmp[AliEMCALGeoParams::fgkEMCALLEDRefs] = {0};
345   Float_t rLEDRefAmpRMS[AliEMCALGeoParams::fgkEMCALLEDRefs]= {0};
346   Int_t iLEDRefHighLow[AliEMCALGeoParams::fgkEMCALLEDRefs]= {0};
347   Float_t temperature[AliEMCALGeoParams::fgkEMCALTempSensors]= {0};
348   Float_t temperatureRMS[AliEMCALGeoParams::fgkEMCALTempSensors]= {0};
349   // third: info for each tower
350   Int_t iHighLow[AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows]; 
351   Float_t rLEDAmp[AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows]; 
352   Float_t rLEDAmpRMS[AliEMCALGeoParams::fgkEMCALCols][AliEMCALGeoParams::fgkEMCALRows]; 
353   // end - all values
354
355   // just to make the initializations of the arrays are done correctly, let's use memset
356   memset(rLEDRefAmp, 0, sizeof(rLEDRefAmp)); 
357   memset(rLEDRefAmpRMS, 0, sizeof(rLEDRefAmpRMS)); 
358   memset(iLEDRefHighLow, 0, sizeof(iLEDRefHighLow)); 
359   memset(temperature, 0, sizeof(temperature)); 
360   memset(temperatureRMS, 0, sizeof(temperatureRMS)); 
361   memset(iHighLow, 0, sizeof(iHighLow)); 
362   memset(rLEDAmp, 0, sizeof(rLEDAmp)); 
363   memset(rLEDAmpRMS, 0, sizeof(rLEDAmpRMS)); 
364
365   Int_t nAPDPerSM = AliEMCALGeoParams::fgkEMCALCols * AliEMCALGeoParams::fgkEMCALRows;
366   // for looping over towers
367   Int_t iCol = 0;
368   Int_t iRow = 0;
369
370   // declare the branches
371   // first
372   tree->Branch("iSM", &iSM, "iSM/I");
373   tree->Branch("ReferenceTime", &iReferenceTime, "ReferenceTime/I");
374   // second  
375   tree->Branch( "LEDRefAmp", &rLEDRefAmp, Form("LEDRefAmp[%d]/F", AliEMCALGeoParams::fgkEMCALLEDRefs) );
376   tree->Branch( "LEDRefAmpRMS", &rLEDRefAmpRMS, Form("LEDRefAmpRMS[%d]/F", AliEMCALGeoParams::fgkEMCALLEDRefs) );
377   tree->Branch( "LEDRefHighLow", &iLEDRefHighLow, Form("LEDRefHighLow[%d]/I", AliEMCALGeoParams::fgkEMCALLEDRefs) );
378   tree->Branch( "Temperature", &temperature, Form("Temperature[%d]/F", AliEMCALGeoParams::fgkEMCALTempSensors) );
379   tree->Branch( "TemperatureRMS", &temperatureRMS, Form("TemperatureRMS[%d]/F", AliEMCALGeoParams::fgkEMCALTempSensors) );
380   // third: info for each tower; see if a 2D array works OK or if we'll have to use 1D arrays instead 
381   tree->Branch( "HighLow", &iHighLow, Form("HighLow[%d][%d]/I", AliEMCALGeoParams::fgkEMCALCols, AliEMCALGeoParams::fgkEMCALRows) );
382   tree->Branch( "LEDAmp", &rLEDAmp, Form("LEDAmp[%d][%d]/F", AliEMCALGeoParams::fgkEMCALCols, AliEMCALGeoParams::fgkEMCALRows) );
383   tree->Branch( "LEDAmpRMS", &rLEDAmpRMS, Form("LEDAmpRMS[%d][%d]/F", AliEMCALGeoParams::fgkEMCALCols, AliEMCALGeoParams::fgkEMCALRows) );
384
385   for (iSM = 0; iSM < fNSuperModule; iSM++) {
386     AliEMCALSuperModuleCalibReference * t = (AliEMCALSuperModuleCalibReference*) fSuperModuleData[iSM];
387
388     iSM = t->GetSuperModuleNum();
389     // first, overall values
390     iReferenceTime = t->GetReferenceTime();
391
392     // second: additional info for LED references and SM temperatures
393     for (Int_t j=0; j<AliEMCALGeoParams::fgkEMCALLEDRefs; j++) {
394       rLEDRefAmp[j] = t->GetLEDRefAmp(j);
395       rLEDRefAmpRMS[j] = t->GetLEDRefAmpRMS(j);
396       iLEDRefHighLow[j] = t->GetLEDRefHighLow(j);
397     }
398     for (Int_t j=0; j<AliEMCALGeoParams::fgkEMCALTempSensors; j++) {
399       temperature[j] = t->GetTemperature(j);
400       temperatureRMS[j] = t->GetTemperatureRMS(j);
401     }
402
403     // third: info for each tower
404     for (Int_t j=0; j<nAPDPerSM; j++) {
405       iCol = j / AliEMCALGeoParams::fgkEMCALRows;
406       iRow = j % AliEMCALGeoParams::fgkEMCALRows;
407
408       // help variables: possibly modified or swapped indices
409       int iColMod = iCol;
410       int iRowMod = iRow;
411       // assume that this info is already swapped and done for this basis?
412       if (swapSides) {
413         // C side, oriented differently than A side: swap is requested
414         iColMod = AliEMCALGeoParams::fgkEMCALCols-1 - iCol;
415         iRowMod = AliEMCALGeoParams::fgkEMCALRows-1 - iRow;
416       }
417
418       AliEMCALCalibReferenceVal * v = t->GetAPDVal(iCol, iRow);
419
420       iHighLow[iColMod][iRowMod] = v->GetHighLow();
421       rLEDAmp[iColMod][iRowMod] = v->GetLEDAmp();
422       rLEDAmpRMS[iColMod][iRowMod] = v->GetLEDAmpRMS();
423     }
424
425     tree->Fill();
426   } // i, SuperModule
427
428   tree->Write();
429   destFile.Close();
430
431   return;
432 }
433
434 //____________________________________________________________________________
435 AliEMCALCalibReference::~AliEMCALCalibReference()
436 {
437   fSuperModuleData.Delete();
438 }
439
440 //____________________________________________________________________________
441 AliEMCALSuperModuleCalibReference * AliEMCALCalibReference::GetSuperModuleCalibReferenceNum(Int_t supModIndex)const
442 {
443   for (int i=0; i<fNSuperModule; i++) {
444     AliEMCALSuperModuleCalibReference * t = (AliEMCALSuperModuleCalibReference*) fSuperModuleData[i];
445     if (t->GetSuperModuleNum() == supModIndex) {
446       return t;
447     }
448   }
449
450   // if we arrived here, then nothing was found.. just return a NULL pointer 
451   return NULL;
452 }
453