1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15 /* $Id: AliCaloCalibSignal.cxx $ */
17 //________________________________________________________________________
19 // A help class for monitoring and calibration tools: MOOD, AMORE etc.,
20 // It can be created and used a la (ctor):
22 //Create the object for making the histograms
23 fSignals = new AliCaloCalibSignal( fDetType );
24 // AliCaloCalibSignal knows how many modules we have for PHOS or EMCAL
25 fNumModules = fSignals->GetModules();
28 // fSignals->ProcessEvent(fCaloRawStream,fRawEventHeaderBase);
29 // asked to draw graphs or profiles:
30 // fSignals->GetGraphAmpVsTimeHighGain(module,column,row)->Draw("ap");
32 // fSignals->GetProfAmpVsTimeHighGain(module,column,row)->Draw();
34 //________________________________________________________________________
38 #include "AliRawEventHeaderBase.h"
39 #include "AliCaloRawStream.h"
42 #include "AliCaloCalibSignal.h"
44 ClassImp(AliCaloCalibSignal)
48 // ctor; initialize everything in order to avoid compiler warnings
49 // put some reasonable defaults
50 AliCaloCalibSignal::AliCaloCalibSignal(kDetType detectorType) :
59 fReqFractionAboveAmpCutVal(0.8),
60 fReqFractionAboveAmp(kTRUE),
68 //Default constructor. First we set the detector-type related constants.
69 if (detectorType == kPhos) {
70 fColumns = fgkPhosCols;
72 fModules = fgkPhosModules;
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;
80 fModules = fgkEmCalModules;
83 fDetType = detectorType;
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));
89 CreateGraphs(); // set up the TGraphs
91 // init TProfiles to NULL=0 also
92 memset(fProfAmpVsTimeHighGain, 0, sizeof(fProfAmpVsTimeHighGain));
93 memset(fProfAmpVsTimeLowGain, 0, sizeof(fProfAmpVsTimeLowGain));
97 //_____________________________________________________________________
98 AliCaloCalibSignal::~AliCaloCalibSignal()
103 //_____________________________________________________________________
104 void AliCaloCalibSignal::ClearObjects()
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]; }
114 memset(fGraphAmpVsTimeHighGain, 0, sizeof(fGraphAmpVsTimeHighGain));
115 memset(fGraphAmpVsTimeLowGain, 0, sizeof(fGraphAmpVsTimeLowGain));
116 memset(fProfAmpVsTimeHighGain, 0, sizeof(fProfAmpVsTimeHighGain));
117 memset(fProfAmpVsTimeLowGain, 0, sizeof(fProfAmpVsTimeLowGain));
123 //_____________________________________________________________________
124 AliCaloCalibSignal::AliCaloCalibSignal(const AliCaloCalibSignal &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())
142 // also the TGraph contents
146 // assignment operator; use copy ctor to make life easy..
147 //_____________________________________________________________________
148 AliCaloCalibSignal& AliCaloCalibSignal::operator = (const AliCaloCalibSignal &source)
150 // assignment operator; use copy ctor
151 if (&source == this) return *this;
153 new (this) AliCaloCalibSignal(source);
157 //_____________________________________________________________________
158 void AliCaloCalibSignal::CreateGraphs()
160 //Then, loop for the requested number of modules
162 for (int i = 0; i < fModules; i++) {
164 // Amplitude vs. Time graph for each channel
165 for(int ic=0;ic < fColumns;ic++){
166 for(int ir=0;ir < fRows;ir++){
168 int id = GetTowerNum(i, ic, ir);
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;
178 fGraphAmpVsTimeHighGain[id] = new TGraph();
179 fGraphAmpVsTimeHighGain[id]->SetName(name);
180 fGraphAmpVsTimeHighGain[id]->SetTitle(title);
181 fGraphAmpVsTimeHighGain[id]->SetMarkerStyle(20);
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;
191 fGraphAmpVsTimeLowGain[id] = new TGraph();
192 fGraphAmpVsTimeLowGain[id]->SetName(name);
193 fGraphAmpVsTimeLowGain[id]->SetTitle(title);
194 fGraphAmpVsTimeLowGain[id]->SetMarkerStyle(20);
202 //_____________________________________________________________________
203 void AliCaloCalibSignal::Reset()
205 Zero(); // set all counters to 0
206 ClearObjects(); // delete previous TGraphs and TProfiles
207 CreateGraphs(); // and create some new ones
211 //_____________________________________________________________________
212 void AliCaloCalibSignal::Zero()
214 // set all counters to 0; not cuts etc.though
218 fNAcceptedEvents = 0;
222 //_____________________________________________________________________
223 Bool_t AliCaloCalibSignal::CheckFractionAboveAmp(int *AmpVal, int nTotChan)
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) {
239 double fraction = (1.0*nAbove) / nTotChan;
241 if (fraction > fReqFractionAboveAmpCutVal) {
247 //_____________________________________________________________________
248 Bool_t AliCaloCalibSignal::AddInfo(const AliCaloCalibSignal *sig)
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..
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;
257 for (int i = 0; i < fModules; i++) {
258 for (int j = 0; j < fColumns; j++) {
259 for (int k = 0; k < fRows; k++) {
261 id = GetTowerNum(i,j,k);
263 if(fUseAverage){ // add to Profiles
264 if (sig->GetProfAmpVsTimeHighGain(id)) {
265 GetProfAmpVsTimeHighGain(id)->Add(sig->GetProfAmpVsTimeHighGain(id));
267 if (sig->GetProfAmpVsTimeLowGain(id)) {
268 GetProfAmpVsTimeLowGain(id)->Add(sig->GetProfAmpVsTimeLowGain(id));
271 else{ // add to Graphs
273 numGraphPoints= sig->GetGraphAmpVsTimeHighGain(id)->GetN();
274 if (numGraphPoints > 0) {
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]);
283 numGraphPoints= sig->GetGraphAmpVsTimeLowGain(id)->GetN();
284 if (numGraphPoints > 0) {
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]);
299 return kTRUE;//We succesfully added info from the supplied object
303 //_____________________________________________________________________
304 Bool_t AliCaloCalibSignal::ProcessEvent(AliCaloRawStream *in, AliRawEventHeaderBase *aliHeader)
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
309 fNEvents++; // one more event
311 // PHOS has more towers than EMCAL, so use PHOS numbers to set array sizes
312 int AmpValHighGain[fgkMaxTowers];
313 int AmpValLowGain[fgkMaxTowers];
315 memset(AmpValHighGain, 0, sizeof(AmpValHighGain));
316 memset(AmpValLowGain, 0, sizeof(AmpValLowGain));
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
322 // Number of Low and High gain channels for this event:
326 int TowerNum = 0; // array index for TGraphs etc.
328 // loop first to get the fraction of channels with amplitudes above cut
330 sample = in->GetSignal(); //Get the adc signal
331 if (sample < min) min = sample;
332 if (sample > max) max = sample;
334 if ( i >= in->GetTimeLength()) {
335 //If we're here then we're done with this tower
336 gain = 1 - in->IsLowGain();
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?)
345 if (arrayPos < 0 || arrayPos >= fModules) {
346 printf("Oh no: arrayPos = %i.\n", arrayPos);
349 // get tower number for AmpVal array
350 TowerNum = GetTowerNum(arrayPos, in->GetColumn(), in->GetRow());
353 // fill amplitude into the array
354 AmpValLowGain[TowerNum] = max - min;
357 else if (gain==1) {//fill the high gain ones
358 // fill amplitude into the array
359 AmpValHighGain[TowerNum] = max - min;
364 max = fgkSampleMin; min = fgkSampleMax;
367 }//End if end of tower
369 }//end while, of stream
371 // now check if it was a led event, only use high gain (that should be sufficient)
372 if (fReqFractionAboveAmp) {
373 bool ok = CheckFractionAboveAmp(AmpValHighGain, nHighChan);
374 if (!ok) return false; // skip event
377 fNAcceptedEvents++; // one more event accepted
379 if (fStartTime == 0) { // if start-timestamp wasn't set,we'll pick it up from the first event we encounter
380 fStartTime = aliHeader->Get("Timestamp");
383 fHour = (aliHeader->Get("Timestamp")-fStartTime)/(double)fgkNumSecInHr;
384 if (fLatestHour < fHour) {
388 // it is a led event, now fill graphs (maybe profiles later)
389 for(int i=0;i<fModules;i++){
390 for(int j=0;j<fColumns;j++){
391 for(int k=0;k<fRows;k++){
393 TowerNum = GetTowerNum(i, j, k);
395 if(AmpValHighGain[TowerNum]) {
396 fGraphAmpVsTimeHighGain[TowerNum]->SetPoint(fNHighGain[TowerNum]++,fHour,AmpValHighGain[TowerNum]);
398 if(AmpValLowGain[TowerNum]) {
399 fGraphAmpVsTimeLowGain[TowerNum]->SetPoint(fNLowGain[TowerNum]++,fHour,AmpValLowGain[TowerNum]);
408 //_____________________________________________________________________
409 void AliCaloCalibSignal::CreateProfile(int imod, int ic, int ir, int towerId, int gain,
410 int nbins, double min, double max)
411 { //! create/setup a TProfile
414 name = "fProfAmpVsTimeLowGain_";
415 title = "Amp vs. Time Low Gain Mod ";
417 else if (gain == 1) {
418 name = "fProfAmpVsTimeHighGain_";
419 title = "Amp vs. Time High Gain Mod ";
422 name += "_"; name += ic;
423 name += "_"; name += ir;
425 title += " Col "; title += ic;
426 title += " Row "; title += ir;
428 // use "s" option for RMS
430 fProfAmpVsTimeLowGain[towerId] = new TProfile(name,title, nbins, min, max,"s");
433 fProfAmpVsTimeHighGain[towerId] = new TProfile(name,title, nbins, min, max,"s");
438 //_____________________________________________________________________
439 Bool_t AliCaloCalibSignal::Save(TString fileName, Bool_t saveEmptyGraphs)
441 //Saves all the histograms (or profiles, to be accurate) to the designated file
443 TFile destFile(fileName, "recreate");
445 if (destFile.IsZombie()) {
451 // setup variables for the TProfile plot
456 if (fSecInAverage > 0) {
457 numProfBins = (int)( (fLatestHour*fgkNumSecInHr)/fSecInAverage + 1 ); // round-off
459 numProfBins += 2; // add extra buffer : first and last
460 double binSize = 1.0*fSecInAverage / fgkNumSecInHr;
462 timeMax = timeMin + numProfBins*binSize;
465 int numGraphPoints= 0;
467 for (int i = 0; i < fModules; i++) {
469 for(int ic=0;ic < fColumns;ic++){
470 for(int ir=0;ir < fRows;ir++){
472 TowerNum = GetTowerNum(i, ic, ir);
475 numGraphPoints= fGraphAmpVsTimeHighGain[TowerNum]->GetN();
476 if( numGraphPoints>0 || saveEmptyGraphs) {
478 // average the graphs points over time if requested and put them in a profile plot
479 if(fUseAverage && numGraphPoints>0) {
482 double *graphX = fGraphAmpVsTimeHighGain[TowerNum]->GetX();
483 double *graphY = fGraphAmpVsTimeHighGain[TowerNum]->GetY();
485 // create the TProfile: 1 is for High gain
486 CreateProfile(i, ic, ir, TowerNum, 1,
487 numProfBins, timeMin, timeMax);
489 // loop over graph points and fill profile
490 for(int ip=0; ip < numGraphPoints; ip++){
491 fProfAmpVsTimeHighGain[TowerNum]->Fill(graphX[ip],graphY[ip]);
494 fProfAmpVsTimeHighGain[TowerNum]->GetXaxis()->SetTitle("Hours");
495 fProfAmpVsTimeHighGain[TowerNum]->GetYaxis()->SetTitle("MaxAmplitude - Pedestal");
496 fProfAmpVsTimeHighGain[TowerNum]->Write();
500 //otherwise, just save the graphs and forget the profiling
501 fGraphAmpVsTimeHighGain[TowerNum]->GetXaxis()->SetTitle("Hours");
502 fGraphAmpVsTimeHighGain[TowerNum]->GetYaxis()->SetTitle("MaxAmplitude - Pedestal");
503 fGraphAmpVsTimeHighGain[TowerNum]->Write();
506 } // low gain graph info should be saved in one form or another
508 // 2nd: now go to the low gain case
509 numGraphPoints= fGraphAmpVsTimeLowGain[TowerNum]->GetN();
510 if( numGraphPoints>0 || saveEmptyGraphs) {
512 // average the graphs points over time if requested and put them in a profile plot
513 if(fUseAverage && numGraphPoints>0) {
515 double *graphX = fGraphAmpVsTimeLowGain[TowerNum]->GetX();
516 double *graphY = fGraphAmpVsTimeLowGain[TowerNum]->GetY();
518 // create the TProfile: 0 is for Low gain
519 CreateProfile(i, ic, ir, TowerNum, 0,
520 numProfBins, timeMin, timeMax);
522 // loop over graph points and fill profile
523 for(int ip=0; ip < numGraphPoints; ip++){
524 fProfAmpVsTimeLowGain[TowerNum]->Fill(graphX[ip],graphY[ip]);
527 fProfAmpVsTimeLowGain[TowerNum]->GetXaxis()->SetTitle("Hours");
528 fProfAmpVsTimeLowGain[TowerNum]->GetYaxis()->SetTitle("MaxAmplitude - Pedestal");
529 fProfAmpVsTimeLowGain[TowerNum]->Write();
533 //otherwise, just save the graphs and forget the profiling
534 fGraphAmpVsTimeLowGain[TowerNum]->GetXaxis()->SetTitle("Hours");
535 fGraphAmpVsTimeLowGain[TowerNum]->GetYaxis()->SetTitle("MaxAmplitude - Pedestal");
536 fGraphAmpVsTimeLowGain[TowerNum]->Write();
539 } // low gain graph info should be saved in one form or another