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 **************************************************************************/
27 #include <TDirectory.h>
30 #include "AliRawReader.h"
31 #include "AliRawReaderRoot.h"
32 #include "AliRawReaderDate.h"
33 #include "AliTPCRawStream.h"
34 #include "AliTPCCalROC.h"
35 #include "AliTPCROC.h"
36 #include "AliMathBase.h"
37 #include "TTreeStream.h"
38 #include "AliTPCRawStreamFast.h"
44 #include "AliTPCCalibPedestal.h"
47 ///////////////////////////////////////////////////////////////////////////////////////
48 // Implementation of the TPC pedestal and noise calibration
50 // Origin: Jens Wiechula, Marian Ivanov J.Wiechula@gsi.de, Marian.Ivanov@cern.ch
53 // *************************************************************************************
54 // * Class Description *
55 // *************************************************************************************
59 // Raw pedestal data is processed by calling one of the ProcessEvent(...) functions
60 // (see below). These in the end call the Update(...) function, where the data is filled
63 // For each ROC one TH2F histo (ROC channel vs. ADC channel) is created when
64 // it is filled for the first time (GetHistoPedestal(ROC,kTRUE)). All histos are stored in the
65 // TObjArray fHistoPedestalArray.
67 // For a fast filling of the histogram the corresponding bin number of the channel and ADC channel
68 // is computed by hand and the histogram array is accessed directly via its pointer.
69 // ATTENTION: Doing so the the entry counter of the histogram is not increased
70 // this means that e.g. the colz draw option gives an empty plot unless
71 // calling 'histo->SetEntries(1)' before drawing.
73 // After accumulating the desired statistics the Analyse() function has to be called.
74 // Whithin this function the pedestal and noise values are calculated for each pad, using
75 // the fast gaus fit function AliMathBase::FitGaus(...), and the calibration
76 // storage classes (AliTPCCalROC) are filled for each ROC.
77 // The calibration information is stored in the TObjArrays fCalRocArrayPedestal and fCalRocArrayRMS;
81 // User interface for filling data:
82 // --------------------------------
84 // To Fill information one of the following functions can be used:
86 // Bool_t ProcessEvent(eventHeaderStruct *event);
87 // - process Date event
88 // - use AliTPCRawReaderDate and call ProcessEvent(AliRawReader *rawReader)
90 // Bool_t ProcessEvent(AliRawReader *rawReader);
91 // - process AliRawReader event
92 // - use AliTPCRawStream to loop over data and call ProcessEvent(AliTPCRawStream *rawStream)
94 // Bool_t ProcessEvent(AliTPCRawStream *rawStream);
95 // - process event from AliTPCRawStream
96 // - call Update function for signal filling
98 // Int_t Update(const Int_t isector, const Int_t iRow, const Int_t
99 // iPad, const Int_t iTimeBin, const Float_t signal);
100 // - directly fill signal information (sector, row, pad, time bin, pad)
101 // to the reference histograms
103 // It is also possible to merge two independently taken calibrations using the function
105 // void Merge(AliTPCCalibPedestal *ped)
106 // - copy histograms in 'ped' if the do not exist in this instance
107 // - Add histograms in 'ped' to the histograms in this instance if the allready exist
108 // - After merging call Analyse again!
112 // -- example: filling data using root raw data:
113 // void fillPedestal(Char_t *filename)
115 // rawReader = new AliRawReaderRoot(fileName);
116 // if ( !rawReader ) return;
117 // AliTPCCalibPedestal *calib = new AliTPCCalibPedestal;
118 // while (rawReader->NextEvent()){
119 // calib->ProcessEvent(rawReader);
122 // calib->DumpToFile("PedestalData.root");
128 // What kind of information is stored and how to retrieve them:
129 // ------------------------------------------------------------
131 // - Accessing the 'Reference Histograms' (pedestal distribution histograms):
133 // TH2F *GetHistoPedestal(Int_t sector);
135 // - Accessing the calibration storage objects:
137 // AliTPCCalROC *GetCalRocPedestal(Int_t sector); - for the pedestal values
138 // AliTPCCalROC *GetCalRocNoise(Int_t sector); - for the Noise values
140 // example for visualisation:
141 // if the file "PedestalData.root" was created using the above example one could do the following:
143 // TFile filePedestal("PedestalData.root")
144 // AliTPCCalibPedestal *ped = (AliTPCCalibPedestal*)filePedestal->Get("AliTPCCalibPedestal");
145 // ped->GetCalRocPedestal(0)->Draw("colz");
146 // ped->GetCalRocRMS(0)->Draw("colz");
148 // or use the AliTPCCalPad functionality:
149 // AliTPCCalPad padPedestal(ped->GetCalPadPedestal());
150 // AliTPCCalPad padNoise(ped->GetCalPadRMS());
151 // padPedestal->MakeHisto2D()->Draw("colz"); //Draw A-Side Pedestal Information
152 // padNoise->MakeHisto2D()->Draw("colz"); //Draw A-Side Noise Information
156 example: fill pedestal with gausschen noise
157 AliTPCCalibPedestal ped;
161 TCanvas* c1 = new TCanvas;
164 ped.GetHistoPedestal(0)->SetEntries(1); //needed in order for colz to work, reason: fast filling does not increase the entries counter
165 ped.GetHistoPedestal(0)->Draw("colz");
167 ped.GetHistoPedestal(36)->SetEntries(1); //needed in order for colz to work, reason: fast filling does not increase the entries counter
168 ped.GetHistoPedestal(36)->Draw("colz");
169 TCanvas* c2 = new TCanvas;
172 ped.GetCalRocPedestal(0)->Draw("colz");
174 ped.GetCalRocRMS(0)->Draw("colz");
176 ped.GetCalRocPedestal(36)->Draw("colz");
178 ped.GetCalRocRMS(36)->Draw("colz");
182 // Time dependent pedestals:
184 // If wished there is the possibility to calculate for each channel and time bin
185 // the mean pedestal [pedestals(t)]. This is done by
187 // 1) setting SetTimeAnalysis(kTRUE),
188 // 2) processing the data by looping over the events using ProcessEvent(..)
189 // 3) calling the Analyse() and AnalyseTime(nevents) functions (providing nevents)
190 // 4) getting the pedestals(t) using TArrayF **timePed = calibPedestal.GetTimePedestals();
191 // 5) looking at values using timePed[row][pad].At(timebin)
193 // This functionality is intended to be used on an LDC bu the detector algorithm
194 // (TPCPEDESTALda) to generate a data set used for configuration of the pattern
195 // memory for baseline subtraction in the ALTROs. Later the information should also
196 // be stored as reference data.
200 ClassImp(AliTPCCalibPedestal)
202 AliTPCCalibPedestal::AliTPCCalibPedestal() : /*FOLD00*/
208 fOldRCUformat(kTRUE),
209 fTimeAnalysis(kFALSE),
210 fROC(AliTPCROC::Instance()),
212 fCalRocArrayPedestal(72),
214 fHistoPedestalArray(72),
218 // default constructor
223 //_____________________________________________________________________
224 AliTPCCalibPedestal::AliTPCCalibPedestal(const AliTPCCalibPedestal &ped) : /*FOLD00*/
226 fFirstTimeBin(ped.GetFirstTimeBin()),
227 fLastTimeBin(ped.GetLastTimeBin()),
228 fAdcMin(ped.GetAdcMin()),
229 fAdcMax(ped.GetAdcMax()),
230 fOldRCUformat(ped.fOldRCUformat),
231 fTimeAnalysis(ped.fTimeAnalysis),
232 fROC(AliTPCROC::Instance()),
234 fCalRocArrayPedestal(72),
236 fHistoPedestalArray(72),
237 fTimeSignal(ped.fTimeSignal)
242 for (Int_t iSec = 0; iSec < 72; ++iSec){
243 const AliTPCCalROC *calPed = (AliTPCCalROC*)ped.fCalRocArrayPedestal.UncheckedAt(iSec);
244 const AliTPCCalROC *calRMS = (AliTPCCalROC*)ped.fCalRocArrayRMS.UncheckedAt(iSec);
245 const TH2F *hPed = (TH2F*)ped.fHistoPedestalArray.UncheckedAt(iSec);
247 if ( calPed != 0x0 ) fCalRocArrayPedestal.AddAt(new AliTPCCalROC(*calPed), iSec);
248 if ( calRMS != 0x0 ) fCalRocArrayRMS.AddAt(new AliTPCCalROC(*calRMS), iSec);
251 TH2F *hNew = new TH2F(*hPed);
252 hNew->SetDirectory(0);
253 fHistoPedestalArray.AddAt(hNew,iSec);
259 //_____________________________________________________________________
260 AliTPCCalibPedestal& AliTPCCalibPedestal::operator = (const AliTPCCalibPedestal &source)
263 // assignment operator
265 if (&source == this) return *this;
266 new (this) AliTPCCalibPedestal(source);
272 //_____________________________________________________________________
273 AliTPCCalibPedestal::~AliTPCCalibPedestal() /*FOLD00*/
279 fCalRocArrayPedestal.Delete();
280 fCalRocArrayRMS.Delete();
281 fHistoPedestalArray.Delete();
284 for (Int_t i = 0; i < 159; i++) {
285 delete [] fTimeSignal[i];
288 delete [] fTimeSignal;
292 // do not delete fMapping, because we do not own it.
297 //_____________________________________________________________________
298 void AliTPCCalibPedestal::SetTimeAnalysis(Bool_t time)
301 // Use time dependent analysis: Pedestals are analysed as a function
302 // of the drift time. There is one mean value generated for each time
303 // bin and each channel. It can be used as reference data and for
304 // configuration of the ALTRO pattern memory for baseline subtraction.
306 // ATTENTION: Use only on LDC in TPCPEDESTALda! On a LDC we get data
307 // only from one sector. For the full TPC we would need a lot of
308 // memory (36*159*140*1024*4bytes = 3.3GB)!
311 fTimeAnalysis = time;
313 if ( !fTimeAnalysis ) return;
315 // prepare array for one sector (159*140*1024*4bytes = 92MB):
316 fTimeSignal = new TArrayF*[159];
317 for (Int_t i = 0; i < 159; i++) { // padrows
318 fTimeSignal[i] = new TArrayF[140];
319 for (Int_t j = 0; j < 140; j++) { // pads per row
320 fTimeSignal[i][j].Set(1024);
321 for (Int_t k = 0; k < 1024; k++) { // time bins per pad
322 fTimeSignal[i][j].AddAt(0., k);
329 //_____________________________________________________________________
330 Int_t AliTPCCalibPedestal::Update(const Int_t icsector, /*FOLD00*/
333 const Int_t icTimeBin,
334 const Float_t csignal)
337 // Signal filling method
340 // Time dependent pedestals
341 if ( fTimeAnalysis ) {
342 if ( icsector < 36 ) // IROC
343 fTimeSignal[icRow][icPad].AddAt(fTimeSignal[icRow][icPad].At(icTimeBin)+csignal, icTimeBin);
345 fTimeSignal[icRow+63][icPad].AddAt(fTimeSignal[icRow+63][icPad].At(icTimeBin)+csignal, icTimeBin);
347 //return if we are out of the specified time bin or adc range
348 if ( (icTimeBin>fLastTimeBin) || (icTimeBin<fFirstTimeBin) ) return 0;
349 if ( ((Int_t)csignal>fAdcMax) || ((Int_t)csignal<fAdcMin) ) return 0;
351 Int_t iChannel = fROC->GetRowIndexes(icsector)[icRow]+icPad; // global pad position in sector
353 // fast filling method
354 // Attention: the entry counter of the histogram is not increased
355 // this means that e.g. the colz draw option gives an empty plot
356 Int_t bin = (iChannel+1)*(fAdcMax-fAdcMin+2)+((Int_t)csignal-fAdcMin+1);
358 GetHistoPedestal(icsector,kTRUE)->GetArray()[bin]++;
364 //_____________________________________________________________________
365 Bool_t AliTPCCalibPedestal::ProcessEventFast(AliTPCRawStreamFast *rawStreamFast)
368 // Event Processing loop - AliTPCRawStream
370 Bool_t withInput = kFALSE;
372 while ( rawStreamFast->NextDDL() ){
373 while ( rawStreamFast->NextChannel() ){
374 Int_t isector = rawStreamFast->GetSector(); // current sector
375 Int_t iRow = rawStreamFast->GetRow(); // current row
376 Int_t iPad = rawStreamFast->GetPad(); // current pad
377 Int_t startTbin = (Int_t)rawStreamFast->GetStartTimeBin();
378 Int_t endTbin = (Int_t)rawStreamFast->GetEndTimeBin();
380 while ( rawStreamFast->NextBunch() ){
381 for (Int_t iTimeBin = startTbin; iTimeBin < endTbin; iTimeBin++){
382 Float_t signal=(Float_t)rawStreamFast->GetSignals()[iTimeBin-startTbin];
383 Update(isector,iRow,iPad,iTimeBin+1,signal);
392 //_____________________________________________________________________
393 Bool_t AliTPCCalibPedestal::ProcessEventFast(AliRawReader *rawReader)
396 // Event processing loop - AliRawReader
398 AliTPCRawStreamFast *rawStreamFast = new AliTPCRawStreamFast(rawReader, (AliAltroMapping**)fMapping);
399 Bool_t res=ProcessEventFast(rawStreamFast);
400 delete rawStreamFast;
404 //_____________________________________________________________________
405 Bool_t AliTPCCalibPedestal::ProcessEvent(AliTPCRawStream *rawStream)
408 // Event Processing loop - AliTPCRawStream
411 rawStream->SetOldRCUFormat(fOldRCUformat);
413 Bool_t withInput = kFALSE;
415 while (rawStream->Next()) {
417 Int_t iSector = rawStream->GetSector(); // current ROC
418 Int_t iRow = rawStream->GetRow(); // current row
419 Int_t iPad = rawStream->GetPad(); // current pad
420 Int_t iTimeBin = rawStream->GetTime(); // current time bin
421 Float_t signal = rawStream->GetSignal(); // current ADC signal
423 Update(iSector,iRow,iPad,iTimeBin,signal);
431 //_____________________________________________________________________
432 Bool_t AliTPCCalibPedestal::ProcessEvent(AliRawReader *rawReader)
435 // Event processing loop - AliRawReader
438 // if fMapping is NULL the rawstream will crate its own mapping
439 AliTPCRawStream rawStream(rawReader, (AliAltroMapping**)fMapping);
440 rawReader->Select("TPC");
441 return ProcessEvent(&rawStream);
445 //_____________________________________________________________________
446 Bool_t AliTPCCalibPedestal::ProcessEvent(eventHeaderStruct *event)
449 // process date event
452 AliRawReader *rawReader = new AliRawReaderDate((void*)event);
453 Bool_t result=ProcessEvent(rawReader);
459 //_____________________________________________________________________
460 Bool_t AliTPCCalibPedestal::TestEvent() /*FOLD00*/
464 // fill one oroc and one iroc with random gaus
469 for (UInt_t iSec=0; iSec<72; ++iSec){
470 if (iSec%36>0) continue;
471 for (UInt_t iRow=0; iRow < fROC->GetNRows(iSec); ++iRow){
472 for (UInt_t iPad=0; iPad < fROC->GetNPads(iSec,iRow); ++iPad){
473 for (UInt_t iTimeBin=0; iTimeBin<1024; ++iTimeBin){
474 Float_t signal=(Int_t)(iRow+3+gRandom->Gaus(0,.7));
475 if ( signal>0 )Update(iSec,iRow,iPad,iTimeBin,signal);
484 //_____________________________________________________________________
485 TH2F* AliTPCCalibPedestal::GetHisto(Int_t sector, TObjArray *arr, /*FOLD00*/
486 Int_t nbinsY, Float_t ymin, Float_t ymax,
487 Char_t *type, Bool_t force)
490 // return pointer to Q histogram
491 // if force is true create a new histogram if it doesn't exist allready
493 if ( !force || arr->UncheckedAt(sector) )
494 return (TH2F*)arr->UncheckedAt(sector);
496 // if we are forced and histogram doesn't yes exist create it
497 Char_t name[255], title[255];
499 sprintf(name,"hCalib%s%.2d",type,sector);
500 sprintf(title,"%s calibration histogram sector %.2d;ADC channel;Channel (pad)",type,sector);
502 // new histogram with Q calib information. One value for each pad!
503 TH2F* hist = new TH2F(name,title,
505 fROC->GetNChannels(sector),0,fROC->GetNChannels(sector)
507 hist->SetDirectory(0);
508 arr->AddAt(hist,sector);
513 //_____________________________________________________________________
514 TH2F* AliTPCCalibPedestal::GetHistoPedestal(Int_t sector, Bool_t force) /*FOLD00*/
517 // return pointer to T0 histogram
518 // if force is true create a new histogram if it doesn't exist allready
520 TObjArray *arr = &fHistoPedestalArray;
521 return GetHisto(sector, arr, fAdcMax-fAdcMin, fAdcMin, fAdcMax, "Pedestal", force);
525 //_____________________________________________________________________
526 AliTPCCalROC* AliTPCCalibPedestal::GetCalRoc(Int_t sector, TObjArray* arr, Bool_t force) /*FOLD00*/
529 // return pointer to ROC Calibration
530 // if force is true create a new histogram if it doesn't exist allready
532 if ( !force || arr->UncheckedAt(sector) )
533 return (AliTPCCalROC*)arr->UncheckedAt(sector);
535 // if we are forced and the histogram doesn't yet exist create it
537 // new AliTPCCalROC for T0 information. One value for each pad!
538 AliTPCCalROC *croc = new AliTPCCalROC(sector);
539 arr->AddAt(croc,sector);
544 //_____________________________________________________________________
545 AliTPCCalROC* AliTPCCalibPedestal::GetCalRocPedestal(Int_t sector, Bool_t force) /*FOLD00*/
548 // return pointer to Carge ROC Calibration
549 // if force is true create a new histogram if it doesn't exist allready
551 TObjArray *arr = &fCalRocArrayPedestal;
552 return GetCalRoc(sector, arr, force);
556 //_____________________________________________________________________
557 AliTPCCalROC* AliTPCCalibPedestal::GetCalRocRMS(Int_t sector, Bool_t force) /*FOLD00*/
560 // return pointer to signal width ROC Calibration
561 // if force is true create a new histogram if it doesn't exist allready
563 TObjArray *arr = &fCalRocArrayRMS;
564 return GetCalRoc(sector, arr, force);
568 //_____________________________________________________________________
569 void AliTPCCalibPedestal::Merge(AliTPCCalibPedestal *ped)
572 // Merge reference histograms of sig to the current AliTPCCalibSignal
576 for (Int_t iSec=0; iSec<72; ++iSec){
577 TH2F *hRefPedMerge = ped->GetHistoPedestal(iSec);
580 TDirectory *dir = hRefPedMerge->GetDirectory(); hRefPedMerge->SetDirectory(0);
581 TH2F *hRefPed = GetHistoPedestal(iSec);
582 if ( hRefPed ) hRefPed->Add(hRefPedMerge);
584 TH2F *hist = new TH2F(*hRefPedMerge);
585 hist->SetDirectory(0);
586 fHistoPedestalArray.AddAt(hist, iSec);
588 hRefPedMerge->SetDirectory(dir);
598 //_____________________________________________________________________
599 void AliTPCCalibPedestal::Analyse() /*FOLD00*/
602 // Calculate calibration constants
605 Int_t nbinsAdc = fAdcMax-fAdcMin;
612 for (Int_t iSec=0; iSec<72; ++iSec){
613 TH2F *hP = GetHistoPedestal(iSec);
616 AliTPCCalROC *rocPedestal = GetCalRocPedestal(iSec,kTRUE);
617 AliTPCCalROC *rocRMS = GetCalRocRMS(iSec,kTRUE);
619 array_hP = hP->GetArray();
620 UInt_t nChannels = fROC->GetNChannels(iSec);
622 for (UInt_t iChannel=0; iChannel<nChannels; ++iChannel){
623 Int_t offset = (nbinsAdc+2)*(iChannel+1)+1;
624 Double_t ret = AliMathBase::FitGaus(array_hP+offset,nbinsAdc,fAdcMin,fAdcMax,¶m,&dummy);
625 // if the fitting failed set noise and pedestal to 0
630 rocPedestal->SetValue(iChannel,param[1]);
631 rocRMS->SetValue(iChannel,param[2]);
637 //_____________________________________________________________________
638 void AliTPCCalibPedestal::AnalyseTime(Int_t nevents)
641 // Calculate for each channel and time bin the mean pedestal. This
642 // is used on LDC by TPCPEDESTALda to generate data used for configuration
643 // of the pattern memory for baseline subtraction in the ALTROs.
646 if ( nevents <= 0 ) return;
647 if ( fTimeAnalysis ) {
648 for (Int_t i = 0; i < 159; i++) { // padrows
649 for (Int_t j = 0; j < 140; j++) { // pads per row
650 for (Int_t k = 0; k < 1024; k++) { // time bins per pad
651 fTimeSignal[i][j].AddAt(fTimeSignal[i][j].At(k)/(Float_t)nevents, k);
659 //_____________________________________________________________________
660 void AliTPCCalibPedestal::DumpToFile(const Char_t *filename, const Char_t *dir, Bool_t append) /*FOLD00*/
663 // Write class to file
674 TDirectory *backup = gDirectory;
675 TFile f(filename,option.Data());
677 if ( !sDir.IsNull() ){
678 f.mkdir(sDir.Data());
684 if ( backup ) backup->cd();