]> git.uio.no Git - u/mrichter/AliRoot.git/blame - EMCAL/AliCaloCalibSignal.cxx
silvermy@ornl.gov - safety check in AliCaloCalibSignal, and saving objects/class...
[u/mrichter/AliRoot.git] / EMCAL / AliCaloCalibSignal.cxx
CommitLineData
bd83f412 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: AliCaloCalibSignal.cxx $ */
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 fSignals = new AliCaloCalibSignal( fDetType );
24 // AliCaloCalibSignal knows how many modules we have for PHOS or EMCAL
25 fNumModules = fSignals->GetModules();
26*/
27// fed an event:
28// fSignals->ProcessEvent(fCaloRawStream,fRawEventHeaderBase);
29// asked to draw graphs or profiles:
30// fSignals->GetGraphAmpVsTimeHighGain(module,column,row)->Draw("ap");
31// or
32// fSignals->GetProfAmpVsTimeHighGain(module,column,row)->Draw();
33// etc.
34//________________________________________________________________________
35
36#include "TFile.h"
37
38#include "AliRawEventHeaderBase.h"
39#include "AliCaloRawStream.h"
40
41//The include file
42#include "AliCaloCalibSignal.h"
43
44ClassImp(AliCaloCalibSignal)
45
46using namespace std;
47
48// ctor; initialize everything in order to avoid compiler warnings
49// put some reasonable defaults
50AliCaloCalibSignal::AliCaloCalibSignal(kDetType detectorType) :
51 TObject(),
52 fDetType(kNone),
53 fColumns(0),
54 fRows(0),
55 fModules(0),
56 fRunNumber(-1),
57 fStartTime(0),
58 fAmpCut(50),
59 fReqFractionAboveAmpCutVal(0.8),
60 fReqFractionAboveAmp(kTRUE),
61 fHour(0),
62 fLatestHour(0),
63 fUseAverage(kTRUE),
64 fSecInAverage(1800),
65 fNEvents(0),
66 fNAcceptedEvents(0)
67{
68 //Default constructor. First we set the detector-type related constants.
69 if (detectorType == kPhos) {
70 fColumns = fgkPhosCols;
71 fRows = fgkPhosRows;
72 fModules = fgkPhosModules;
73 }
74 else {
75 //We'll just trust the enum to keep everything in line, so that if detectorType
76 //isn't kPhos then it is kEmCal. Note, however, that this is not necessarily the
77 //case, if someone intentionally gives another number
78 fColumns = fgkEmCalCols;
79 fRows = fgkEmCalRows;
80 fModules = fgkEmCalModules;
81 }
82
83 fDetType = detectorType;
84
85 // Set the number of points for each Amp vs. Time graph to 0
86 memset(fNHighGain, 0, sizeof(fNHighGain));
87 memset(fNLowGain, 0, sizeof(fNLowGain));
88
89 CreateGraphs(); // set up the TGraphs
90
91 // init TProfiles to NULL=0 also
92 memset(fProfAmpVsTimeHighGain, 0, sizeof(fProfAmpVsTimeHighGain));
93 memset(fProfAmpVsTimeLowGain, 0, sizeof(fProfAmpVsTimeLowGain));
94}
95
96// dtor
97//_____________________________________________________________________
98AliCaloCalibSignal::~AliCaloCalibSignal()
99{
100 ClearObjects();
101}
102
103//_____________________________________________________________________
104void AliCaloCalibSignal::ClearObjects()
105{
106 // delete what was created in the ctor (TGraphs), and possible later (TProfiles)
107 for (int i=0; i<fgkMaxTowers; i++) {
108 if ( fGraphAmpVsTimeHighGain[i] ) { delete fGraphAmpVsTimeHighGain[i]; }
109 if ( fGraphAmpVsTimeLowGain[i] ) { delete fGraphAmpVsTimeLowGain[i]; }
110 if ( fProfAmpVsTimeHighGain[i] ) { delete fProfAmpVsTimeHighGain[i]; }
111 if ( fProfAmpVsTimeLowGain[i] ) { delete fProfAmpVsTimeLowGain[i]; }
112 }
113 // set pointers
114 memset(fGraphAmpVsTimeHighGain, 0, sizeof(fGraphAmpVsTimeHighGain));
115 memset(fGraphAmpVsTimeLowGain, 0, sizeof(fGraphAmpVsTimeLowGain));
116 memset(fProfAmpVsTimeHighGain, 0, sizeof(fProfAmpVsTimeHighGain));
117 memset(fProfAmpVsTimeLowGain, 0, sizeof(fProfAmpVsTimeLowGain));
118
119 return;
120}
121
122// copy ctor
123//_____________________________________________________________________
124AliCaloCalibSignal::AliCaloCalibSignal(const AliCaloCalibSignal &sig) :
125 TObject(sig),
126 fDetType(sig.GetDetectorType()),
127 fColumns(sig.GetColumns()),
128 fRows(sig.GetRows()),
129 fModules(sig.GetModules()),
130 fRunNumber(sig.GetRunNumber()),
131 fStartTime(sig.GetStartTime()),
132 fAmpCut(sig.GetAmpCut()),
133 fReqFractionAboveAmpCutVal(sig.GetReqFractionAboveAmpCutVal()),
134 fReqFractionAboveAmp(sig.GetReqFractionAboveAmp()),
135 fHour(sig.GetHour()),
136 fLatestHour(sig.GetLatestHour()),
137 fUseAverage(sig.GetUseAverage()),
138 fSecInAverage(sig.GetSecInAverage()),
139 fNEvents(sig.GetNEvents()),
140 fNAcceptedEvents(sig.GetNAcceptedEvents())
141{
142 // also the TGraph contents
143 AddInfo(&sig);
144}
145
146// assignment operator; use copy ctor to make life easy..
147//_____________________________________________________________________
148AliCaloCalibSignal& AliCaloCalibSignal::operator = (const AliCaloCalibSignal &source)
149{
150 // assignment operator; use copy ctor
151 if (&source == this) return *this;
152
153 new (this) AliCaloCalibSignal(source);
154 return *this;
155}
156
157//_____________________________________________________________________
158void AliCaloCalibSignal::CreateGraphs()
159{
160 //Then, loop for the requested number of modules
161 TString title, name;
162 for (int i = 0; i < fModules; i++) {
163
164 // Amplitude vs. Time graph for each channel
165 for(int ic=0;ic < fColumns;ic++){
166 for(int ir=0;ir < fRows;ir++){
167
168 int id = GetTowerNum(i, ic, ir);
169
170 // high gain graph
171 name = "fGraphAmpVsTimeHighGain_"; name += i;
172 name += "_"; name += ic;
173 name += "_"; name += ir;
174 title = "Amp vs. Time High Gain Mod "; title += i;
175 title += " Col "; title += ic;
176 title += " Row "; title += ir;
177
178 fGraphAmpVsTimeHighGain[id] = new TGraph();
179 fGraphAmpVsTimeHighGain[id]->SetName(name);
180 fGraphAmpVsTimeHighGain[id]->SetTitle(title);
181 fGraphAmpVsTimeHighGain[id]->SetMarkerStyle(20);
182
183 // Low Gain
184 name = "fGraphAmpVsTimeLowGain_"; name += i;
185 name += "_"; name += ic;
186 name += "_"; name += ir;
187 title = "Amp vs. Time Low Gain Mod "; title += i;
188 title += " Col "; title += ic;
189 title += " Row "; title += ir;
190
191 fGraphAmpVsTimeLowGain[id] = new TGraph();
192 fGraphAmpVsTimeLowGain[id]->SetName(name);
193 fGraphAmpVsTimeLowGain[id]->SetTitle(title);
194 fGraphAmpVsTimeLowGain[id]->SetMarkerStyle(20);
195
196 }
197 }
198
199 }//end for nModules
200}
201
202//_____________________________________________________________________
203void AliCaloCalibSignal::Reset()
204{
205 Zero(); // set all counters to 0
206 ClearObjects(); // delete previous TGraphs and TProfiles
207 CreateGraphs(); // and create some new ones
208 return;
209}
210
211//_____________________________________________________________________
212void AliCaloCalibSignal::Zero()
213{
214 // set all counters to 0; not cuts etc.though
215 fHour = 0;
216 fLatestHour = 0;
217 fNEvents = 0;
218 fNAcceptedEvents = 0;
219 return;
220}
221
222//_____________________________________________________________________
223Bool_t AliCaloCalibSignal::CheckFractionAboveAmp(int *AmpVal, int nTotChan)
224{
225 int nAbove = 0;
226
227 int TowerNum = 0;
228 for (int i = 0; i<fModules; i++) {
229 for (int j = 0; j<fColumns; j++) {
230 for (int k = 0; k<fRows; k++) {
231 TowerNum = GetTowerNum(i,j,k);
232 if (AmpVal[TowerNum] > fAmpCut) {
233 nAbove++;
234 }
235 }
236 }
237 }
238
239 double fraction = (1.0*nAbove) / nTotChan;
240
241 if (fraction > fReqFractionAboveAmpCutVal) {
242 return true;
243 }
244 else return false;
245}
246
247//_____________________________________________________________________
248Bool_t AliCaloCalibSignal::AddInfo(const AliCaloCalibSignal *sig)
249{
250 // just do this for the basic graphs/profiles that get filled in ProcessEvent
251 // may not have data for all channels, but let's just Add everything..
4fb34e09 252 // Note: this method will run into problems with TProfile adding if the binning of
253 // the local profiles is not the same as those provided by the argument *sig..
254 int numGraphPoints = 0;
255 int id = 0;
256 int ip = 0;
bd83f412 257 for (int i = 0; i < fModules; i++) {
258 for (int j = 0; j < fColumns; j++) {
259 for (int k = 0; k < fRows; k++) {
260
4fb34e09 261 id = GetTowerNum(i,j,k);
262
263 if(fUseAverage){ // add to Profiles
264 if (sig->GetProfAmpVsTimeHighGain(id)) {
265 GetProfAmpVsTimeHighGain(id)->Add(sig->GetProfAmpVsTimeHighGain(id));
266 }
267 if (sig->GetProfAmpVsTimeLowGain(id)) {
268 GetProfAmpVsTimeLowGain(id)->Add(sig->GetProfAmpVsTimeLowGain(id));
269 }
bd83f412 270 }
4fb34e09 271 else{ // add to Graphs
272 // high gain
273 numGraphPoints= sig->GetGraphAmpVsTimeHighGain(id)->GetN();
274 if (numGraphPoints > 0) {
275 // get the values
276 double *graphX = sig->GetGraphAmpVsTimeHighGain(id)->GetX();
277 double *graphY = sig->GetGraphAmpVsTimeHighGain(id)->GetY();
278 for(ip=0; ip < numGraphPoints; ip++){
279 fGraphAmpVsTimeHighGain[id]->SetPoint(fNHighGain[id]++,graphX[ip],graphY[ip]);
280 }
281 }
282 // low gain
283 numGraphPoints= sig->GetGraphAmpVsTimeLowGain(id)->GetN();
284 if (numGraphPoints > 0) {
285 // get the values
286 double *graphX = sig->GetGraphAmpVsTimeLowGain(id)->GetX();
287 double *graphY = sig->GetGraphAmpVsTimeLowGain(id)->GetY();
288 for(ip=0; ip < numGraphPoints; ip++){
289 fGraphAmpVsTimeLowGain[id]->SetPoint(fNLowGain[id]++,graphX[ip],graphY[ip]);
290 }
291 }
292
bd83f412 293 }
294
295 }//end for nModules
296 }//end for nColumns
297 }//end for nRows
298
299 return kTRUE;//We succesfully added info from the supplied object
300}
301
302
303//_____________________________________________________________________
304Bool_t AliCaloCalibSignal::ProcessEvent(AliCaloRawStream *in, AliRawEventHeaderBase *aliHeader)
305{
306 // Method to process=analyze one event in the data stream
307 if (!in) return kFALSE; //Return right away if there's a null pointer
308
309 fNEvents++; // one more event
310
311 // PHOS has more towers than EMCAL, so use PHOS numbers to set array sizes
312 int AmpValHighGain[fgkMaxTowers];
313 int AmpValLowGain[fgkMaxTowers];
314
315 memset(AmpValHighGain, 0, sizeof(AmpValHighGain));
316 memset(AmpValLowGain, 0, sizeof(AmpValLowGain));
317
318 int sample, i = 0; //The sample temp, and the sample number in current event.
319 int max = fgkSampleMin, min = fgkSampleMax;//Use these for picking the signal
320 int gain = 0;
321
322 // Number of Low and High gain channels for this event:
323 int nLowChan = 0;
324 int nHighChan = 0;
325
326 int TowerNum = 0; // array index for TGraphs etc.
327
328 // loop first to get the fraction of channels with amplitudes above cut
329 while (in->Next()) {
330 sample = in->GetSignal(); //Get the adc signal
331 if (sample < min) min = sample;
332 if (sample > max) max = sample;
333 i++;
334 if ( i >= in->GetTimeLength()) {
335 //If we're here then we're done with this tower
336 gain = 1 - in->IsLowGain();
337
338 int arrayPos = in->GetModule(); //The modules are numbered starting from 0
339 if (arrayPos >= fModules) {
340 //TODO: return an error message, if appopriate (perhaps if debug>0?)
341 return kFALSE;
342 }
343
344 //Debug
345 if (arrayPos < 0 || arrayPos >= fModules) {
346 printf("Oh no: arrayPos = %i.\n", arrayPos);
347 }
348
349 // get tower number for AmpVal array
350 TowerNum = GetTowerNum(arrayPos, in->GetColumn(), in->GetRow());
351
352 if (gain == 0) {
353 // fill amplitude into the array
354 AmpValLowGain[TowerNum] = max - min;
355 nLowChan++;
356 }
357 else if (gain==1) {//fill the high gain ones
358 // fill amplitude into the array
359 AmpValHighGain[TowerNum] = max - min;
360 nHighChan++;
361 }//end if gain
362
363
364 max = fgkSampleMin; min = fgkSampleMax;
365 i = 0;
366
367 }//End if end of tower
368
369 }//end while, of stream
370
371 // now check if it was a led event, only use high gain (that should be sufficient)
372 if (fReqFractionAboveAmp) {
452729ca 373 bool ok = false;
374 if (nHighChan > 0) {
375 ok = CheckFractionAboveAmp(AmpValHighGain, nHighChan);
376 }
bd83f412 377 if (!ok) return false; // skip event
378 }
379
380 fNAcceptedEvents++; // one more event accepted
381
382 if (fStartTime == 0) { // if start-timestamp wasn't set,we'll pick it up from the first event we encounter
383 fStartTime = aliHeader->Get("Timestamp");
384 }
385
386 fHour = (aliHeader->Get("Timestamp")-fStartTime)/(double)fgkNumSecInHr;
387 if (fLatestHour < fHour) {
388 fLatestHour = fHour;
389 }
390
391 // it is a led event, now fill graphs (maybe profiles later)
392 for(int i=0;i<fModules;i++){
393 for(int j=0;j<fColumns;j++){
394 for(int k=0;k<fRows;k++){
395
396 TowerNum = GetTowerNum(i, j, k);
397
398 if(AmpValHighGain[TowerNum]) {
399 fGraphAmpVsTimeHighGain[TowerNum]->SetPoint(fNHighGain[TowerNum]++,fHour,AmpValHighGain[TowerNum]);
400 }
401 if(AmpValLowGain[TowerNum]) {
402 fGraphAmpVsTimeLowGain[TowerNum]->SetPoint(fNLowGain[TowerNum]++,fHour,AmpValLowGain[TowerNum]);
403 }
404 }
405 }
406 }
407
408 return kTRUE;
409}
410
411//_____________________________________________________________________
412void AliCaloCalibSignal::CreateProfile(int imod, int ic, int ir, int towerId, int gain,
413 int nbins, double min, double max)
414{ //! create/setup a TProfile
415 TString title, name;
416 if (gain == 0) {
417 name = "fProfAmpVsTimeLowGain_";
418 title = "Amp vs. Time Low Gain Mod ";
419 }
420 else if (gain == 1) {
421 name = "fProfAmpVsTimeHighGain_";
422 title = "Amp vs. Time High Gain Mod ";
423 }
424 name += imod;
425 name += "_"; name += ic;
426 name += "_"; name += ir;
427 title += imod;
428 title += " Col "; title += ic;
429 title += " Row "; title += ir;
430
431 // use "s" option for RMS
432 if (gain==0) {
433 fProfAmpVsTimeLowGain[towerId] = new TProfile(name,title, nbins, min, max,"s");
434 }
435 else if (gain==1) {
436 fProfAmpVsTimeHighGain[towerId] = new TProfile(name,title, nbins, min, max,"s");
437 }
438
439 return;
440}
441//_____________________________________________________________________
442Bool_t AliCaloCalibSignal::Save(TString fileName, Bool_t saveEmptyGraphs)
443{
444 //Saves all the histograms (or profiles, to be accurate) to the designated file
445
446 TFile destFile(fileName, "recreate");
447
448 if (destFile.IsZombie()) {
449 return kFALSE;
450 }
451
452 destFile.cd();
453
454 // setup variables for the TProfile plot
455 int numProfBins = 0;
456 double timeMin = 0;
457 double timeMax = 0;
458 if (fUseAverage) {
459 if (fSecInAverage > 0) {
460 numProfBins = (int)( (fLatestHour*fgkNumSecInHr)/fSecInAverage + 1 ); // round-off
461 }
462 numProfBins += 2; // add extra buffer : first and last
463 double binSize = 1.0*fSecInAverage / fgkNumSecInHr;
464 timeMin = - binSize;
465 timeMax = timeMin + numProfBins*binSize;
466 }
467
468 int numGraphPoints= 0;
469 int TowerNum = 0;
470 for (int i = 0; i < fModules; i++) {
471
472 for(int ic=0;ic < fColumns;ic++){
473 for(int ir=0;ir < fRows;ir++){
474
475 TowerNum = GetTowerNum(i, ic, ir);
476
477 // 1st: high gain
478 numGraphPoints= fGraphAmpVsTimeHighGain[TowerNum]->GetN();
479 if( numGraphPoints>0 || saveEmptyGraphs) {
480
481 // average the graphs points over time if requested and put them in a profile plot
482 if(fUseAverage && numGraphPoints>0) {
483
484 // get the values
485 double *graphX = fGraphAmpVsTimeHighGain[TowerNum]->GetX();
486 double *graphY = fGraphAmpVsTimeHighGain[TowerNum]->GetY();
487
488 // create the TProfile: 1 is for High gain
489 CreateProfile(i, ic, ir, TowerNum, 1,
490 numProfBins, timeMin, timeMax);
491
492 // loop over graph points and fill profile
493 for(int ip=0; ip < numGraphPoints; ip++){
494 fProfAmpVsTimeHighGain[TowerNum]->Fill(graphX[ip],graphY[ip]);
495 }
496
497 fProfAmpVsTimeHighGain[TowerNum]->GetXaxis()->SetTitle("Hours");
498 fProfAmpVsTimeHighGain[TowerNum]->GetYaxis()->SetTitle("MaxAmplitude - Pedestal");
499 fProfAmpVsTimeHighGain[TowerNum]->Write();
500
501 }
502 else{
503 //otherwise, just save the graphs and forget the profiling
504 fGraphAmpVsTimeHighGain[TowerNum]->GetXaxis()->SetTitle("Hours");
505 fGraphAmpVsTimeHighGain[TowerNum]->GetYaxis()->SetTitle("MaxAmplitude - Pedestal");
506 fGraphAmpVsTimeHighGain[TowerNum]->Write();
507 }
508
509 } // low gain graph info should be saved in one form or another
510
511 // 2nd: now go to the low gain case
512 numGraphPoints= fGraphAmpVsTimeLowGain[TowerNum]->GetN();
513 if( numGraphPoints>0 || saveEmptyGraphs) {
514
515 // average the graphs points over time if requested and put them in a profile plot
516 if(fUseAverage && numGraphPoints>0) {
517
518 double *graphX = fGraphAmpVsTimeLowGain[TowerNum]->GetX();
519 double *graphY = fGraphAmpVsTimeLowGain[TowerNum]->GetY();
520
521 // create the TProfile: 0 is for Low gain
522 CreateProfile(i, ic, ir, TowerNum, 0,
523 numProfBins, timeMin, timeMax);
524
525 // loop over graph points and fill profile
526 for(int ip=0; ip < numGraphPoints; ip++){
527 fProfAmpVsTimeLowGain[TowerNum]->Fill(graphX[ip],graphY[ip]);
528 }
529
530 fProfAmpVsTimeLowGain[TowerNum]->GetXaxis()->SetTitle("Hours");
531 fProfAmpVsTimeLowGain[TowerNum]->GetYaxis()->SetTitle("MaxAmplitude - Pedestal");
532 fProfAmpVsTimeLowGain[TowerNum]->Write();
533
534 }
535 else{
536 //otherwise, just save the graphs and forget the profiling
537 fGraphAmpVsTimeLowGain[TowerNum]->GetXaxis()->SetTitle("Hours");
538 fGraphAmpVsTimeLowGain[TowerNum]->GetYaxis()->SetTitle("MaxAmplitude - Pedestal");
539 fGraphAmpVsTimeLowGain[TowerNum]->Write();
540 }
541
542 } // low gain graph info should be saved in one form or another
543
544 } // fRows
545 } // fColumns
546
547 } // fModules
548 destFile.Close();
549
550 return kTRUE;
551}