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 **************************************************************************/
18 ////////////////////////////////////////////////////////////////////////////////////////
20 // Implementation of the TPC Central Electrode calibration //
22 // Origin: Jens Wiechula, Marian Ivanov J.Wiechula@gsi.de, Marian.Ivanov@cern.ch //
24 ////////////////////////////////////////////////////////////////////////////////////////
27 // *************************************************************************************
28 // * Class Description *
29 // *************************************************************************************
32 <h4>The AliTPCCalibCE class is used to get calibration data from the Central Electrode
33 using laser runs.</h4>
35 The information retrieved is
36 <ul style="list-style-type: square;">
37 <li>Time arrival from the CE</li>
43 <ol style="list-style-type: upper-roman;">
44 <li><a href="#working">Working principle</a></li>
45 <li><a href="#user">User interface for filling data</a></li>
46 <li><a href="#info">Stored information</a></li>
49 <h3><a name="working">I. Working principle</a></h3>
51 <h4>Raw laser data is processed by calling one of the ProcessEvent(...) functions
52 (see below). These in the end call the Update(...) function.</h4>
54 <ul style="list-style-type: square;">
55 <li>the Update(...) function:<br />
56 In this function the array fPadSignal is filled with the adc signals between the specified range
57 fFirstTimeBin and fLastTimeBin for the current pad.
58 before going to the next pad the ProcessPad() function is called, which analyses the data for one pad
61 <ul style="list-style-type: square;">
62 <li>the ProcessPad() function:</li>
63 <ol style="list-style-type: decimal;">
64 <li>Find Pedestal and Noise information</li>
65 <ul style="list-style-type: square;">
66 <li>use database information which has to be set by calling<br />
67 SetPedestalDatabase(AliTPCCalPad *pedestalTPC, AliTPCCalPad *padNoiseTPC)</li>
68 <li>if no information from the pedestal data base
69 is available the informaion is calculated on the fly
70 ( see FindPedestal() function )</li>
72 <li>Find local maxima of the pad signal</li>
73 <ul style="list-style-type: square;">
74 <li>maxima arise from the laser tracks, the CE and also periodic postpeaks after the CE signal have
75 have been observed ( see FindLocalMaxima(...) )</li>
77 <li>Find the CE signal information</li>
78 <ul style="list-style-type: square;">
79 <li>to find the position of the CE signal the Tmean information from the previos event is used
80 as the CE signal the local maximum closest to this Tmean is identified</li>
81 <li>calculate mean = T0, RMS = signal width and Q sum in a range of -4+7 timebins around Q max position
82 the Q sum is scaled by pad area (see FindPulserSignal(...) function)</li>
84 <li>Fill a temprary array for the T0 information (GetPadTimesEvent(fCurrentSector,kTRUE)) (why see below)</li>
85 <li>Fill the Q sum and RMS values in the histograms (GetHisto[RMS,Q](ROC,kTRUE))</li>
90 <h4>At the end of each event the EndEvent() function is called</h4>
92 <ul style="list-style-type: square;">
93 <li>the EndEvent() function:</li>
94 <ul style="list-style-type: square;">
95 <li>calculate the mean T0 for side A and side C. Fill T0 histogram with Time0-<Time0 for side[A,C]>
96 This is done to overcome syncronisation problems between the trigger and the fec clock.</li>
97 <li>calculate Mean T for each ROC using the COG aroud the median of the LocalMaxima distribution in one sector</li>
98 <li>calculate Mean Q</li>
99 <li>calculate Global fit parameters for Pol1 and Pol2 fits</li>
103 <h4>After accumulating the desired statistics the Analyse() function has to be called.</h4>
104 <ul style="list-style-type: square;">
105 <li>the Analyse() function:</li>
106 <ul style="list-style-type: square;">
107 <li>calculate the mean values of T0, RMS, Q for each pad, using
108 the AliMathBase::GetCOG(...) function</li>
109 <li>fill the calibration storage classes (AliTPCCalROC) for each ROC</li>
110 (The calibration information is stored in the TObjArrays fCalRocArrayT0, fCalRocArrayRMS and fCalRocArrayQ</li>
114 <h3><a name="user">II. User interface for filling data</a></h3>
116 <h4>To Fill information one of the following functions can be used:</h4>
118 <ul style="list-style-type: none;">
119 <li> Bool_t ProcessEvent(eventHeaderStruct *event);</li>
120 <ul style="list-style-type: square;">
121 <li>process Date event</li>
122 <li>use AliTPCRawReaderDate and call ProcessEvent(AliRawReader *rawReader)</li>
126 <li> Bool_t ProcessEvent(AliRawReader *rawReader);</li>
127 <ul style="list-style-type: square;">
128 <li>process AliRawReader event</li>
129 <li>use AliTPCRawStream to loop over data and call ProcessEvent(AliTPCRawStream *rawStream)</li>
133 <li> Bool_t ProcessEvent(AliTPCRawStream *rawStream);</li>
134 <ul style="list-style-type: square;">
135 <li>process event from AliTPCRawStream</li>
136 <li>call Update function for signal filling</li>
140 <li> Int_t Update(const Int_t isector, const Int_t iRow, const Int_t
141 iPad, const Int_t iTimeBin, const Float_t signal);</li>
142 <ul style="list-style-type: square;">
143 <li>directly fill signal information (sector, row, pad, time bin, pad)
144 to the reference histograms</li>
148 <h4>It is also possible to merge two independently taken calibrations using the function</h4>
150 <ul style="list-style-type: none;">
151 <li> void Merge(AliTPCCalibSignal *sig)</li>
152 <ul style="list-style-type: square;">
153 <li>copy histograms in 'sig' if they do not exist in this instance</li>
154 <li>Add histograms in 'sig' to the histograms in this instance if the allready exist</li>
155 <li>After merging call Analyse again!</li>
160 <h4>example: filling data using root raw data:</h4>
162 void fillCE(Char_t *filename)
164 rawReader = new AliRawReaderRoot(fileName);
165 if ( !rawReader ) return;
166 AliTPCCalibCE *calib = new AliTPCCalibCE;
167 while (rawReader->NextEvent()){
168 calib->ProcessEvent(rawReader);
171 calib->DumpToFile("CEData.root");
177 <h3><a name="info">III. What kind of information is stored and how to retrieve it</a></h4>
179 <h4><a name="info:stored">III.1 Stored information</a></h4>
180 <ul style="list-style-type: none;">
182 <ul style="list-style-type: none;">
183 <li>For each ROC three TH2S histos 'Reference Histograms' (ROC channel vs. [Time0, signal width, Q sum])
184 is created when it is filled for the first time (GetHisto[T0,RMS,Q](ROC,kTRUE)). The histos are
185 stored in the TObjArrays fHistoT0Array, fHistoRMSArray and fHistoQArray.</li>
189 <li>Calibration Data:</li>
190 <ul style="list-style-type: none;">
191 <li>For each ROC three types of calibration data (AliTPCCalROC) is stored: for the mean arrival Time,
192 the signal width and the signal Sum. The AliTPCCalROC objects are stored in the TObjArrays
193 fCalRocArrayT0, fCalRocArrayRMS , fCalRocArrayQ. The object for each roc is created the first time it
194 is accessed (GetCalRoc[T0,RMS,Q](ROC,kTRUE));</li>
198 <li>For each event the following information is stored:</li>
200 <ul style="list-style-type: square;">
201 <li>event time ( TVectorD fVEventTime )</li>
202 <li>event id ( TVectorD fVEventNumber )</li>
204 <li>mean arrival time for each ROC ( TObjArray fTMeanArrayEvent )</li>
205 <li>mean Q for each ROC ( TObjArray fQMeanArrayEvent )</li>
206 <li>parameters of a plane fit for each ROC ( TObjArray fParamArrayEventPol1 )</li>
207 <li>parameters of a 2D parabola fit for each ROC ( TObjArray fParamArrayEventPol2 )</li>
211 <h4><a name="info:retrieve">III.2 Retrieving information</a></h4>
212 <ul style="list-style-type: none;">
213 <li>Accessing the 'Reference Histograms' (Time0, signal width and Q sum information pad by pad):</li>
214 <ul style="list-style-type: square;">
215 <li>TH2F *GetHistoT0(Int_t sector);</li>
216 <li>TH2F *GetHistoRMS(Int_t sector);</li>
217 <li>TH2F *GetHistoQ(Int_t sector);</li>
221 <li>Accessing the calibration storage objects:</li>
222 <ul style="list-style-type: square;">
223 <li>AliTPCCalROC *GetCalRocT0(Int_t sector); // for the Time0 values</li>
224 <li>AliTPCCalROC *GetCalRocRMS(Int_t sector); // for the signal width values</li>
225 <li>AliTPCCalROC *GetCalRocQ(Int_t sector); // for the Q sum values</li>
229 <li>Accessin the event by event information:</li>
230 <ul style="list-style-type: square;">
231 <li>The event by event information can be displayed using the</li>
232 <li>MakeGraphTimeCE(Int_t sector, Int_t xVariable, Int_t fitType, Int_t fitParameter)</li>
233 <li>which creates a graph from the specified variables</li>
237 <h4>example for visualisation:</h4>
239 //if the file "CEData.root" was created using the above example one could do the following:
240 TFile fileCE("CEData.root")
241 AliTPCCalibCE *ce = (AliTPCCalibCE*)fileCE->Get("AliTPCCalibCE");
242 ce->GetCalRocT0(0)->Draw("colz");
243 ce->GetCalRocRMS(0)->Draw("colz");
245 //or use the AliTPCCalPad functionality:
246 AliTPCCalPad padT0(ped->GetCalPadT0());
247 AliTPCCalPad padSigWidth(ped->GetCalPadRMS());
248 padT0->MakeHisto2D()->Draw("colz"); //Draw A-Side Time0 Information
249 padSigWidth->MakeHisto2D()->Draw("colz"); //Draw A-Side signal width Information
251 //display event by event information:
252 //Draw mean arrival time as a function of the event time for oroc sector A00
253 ce->MakeGraphTimeCE(36, 0, 2)->Draw("alp");
254 //Draw first derivative in local x from a plane fit as a function of the event time for oroc sector A00
255 ce->MakeGraphTimeCE(36, 0, 0, 1)->Draw("alp");
258 //////////////////////////////////////////////////////////////////////////////////////
262 #include <TObjArray.h>
266 #include <TVectorF.h>
267 #include <TVectorD.h>
268 #include <TMatrixD.h>
273 #include <TDirectory.h>
279 #include "AliRawReader.h"
280 #include "AliRawReaderRoot.h"
281 #include "AliRawReaderDate.h"
282 #include "AliRawEventHeaderBase.h"
283 #include "AliTPCRawStream.h"
284 #include "AliTPCRawStreamFast.h"
285 #include "AliTPCcalibDB.h"
286 #include "AliTPCCalROC.h"
287 #include "AliTPCCalPad.h"
288 #include "AliTPCROC.h"
289 #include "AliTPCParam.h"
290 #include "AliTPCCalibCE.h"
291 #include "AliMathBase.h"
292 #include "TTreeStream.h"
296 ClassImp(AliTPCCalibCE)
299 AliTPCCalibCE::AliTPCCalibCE() :
314 fNoiseThresholdMax(5.),
315 fNoiseThresholdSum(8.),
316 fIsZeroSuppressed(kFALSE),
319 fROC(AliTPCROC::Instance()),
321 fParam(new AliTPCParam),
327 fCalRocArrayT0Err(72),
330 fCalRocArrayOutliers(72),
338 fParamArrayEventPol1(72),
339 fParamArrayEventPol2(72),
340 fTMeanArrayEvent(72),
341 fQMeanArrayEvent(72),
349 fPadTimesArrayEvent(72),
351 fPadRMSArrayEvent(72),
352 fPadPedestalArrayEvent(72),
362 fVTime0OffsetCounter(72),
370 // AliTPCSignal default constructor
372 // fHTime0 = new TH1F("hTime0Event","hTime0Event",(fLastTimeBin-fFirstTimeBin)*10,fFirstTimeBin,fLastTimeBin);
375 //_____________________________________________________________________
376 AliTPCCalibCE::AliTPCCalibCE(const AliTPCCalibCE &sig) :
378 fFirstTimeBin(sig.fFirstTimeBin),
379 fLastTimeBin(sig.fLastTimeBin),
380 fNbinsT0(sig.fNbinsT0),
381 fXminT0(sig.fXminT0),
382 fXmaxT0(sig.fXmaxT0),
383 fNbinsQ(sig.fNbinsQ),
386 fNbinsRMS(sig.fNbinsRMS),
387 fXminRMS(sig.fXminRMS),
388 fXmaxRMS(sig.fXmaxRMS),
389 fPeakMinus(sig.fPeakMinus),
390 fPeakPlus(sig.fPeakPlus),
391 fNoiseThresholdMax(sig.fNoiseThresholdMax),
392 fNoiseThresholdSum(sig.fNoiseThresholdSum),
393 fIsZeroSuppressed(sig.fIsZeroSuppressed),
396 fROC(AliTPCROC::Instance()),
398 fParam(new AliTPCParam),
404 fCalRocArrayT0Err(72),
407 fCalRocArrayOutliers(72),
411 fMeanT0rms(sig.fMeanT0rms),
412 fMeanQrms(sig.fMeanQrms),
413 fMeanRMSrms(sig.fMeanRMSrms),
415 fParamArrayEventPol1(72),
416 fParamArrayEventPol2(72),
417 fTMeanArrayEvent(72),
418 fQMeanArrayEvent(72),
421 fNevents(sig.fNevents),
426 fPadTimesArrayEvent(72),
428 fPadRMSArrayEvent(72),
429 fPadPedestalArrayEvent(72),
439 fVTime0OffsetCounter(72),
444 fDebugLevel(sig.fDebugLevel)
447 // AliTPCSignal copy constructor
450 for (Int_t iSec = 0; iSec < 72; ++iSec){
451 const AliTPCCalROC *calQ = (AliTPCCalROC*)sig.fCalRocArrayQ.UncheckedAt(iSec);
452 const AliTPCCalROC *calT0 = (AliTPCCalROC*)sig.fCalRocArrayT0.UncheckedAt(iSec);
453 const AliTPCCalROC *calRMS = (AliTPCCalROC*)sig.fCalRocArrayRMS.UncheckedAt(iSec);
454 const AliTPCCalROC *calOut = (AliTPCCalROC*)sig.fCalRocArrayOutliers.UncheckedAt(iSec);
456 const TH2S *hQ = (TH2S*)sig.fHistoQArray.UncheckedAt(iSec);
457 const TH2S *hT0 = (TH2S*)sig.fHistoT0Array.UncheckedAt(iSec);
458 const TH2S *hRMS = (TH2S*)sig.fHistoRMSArray.UncheckedAt(iSec);
460 if ( calQ != 0x0 ) fCalRocArrayQ.AddAt(new AliTPCCalROC(*calQ), iSec);
461 if ( calT0 != 0x0 ) fCalRocArrayT0.AddAt(new AliTPCCalROC(*calT0), iSec);
462 if ( calRMS != 0x0 ) fCalRocArrayRMS.AddAt(new AliTPCCalROC(*calRMS), iSec);
463 if ( calOut != 0x0 ) fCalRocArrayOutliers.AddAt(new AliTPCCalROC(*calOut), iSec);
466 // TDirectory *dir = hQ->GetDirectory();
467 // hQ->SetDirectory(0);
468 TH2S *hNew = new TH2S(*hQ);
469 hNew->SetDirectory(0);
470 fHistoQArray.AddAt(hNew,iSec);
471 // hQ->SetDirectory(dir);
474 // TDirectory *dir = hT0->GetDirectory();
475 // hT0->SetDirectory(0);
476 TH2S *hNew = new TH2S(*hT0);
477 hNew->SetDirectory(0);
478 fHistoT0Array.AddAt(hNew,iSec);
479 // hT0->SetDirectory(dir);
482 // TDirectory *dir = hRMS->GetDirectory();
483 // hRMS->SetDirectory(0);
484 TH2S *hNew = new TH2S(*hRMS);
485 hNew->SetDirectory(0);
486 fHistoRMSArray.AddAt(hNew,iSec);
487 // hRMS->SetDirectory(dir);
491 //copy fit parameters event by event
493 for (Int_t iSec=0; iSec<72; ++iSec){
494 arr = (TObjArray*)sig.fParamArrayEventPol1.UncheckedAt(iSec);
496 TObjArray *arrEvents = new TObjArray(arr->GetSize());
497 fParamArrayEventPol1.AddAt(arrEvents, iSec);
498 for (Int_t iEvent=0; iEvent<arr->GetSize(); ++iEvent)
499 if ( TVectorD *vec=(TVectorD*)arr->UncheckedAt(iEvent) )
500 arrEvents->AddAt(new TVectorD(*vec),iEvent);
503 arr = (TObjArray*)sig.fParamArrayEventPol2.UncheckedAt(iSec);
505 TObjArray *arrEvents = new TObjArray(arr->GetSize());
506 fParamArrayEventPol2.AddAt(arrEvents, iSec);
507 for (Int_t iEvent=0; iEvent<arr->GetSize(); ++iEvent)
508 if ( TVectorD *vec=(TVectorD*)arr->UncheckedAt(iEvent) )
509 arrEvents->AddAt(new TVectorD(*vec),iEvent);
512 TVectorF *vMeanTime = (TVectorF*)sig.fTMeanArrayEvent.UncheckedAt(iSec);
513 TVectorF *vMeanQ = (TVectorF*)sig.fQMeanArrayEvent.UncheckedAt(iSec);
515 fTMeanArrayEvent.AddAt(new TVectorF(*vMeanTime), iSec);
517 fQMeanArrayEvent.AddAt(new TVectorF(*vMeanQ), iSec);
521 fVEventTime.ResizeTo(sig.fVEventTime);
522 fVEventNumber.ResizeTo(sig.fVEventNumber);
523 fVEventTime.SetElements(sig.fVEventTime.GetMatrixArray());
524 fVEventNumber.SetElements(sig.fVEventNumber.GetMatrixArray());
528 //_____________________________________________________________________
529 AliTPCCalibCE& AliTPCCalibCE::operator = (const AliTPCCalibCE &source)
532 // assignment operator
534 if (&source == this) return *this;
535 new (this) AliTPCCalibCE(source);
539 //_____________________________________________________________________
540 AliTPCCalibCE::~AliTPCCalibCE()
546 fCalRocArrayT0.Delete();
547 fCalRocArrayT0Err.Delete();
548 fCalRocArrayQ.Delete();
549 fCalRocArrayRMS.Delete();
550 fCalRocArrayOutliers.Delete();
552 fHistoQArray.Delete();
553 fHistoT0Array.Delete();
554 fHistoRMSArray.Delete();
556 fHistoTmean.Delete();
558 fParamArrayEventPol1.Delete();
559 fParamArrayEventPol2.Delete();
560 fTMeanArrayEvent.Delete();
561 fQMeanArrayEvent.Delete();
563 fPadTimesArrayEvent.Delete();
564 fPadQArrayEvent.Delete();
565 fPadRMSArrayEvent.Delete();
566 fPadPedestalArrayEvent.Delete();
568 if ( fDebugStreamer) delete fDebugStreamer;
569 // if ( fHTime0 ) delete fHTime0;
573 //_____________________________________________________________________
574 Int_t AliTPCCalibCE::Update(const Int_t icsector,
577 const Int_t icTimeBin,
578 const Float_t csignal)
581 // Signal filling methode on the fly pedestal and Time offset correction if necessary.
582 // no extra analysis necessary. Assumes knowledge of the signal shape!
583 // assumes that it is looped over consecutive time bins of one pad
587 // if (icsector<36) return 0;
588 // if (icsector%36>17) return 0;
591 if (icRow<0) return 0;
592 if (icPad<0) return 0;
593 if (icTimeBin<0) return 0;
594 if ( (icTimeBin>fLastTimeBin) || (icTimeBin<fFirstTimeBin) ) return 0;
596 Int_t iChannel = fROC->GetRowIndexes(icsector)[icRow]+icPad; // global pad position in sector
598 //init first pad and sector in this event
599 if ( fCurrentChannel == -1 ) {
600 fCurrentChannel = iChannel;
601 fCurrentSector = icsector;
605 //process last pad if we change to a new one
606 if ( iChannel != fCurrentChannel ){
608 fCurrentChannel = iChannel;
609 fCurrentSector = icsector;
613 //fill signals for current pad
614 fPadSignal.GetMatrixArray()[icTimeBin]=csignal;
615 if ( csignal > fMaxPadSignal ){
616 fMaxPadSignal = csignal;
617 fMaxTimeBin = icTimeBin;
621 //_____________________________________________________________________
622 void AliTPCCalibCE::FindPedestal(Float_t part)
625 // find pedestal and noise for the current pad. Use either database or
626 // truncated mean with part*100%
628 Bool_t noPedestal = kTRUE;
630 //use pedestal database if set
631 if (fPedestalTPC&&fPadNoiseTPC){
632 //only load new pedestals if the sector has changed
633 if ( fCurrentSector!=fLastSector ){
634 fPedestalROC = fPedestalTPC->GetCalROC(fCurrentSector);
635 fPadNoiseROC = fPadNoiseTPC->GetCalROC(fCurrentSector);
636 fLastSector=fCurrentSector;
639 if ( fPedestalROC&&fPadNoiseROC ){
640 fPadPedestal = fPedestalROC->GetValue(fCurrentChannel)*(Float_t)(!fIsZeroSuppressed);
641 fPadNoise = fPadNoiseROC->GetValue(fCurrentChannel);
647 //if we are not running with pedestal database, or for the current sector there is no information
648 //available, calculate the pedestal and noise on the fly
652 if ( fIsZeroSuppressed ) return;
653 const Int_t kPedMax = 100; //maximum pedestal value
662 UShort_t histo[kPedMax];
663 memset(histo,0,kPedMax*sizeof(UShort_t));
665 //fill pedestal histogram
666 for (Int_t i=fFirstTimeBin; i<=fLastTimeBin; ++i){
667 padSignal = fPadSignal.GetMatrixArray()[i];
668 if (padSignal<=0) continue;
669 if (padSignal>max && i>10) {
673 if (padSignal>kPedMax-1) continue;
674 histo[int(padSignal+0.5)]++;
678 for (Int_t i=1; i<kPedMax; ++i){
679 if (count1<count0*0.5) median=i;
684 Float_t count=histo[median] ,mean=histo[median]*median, rms=histo[median]*median*median ;
686 for (Int_t idelta=1; idelta<10; ++idelta){
687 if (median-idelta<=0) continue;
688 if (median+idelta>kPedMax) continue;
689 if (count<part*count1){
690 count+=histo[median-idelta];
691 mean +=histo[median-idelta]*(median-idelta);
692 rms +=histo[median-idelta]*(median-idelta)*(median-idelta);
693 count+=histo[median+idelta];
694 mean +=histo[median+idelta]*(median+idelta);
695 rms +=histo[median+idelta]*(median+idelta)*(median+idelta);
700 rms = TMath::Sqrt(TMath::Abs(rms/count-mean*mean));
706 //_____________________________________________________________________
707 void AliTPCCalibCE::FindCESignal(TVectorD ¶m, Float_t &qSum, const TVectorF maxima)
710 // Find position, signal width and height of the CE signal (last signal)
711 // param[0] = Qmax, param[1] = mean time, param[2] = rms;
712 // maxima: array of local maxima of the pad signal use the one closest to the mean CE position
715 Float_t ceQmax =0, ceQsum=0, ceTime=0, ceRMS=0;
717 Float_t ceSumThreshold = fNoiseThresholdSum*fPadNoise; // threshold for the signal sum
718 const Int_t kCemin = 4; // range for the analysis of the ce signal +- channels from the peak
719 const Int_t kCemax = 7;
721 Float_t minDist = 25; //initial minimum distance betweek roc mean ce signal and pad ce signal
723 // find maximum closest to the sector mean from the last event
724 for ( Int_t imax=0; imax<maxima.GetNrows(); ++imax){
725 // get sector mean of last event
726 Float_t tmean = (*GetTMeanEvents(fCurrentSector))[fNevents-1];
727 if ( TMath::Abs( tmean-maxima[imax] ) < minDist ) {
728 minDist = tmean-maxima[imax];
729 cemaxpos = (Int_t)maxima[imax];
734 ceQmax = fPadSignal.GetMatrixArray()[cemaxpos]-fPadPedestal;
735 for (Int_t i=cemaxpos-kCemin; i<cemaxpos+kCemax; ++i){
736 if ( (i>fFirstTimeBin) && (i<fLastTimeBin) ){
737 Float_t signal = fPadSignal.GetMatrixArray()[i]-fPadPedestal;
739 ceTime+=signal*(i+0.5);
740 ceRMS +=signal*(i+0.5)*(i+0.5);
746 if (ceQmax&&ceQsum>ceSumThreshold) {
748 ceRMS = TMath::Sqrt(TMath::Abs(ceRMS/ceQsum-ceTime*ceTime));
749 fVTime0Offset.GetMatrixArray()[fCurrentSector]+=ceTime; // mean time for each sector
750 fVTime0OffsetCounter.GetMatrixArray()[fCurrentSector]++;
752 //Normalise Q to pad area of irocs
753 Float_t norm = fParam->GetPadPitchWidth(fCurrentSector)*fParam->GetPadPitchLength(fCurrentSector,fCurrentRow);
756 fVMeanQ.GetMatrixArray()[fCurrentSector]+=ceQsum;
757 fVMeanQCounter.GetMatrixArray()[fCurrentSector]++;
769 //_____________________________________________________________________
770 Bool_t AliTPCCalibCE::IsPeak(Int_t pos, Int_t tminus, Int_t tplus) const
773 // Check if 'pos' is a Maximum. Consider 'tminus' timebins before
774 // and 'tplus' timebins after 'pos'
776 if ( (pos-tminus)<fFirstTimeBin || (pos+tplus)>fLastTimeBin ) return kFALSE;
777 for (Int_t iTime = pos; iTime>pos-tminus; --iTime)
778 if ( fPadSignal[iTime-1] >= fPadSignal[iTime] ) return kFALSE;
779 for (Int_t iTime = pos, iTime2=pos; iTime<pos+tplus; ++iTime, ++iTime2){
780 if ( (iTime==pos) && (fPadSignal[iTime+1]==fPadSignal[iTime]) ) // allow two timebins with same adc value
782 if ( fPadSignal[iTime2+1] >= fPadSignal[iTime2] ) return kFALSE;
786 //_____________________________________________________________________
787 void AliTPCCalibCE::FindLocalMaxima(TVectorF &maxima)
790 // Find local maxima on the pad signal and Histogram them
792 Float_t ceThreshold = fNoiseThresholdMax*TMath::Max(fPadNoise,Float_t(1.)); // threshold for the signal
796 for (Int_t i=fLastTimeBin-fPeakPlus-1; i>=fFirstTimeBin+fPeakMinus; --i){
797 if ( (fPadSignal[i]-fPadPedestal)>ceThreshold && IsPeak(i,fPeakMinus,fPeakPlus) ){
798 if (count<maxima.GetNrows()){
799 maxima.GetMatrixArray()[count++]=i;
800 GetHistoTmean(fCurrentSector,kTRUE)->Fill(i);
805 //_____________________________________________________________________
806 void AliTPCCalibCE::ProcessPad()
809 // Process data of current pad
813 TVectorF maxima(15); // the expected maximum number of maxima in the complete TPC should be 8 laser beam layers
814 // + central electrode and possibly post peaks from the CE signal
815 // however if we are on a high noise pad a lot more peaks due to the noise might occur
816 FindLocalMaxima(maxima);
817 if ( (fNevents == 0) || (fOldRunNumber!=fRunNumber) ) return; // return because we don't have Time0 info for the CE yet
819 if ( !GetTMeanEvents(fCurrentSector) ) return; //return if we don't have time 0 info, eg if only one side has laser
823 FindCESignal(param, qSum, maxima);
825 Double_t meanT = param[1];
826 Double_t sigmaT = param[2];
828 //Fill Event T0 counter
829 (*GetPadTimesEvent(fCurrentSector,kTRUE)).GetMatrixArray()[fCurrentChannel] = meanT;
832 GetHistoQ(fCurrentSector,kTRUE)->Fill( TMath::Sqrt(qSum), fCurrentChannel );
835 GetHistoRMS(fCurrentSector,kTRUE)->Fill( sigmaT, fCurrentChannel );
838 //Fill debugging info
839 if ( fDebugLevel>0 ){
840 (*GetPadPedestalEvent(fCurrentSector,kTRUE)).GetMatrixArray()[fCurrentChannel]=fPadPedestal;
841 (*GetPadRMSEvent(fCurrentSector,kTRUE)).GetMatrixArray()[fCurrentChannel]=sigmaT;
842 (*GetPadQEvent(fCurrentSector,kTRUE)).GetMatrixArray()[fCurrentChannel]=qSum;
847 //_____________________________________________________________________
848 void AliTPCCalibCE::EndEvent()
851 // Process data of current pad
852 // The Functions 'SetTimeStamp' and 'SetRunNumber' should be called
853 // before the EndEvent function to set the event timestamp and number!!!
854 // This is automatically done if the ProcessEvent(AliRawReader *rawReader)
855 // function was called
858 //check if last pad has allready been processed, if not do so
859 if ( fMaxTimeBin>-1 ) ProcessPad();
861 AliDebug(3, Form("EndEvent() - Start; Event: %05d", fNevents));
865 // TVectorF vMeanTime(72);
866 // TVectorF vMeanQ(72);
867 AliTPCCalROC *calIroc=new AliTPCCalROC(0);
868 AliTPCCalROC *calOroc=new AliTPCCalROC(36);
870 //find mean time0 offset for side A and C
871 Double_t time0Side[2]; //time0 for side A:0 and C:1
872 Double_t time0SideCount[2]; //time0 counter for side A:0 and C:1
873 time0Side[0]=0;time0Side[1]=0;time0SideCount[0]=0;time0SideCount[1]=0;
874 for ( Int_t iSec = 0; iSec<72; ++iSec ){
875 time0Side[(iSec/18)%2] += fVTime0Offset.GetMatrixArray()[iSec];
876 time0SideCount[(iSec/18)%2] += fVTime0OffsetCounter.GetMatrixArray()[iSec];
878 if ( time0SideCount[0] >0 )
879 time0Side[0]/=time0SideCount[0];
880 if ( time0SideCount[1] >0 )
881 time0Side[1]/=time0SideCount[1];
882 // end find time0 offset
885 //loop over all ROCs, fill CE Time histogram corrected for the mean Time0 of each ROC
886 for ( Int_t iSec = 0; iSec<72; ++iSec ){
887 AliDebug(4,Form("Processing sector '%02d'\n",iSec));
888 //find median and then calculate the mean around it
889 TH1S *hMeanT = GetHistoTmean(iSec); //histogram with local maxima position information
890 if ( !hMeanT ) continue;
891 //continue if not enough data is filled in the meanT histogram. This is the case if we do not have a laser event.
892 if ( hMeanT->GetEntries() < fROC->GetNChannels(iSec)*fSecRejectRatio ){
894 AliDebug(3,Form("Skipping sec. '%02d': Not enough statistics\n",iSec));
898 Double_t entries = hMeanT->GetEntries();
900 Short_t *arr = hMeanT->GetArray()+1;
902 for ( ibin=0; ibin<hMeanT->GetNbinsX(); ++ibin){
904 if ( sum>=(entries/2.) ) break;
907 Int_t firstBin = fFirstTimeBin+ibin-delta;
908 Int_t lastBin = fFirstTimeBin+ibin+delta;
909 if ( firstBin<fFirstTimeBin ) firstBin=fFirstTimeBin;
910 if ( lastBin>fLastTimeBin ) lastBin =fLastTimeBin;
911 Float_t median =AliMathBase::GetCOG(arr+ibin-delta,2*delta,firstBin,lastBin);
913 // check boundaries for ebye info of mean time
914 TVectorF *vMeanTime=GetTMeanEvents(iSec,kTRUE);
915 Int_t vSize=vMeanTime->GetNrows();
916 if ( vSize < fNevents+1 )
917 vMeanTime->ResizeTo(vSize+100);
919 vMeanTime->GetMatrixArray()[fNevents]=median;
923 TVectorF *vTimes = GetPadTimesEvent(iSec);
924 if ( !vTimes ) continue; //continue if no time information for this sector is available
927 AliTPCCalROC calIrocOutliers(0);
928 AliTPCCalROC calOrocOutliers(36);
930 // calculate mean Q of the sector
932 if ( fVMeanQCounter.GetMatrixArray()[iSec]>0 ) meanQ=fVMeanQ.GetMatrixArray()[iSec]/fVMeanQCounter.GetMatrixArray()[iSec];
933 TVectorF *vMeanQ=GetQMeanEvents(iSec,kTRUE);
934 if ( vSize < fNevents+1 ) // vSize is the same as for vMeanTime!
935 vMeanQ->ResizeTo(vSize+100);
937 vMeanQ->GetMatrixArray()[fNevents]=meanQ;
939 for ( UInt_t iChannel=0; iChannel<fROC->GetNChannels(iSec); ++iChannel ){
940 Float_t time = (*vTimes).GetMatrixArray()[iChannel];
942 //set values for temporary roc calibration class
944 calIroc->SetValue(iChannel, time);
945 if ( time == 0 ) calIrocOutliers.SetValue(iChannel,1);
948 calOroc->SetValue(iChannel, time);
949 if ( time == 0 ) calOrocOutliers.SetValue(iChannel,1);
952 if ( (fNevents>0) && (fOldRunNumber==fRunNumber) )
953 GetHistoT0(iSec,kTRUE)->Fill( time-time0Side[(iSec/18)%2],iChannel );
957 //------------------------------- Debug start ------------------------------
958 if ( fDebugLevel>0 ){
959 if ( !fDebugStreamer ) {
961 TDirectory *backup = gDirectory;
962 fDebugStreamer = new TTreeSRedirector("debugCalibCE.root");
963 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
970 Float_t q = (*GetPadQEvent(iSec))[iChannel];
971 Float_t rms = (*GetPadRMSEvent(iSec))[iChannel];
973 UInt_t channel=iChannel;
976 while ( channel > (fROC->GetRowIndexes(sector)[row]+fROC->GetNPads(sector,row)-1) ) row++;
977 pad = channel-fROC->GetRowIndexes(sector)[row];
978 padc = pad-(fROC->GetNPads(sector,row)/2);
980 // TH1F *h1 = new TH1F(Form("hSignalD%d.%d.%d",sector,row,pad),
981 // Form("hSignalD%d.%d.%d",sector,row,pad),
982 // fLastTimeBin-fFirstTimeBin,
983 // fFirstTimeBin,fLastTimeBin);
984 // h1->SetDirectory(0);
986 // for (Int_t i=fFirstTimeBin; i<fLastTimeBin+1; ++i)
987 // h1->Fill(i,fPadSignal(i));
990 if (fVTime0OffsetCounter.GetMatrixArray()[iSec]>0)
991 t0Sec = fVTime0Offset.GetMatrixArray()[iSec]/fVTime0OffsetCounter.GetMatrixArray()[iSec];
992 Double_t t0Side = time0Side[(iSec/18)%2];
993 (*fDebugStreamer) << "DataPad" <<
994 "Event=" << fNevents <<
995 "RunNumber=" << fRunNumber <<
996 "TimeStamp=" << fTimeStamp <<
997 "Sector="<< sector <<
1001 "PadSec="<< channel <<
1002 "Time0Sec=" << t0Sec <<
1003 "Time0Side=" << t0Side <<
1007 "MeanQ=" << meanQ <<
1008 // "hist.=" << h1 <<
1014 //----------------------------- Debug end ------------------------------
1015 }// end channel loop
1017 TVectorD paramPol1(3);
1018 TVectorD paramPol2(6);
1019 TMatrixD matPol1(3,3);
1020 TMatrixD matPol2(6,6);
1024 if ( (fNevents>0) && (fOldRunNumber==fRunNumber) ){
1026 calIroc->GlobalFit(&calIrocOutliers,0,paramPol1,matPol1,chi2Pol1,0);
1027 calIroc->GlobalFit(&calIrocOutliers,0,paramPol2,matPol2,chi2Pol2,1);
1029 calOroc->GlobalFit(&calOrocOutliers,0,paramPol1,matPol1,chi2Pol1,0);
1030 calOroc->GlobalFit(&calOrocOutliers,0,paramPol2,matPol2,chi2Pol2,1);
1033 GetParamArrayPol1(iSec,kTRUE)->AddAtAndExpand(new TVectorD(paramPol1), fNevents);
1034 GetParamArrayPol2(iSec,kTRUE)->AddAtAndExpand(new TVectorD(paramPol2), fNevents);
1037 //------------------------------- Debug start ------------------------------
1038 if ( fDebugLevel>0 ){
1039 if ( !fDebugStreamer ) {
1041 TDirectory *backup = gDirectory;
1042 fDebugStreamer = new TTreeSRedirector("debugCalibCE.root");
1043 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
1045 (*fDebugStreamer) << "DataRoc" <<
1046 // "Event=" << fEvent <<
1047 "RunNumber=" << fRunNumber <<
1048 "TimeStamp=" << fTimeStamp <<
1050 "hMeanT.=" << hMeanT <<
1051 "median=" << median <<
1052 "paramPol1.=" << ¶mPol1 <<
1053 "paramPol2.=" << ¶mPol2 <<
1054 "matPol1.=" << &matPol1 <<
1055 "matPol2.=" << &matPol2 <<
1056 "chi2Pol1=" << chi2Pol1 <<
1057 "chi2Pol2=" << chi2Pol2 <<
1060 //------------------------------- Debug end ------------------------------
1063 //return if no sector has a valid mean time
1064 if ( nSecMeanT == 0 ) return;
1067 // fTMeanArrayEvent.AddAtAndExpand(new TVectorF(vMeanTime),fNevents);
1068 // fQMeanArrayEvent.AddAtAndExpand(new TVectorF(vMeanQ),fNevents);
1069 if ( fVEventTime.GetNrows() < fNevents+1 ) {
1070 fVEventTime.ResizeTo((Int_t)(fVEventTime.GetNrows()+100));
1071 fVEventNumber.ResizeTo((Int_t)(fVEventNumber.GetNrows()+100));
1073 fVEventTime.GetMatrixArray()[fNevents] = fTimeStamp;
1074 fVEventNumber.GetMatrixArray()[fNevents] = fEventId;
1077 fOldRunNumber = fRunNumber;
1081 AliDebug(3, Form("EndEvent() - End; Event: %05d", fNevents));
1083 //_____________________________________________________________________
1084 Bool_t AliTPCCalibCE::ProcessEventFast(AliTPCRawStreamFast *rawStreamFast)
1087 // Event Processing loop - AliTPCRawStreamFast
1090 Bool_t withInput = kFALSE;
1091 while ( rawStreamFast->NextDDL() ){
1092 while ( rawStreamFast->NextChannel() ){
1093 Int_t isector = rawStreamFast->GetSector(); // current sector
1094 Int_t iRow = rawStreamFast->GetRow(); // current row
1095 Int_t iPad = rawStreamFast->GetPad(); // current pad
1097 while ( rawStreamFast->NextBunch() ){
1098 Int_t startTbin = (Int_t)rawStreamFast->GetStartTimeBin();
1099 Int_t endTbin = (Int_t)rawStreamFast->GetEndTimeBin();
1100 for (Int_t iTimeBin = startTbin; iTimeBin < endTbin; iTimeBin++){
1101 Float_t signal=(Float_t)rawStreamFast->GetSignals()[iTimeBin-startTbin];
1102 Update(isector,iRow,iPad,iTimeBin+1,signal);
1113 //_____________________________________________________________________
1114 Bool_t AliTPCCalibCE::ProcessEventFast(AliRawReader *rawReader)
1117 // Event processing loop using the fast raw stream algorithm- AliRawReader
1120 //printf("ProcessEventFast - raw reader\n");
1122 AliRawEventHeaderBase* eventHeader = (AliRawEventHeaderBase*)rawReader->GetEventHeader();
1124 fTimeStamp = eventHeader->Get("Timestamp");
1125 fRunNumber = eventHeader->Get("RunNb");
1127 fEventId = *rawReader->GetEventId();
1129 AliTPCRawStreamFast *rawStreamFast = new AliTPCRawStreamFast(rawReader, (AliAltroMapping**)fMapping);
1130 Bool_t res=ProcessEventFast(rawStreamFast);
1131 delete rawStreamFast;
1135 //_____________________________________________________________________
1136 Bool_t AliTPCCalibCE::ProcessEvent(AliTPCRawStream *rawStream)
1139 // Event Processing loop - AliTPCRawStream
1140 // The Function 'SetTimeStamp' should be called for each event to set the event time stamp!!!
1145 Bool_t withInput = kFALSE;
1147 while (rawStream->Next()) {
1149 Int_t isector = rawStream->GetSector(); // current sector
1150 Int_t iRow = rawStream->GetRow(); // current row
1151 Int_t iPad = rawStream->GetPad(); // current pad
1152 Int_t iTimeBin = rawStream->GetTime(); // current time bin
1153 Float_t signal = rawStream->GetSignal(); // current ADC signal
1155 Update(isector,iRow,iPad,iTimeBin,signal);
1165 //_____________________________________________________________________
1166 Bool_t AliTPCCalibCE::ProcessEvent(AliRawReader *rawReader)
1169 // Event processing loop - AliRawReader
1173 AliTPCRawStream rawStream(rawReader,(AliAltroMapping**)fMapping);
1174 AliRawEventHeaderBase* eventHeader = (AliRawEventHeaderBase*)rawReader->GetEventHeader();
1176 fTimeStamp = eventHeader->Get("Timestamp");
1177 fRunNumber = eventHeader->Get("RunNb");
1179 fEventId = *rawReader->GetEventId();
1182 rawReader->Select("TPC");
1184 return ProcessEvent(&rawStream);
1186 //_____________________________________________________________________
1187 Bool_t AliTPCCalibCE::ProcessEvent(eventHeaderStruct *event)
1190 // Event processing loop - date event
1192 AliRawReader *rawReader = new AliRawReaderDate((void*)event);
1193 Bool_t result=ProcessEvent(rawReader);
1198 //_____________________________________________________________________
1199 TH2S* AliTPCCalibCE::GetHisto(Int_t sector, TObjArray *arr,
1200 Int_t nbinsY, Float_t ymin, Float_t ymax,
1201 Char_t *type, Bool_t force)
1204 // return pointer to TH2S histogram of 'type'
1205 // if force is true create a new histogram if it doesn't exist allready
1207 if ( !force || arr->UncheckedAt(sector) )
1208 return (TH2S*)arr->UncheckedAt(sector);
1210 // if we are forced and histogram doesn't exist yet create it
1211 Char_t name[255], title[255];
1213 sprintf(name,"hCalib%s%.2d",type,sector);
1214 sprintf(title,"%s calibration histogram sector %.2d",type,sector);
1216 // new histogram with Q calib information. One value for each pad!
1217 TH2S* hist = new TH2S(name,title,
1219 fROC->GetNChannels(sector),0,fROC->GetNChannels(sector));
1220 hist->SetDirectory(0);
1221 arr->AddAt(hist,sector);
1224 //_____________________________________________________________________
1225 TH2S* AliTPCCalibCE::GetHistoT0(Int_t sector, Bool_t force)
1228 // return pointer to T0 histogram
1229 // if force is true create a new histogram if it doesn't exist allready
1231 TObjArray *arr = &fHistoT0Array;
1232 return GetHisto(sector, arr, fNbinsT0, fXminT0, fXmaxT0, "T0", force);
1234 //_____________________________________________________________________
1235 TH2S* AliTPCCalibCE::GetHistoQ(Int_t sector, Bool_t force)
1238 // return pointer to Q histogram
1239 // if force is true create a new histogram if it doesn't exist allready
1241 TObjArray *arr = &fHistoQArray;
1242 return GetHisto(sector, arr, fNbinsQ, fXminQ, fXmaxQ, "Q", force);
1244 //_____________________________________________________________________
1245 TH2S* AliTPCCalibCE::GetHistoRMS(Int_t sector, Bool_t force)
1248 // return pointer to Q histogram
1249 // if force is true create a new histogram if it doesn't exist allready
1251 TObjArray *arr = &fHistoRMSArray;
1252 return GetHisto(sector, arr, fNbinsRMS, fXminRMS, fXmaxRMS, "RMS", force);
1254 //_____________________________________________________________________
1255 TH1S* AliTPCCalibCE::GetHisto(Int_t sector, TObjArray *arr,
1256 Char_t *type, Bool_t force)
1259 // return pointer to TH1S histogram
1260 // if force is true create a new histogram if it doesn't exist allready
1262 if ( !force || arr->UncheckedAt(sector) )
1263 return (TH1S*)arr->UncheckedAt(sector);
1265 // if we are forced and histogram doesn't yes exist create it
1266 Char_t name[255], title[255];
1268 sprintf(name,"hCalib%s%.2d",type,sector);
1269 sprintf(title,"%s calibration histogram sector %.2d",type,sector);
1271 // new histogram with calib information. One value for each pad!
1272 TH1S* hist = new TH1S(name,title,
1273 fLastTimeBin-fFirstTimeBin,fFirstTimeBin,fLastTimeBin);
1274 hist->SetDirectory(0);
1275 arr->AddAt(hist,sector);
1278 //_____________________________________________________________________
1279 TH1S* AliTPCCalibCE::GetHistoTmean(Int_t sector, Bool_t force)
1282 // return pointer to Q histogram
1283 // if force is true create a new histogram if it doesn't exist allready
1285 TObjArray *arr = &fHistoTmean;
1286 return GetHisto(sector, arr, "LastTmean", force);
1288 //_____________________________________________________________________
1289 TVectorF* AliTPCCalibCE::GetVectSector(Int_t sector, TObjArray *arr, UInt_t size, Bool_t force) const
1292 // return pointer to Pad Info from 'arr' for the current event and sector
1293 // if force is true create it if it doesn't exist allready
1295 if ( !force || arr->UncheckedAt(sector) )
1296 return (TVectorF*)arr->UncheckedAt(sector);
1298 TVectorF *vect = new TVectorF(size);
1299 arr->AddAt(vect,sector);
1302 //_____________________________________________________________________
1303 TVectorF* AliTPCCalibCE::GetPadTimesEvent(Int_t sector, Bool_t force)
1306 // return pointer to Pad Times Array for the current event and sector
1307 // if force is true create it if it doesn't exist allready
1309 TObjArray *arr = &fPadTimesArrayEvent;
1310 return GetVectSector(sector,arr,fROC->GetNChannels(sector),force);
1312 //_____________________________________________________________________
1313 TVectorF* AliTPCCalibCE::GetPadQEvent(Int_t sector, Bool_t force)
1316 // return pointer to Pad Q Array for the current event and sector
1317 // if force is true create it if it doesn't exist allready
1318 // for debugging purposes only
1321 TObjArray *arr = &fPadQArrayEvent;
1322 return GetVectSector(sector,arr,fROC->GetNChannels(sector),force);
1324 //_____________________________________________________________________
1325 TVectorF* AliTPCCalibCE::GetPadRMSEvent(Int_t sector, Bool_t force)
1328 // return pointer to Pad RMS Array for the current event and sector
1329 // if force is true create it if it doesn't exist allready
1330 // for debugging purposes only
1332 TObjArray *arr = &fPadRMSArrayEvent;
1333 return GetVectSector(sector,arr,fROC->GetNChannels(sector),force);
1335 //_____________________________________________________________________
1336 TVectorF* AliTPCCalibCE::GetPadPedestalEvent(Int_t sector, Bool_t force)
1339 // return pointer to Pad RMS Array for the current event and sector
1340 // if force is true create it if it doesn't exist allready
1341 // for debugging purposes only
1343 TObjArray *arr = &fPadPedestalArrayEvent;
1344 return GetVectSector(sector,arr,fROC->GetNChannels(sector),force);
1346 //_____________________________________________________________________
1347 TVectorF* AliTPCCalibCE::GetTMeanEvents(Int_t sector, Bool_t force)
1350 // return pointer to the EbyE info of the mean arrival time for 'sector'
1351 // if force is true create it if it doesn't exist allready
1353 TObjArray *arr = &fTMeanArrayEvent;
1354 return GetVectSector(sector,arr,100,force);
1356 //_____________________________________________________________________
1357 TVectorF* AliTPCCalibCE::GetQMeanEvents(Int_t sector, Bool_t force)
1360 // return pointer to the EbyE info of the mean arrival time for 'sector'
1361 // if force is true create it if it doesn't exist allready
1363 TObjArray *arr = &fQMeanArrayEvent;
1364 return GetVectSector(sector,arr,100,force);
1366 //_____________________________________________________________________
1367 AliTPCCalROC* AliTPCCalibCE::GetCalRoc(Int_t sector, TObjArray* arr, Bool_t force) const
1370 // return pointer to ROC Calibration
1371 // if force is true create a new histogram if it doesn't exist allready
1373 if ( !force || arr->UncheckedAt(sector) )
1374 return (AliTPCCalROC*)arr->UncheckedAt(sector);
1376 // if we are forced and histogram doesn't yes exist create it
1378 // new AliTPCCalROC for T0 information. One value for each pad!
1379 AliTPCCalROC *croc = new AliTPCCalROC(sector);
1380 arr->AddAt(croc,sector);
1383 //_____________________________________________________________________
1384 AliTPCCalROC* AliTPCCalibCE::GetCalRocT0(Int_t sector, Bool_t force)
1387 // return pointer to Time 0 ROC Calibration
1388 // if force is true create a new histogram if it doesn't exist allready
1390 TObjArray *arr = &fCalRocArrayT0;
1391 return GetCalRoc(sector, arr, force);
1393 //_____________________________________________________________________
1394 AliTPCCalROC* AliTPCCalibCE::GetCalRocT0Err(Int_t sector, Bool_t force)
1397 // return pointer to the error of Time 0 ROC Calibration
1398 // if force is true create a new histogram if it doesn't exist allready
1400 TObjArray *arr = &fCalRocArrayT0Err;
1401 return GetCalRoc(sector, arr, force);
1403 //_____________________________________________________________________
1404 AliTPCCalROC* AliTPCCalibCE::GetCalRocQ(Int_t sector, Bool_t force)
1407 // return pointer to T0 ROC Calibration
1408 // if force is true create a new histogram if it doesn't exist allready
1410 TObjArray *arr = &fCalRocArrayQ;
1411 return GetCalRoc(sector, arr, force);
1413 //_____________________________________________________________________
1414 AliTPCCalROC* AliTPCCalibCE::GetCalRocRMS(Int_t sector, Bool_t force)
1417 // return pointer to signal width ROC Calibration
1418 // if force is true create a new histogram if it doesn't exist allready
1420 TObjArray *arr = &fCalRocArrayRMS;
1421 return GetCalRoc(sector, arr, force);
1423 //_____________________________________________________________________
1424 AliTPCCalROC* AliTPCCalibCE::GetCalRocOutliers(Int_t sector, Bool_t force)
1427 // return pointer to Outliers
1428 // if force is true create a new histogram if it doesn't exist allready
1430 TObjArray *arr = &fCalRocArrayOutliers;
1431 return GetCalRoc(sector, arr, force);
1433 //_____________________________________________________________________
1434 TObjArray* AliTPCCalibCE::GetParamArray(Int_t sector, TObjArray* arr, Bool_t force) const
1437 // return pointer to TObjArray of fit parameters
1438 // if force is true create a new histogram if it doesn't exist allready
1440 if ( !force || arr->UncheckedAt(sector) )
1441 return (TObjArray*)arr->UncheckedAt(sector);
1443 // if we are forced and array doesn't yes exist create it
1445 // new TObjArray for parameters
1446 TObjArray *newArr = new TObjArray;
1447 arr->AddAt(newArr,sector);
1450 //_____________________________________________________________________
1451 TObjArray* AliTPCCalibCE::GetParamArrayPol1(Int_t sector, Bool_t force)
1454 // return pointer to TObjArray of fit parameters from plane fit
1455 // if force is true create a new histogram if it doesn't exist allready
1457 TObjArray *arr = &fParamArrayEventPol1;
1458 return GetParamArray(sector, arr, force);
1460 //_____________________________________________________________________
1461 TObjArray* AliTPCCalibCE::GetParamArrayPol2(Int_t sector, Bool_t force)
1464 // return pointer to TObjArray of fit parameters from parabola fit
1465 // if force is true create a new histogram if it doesn't exist allready
1467 TObjArray *arr = &fParamArrayEventPol2;
1468 return GetParamArray(sector, arr, force);
1470 //_____________________________________________________________________
1471 void AliTPCCalibCE::ResetEvent()
1474 // Reset global counters -- Should be called before each event is processed
1483 fPadTimesArrayEvent.Delete();
1484 fPadQArrayEvent.Delete();
1485 fPadRMSArrayEvent.Delete();
1486 fPadPedestalArrayEvent.Delete();
1488 for ( Int_t i=0; i<72; ++i ){
1489 fVTime0Offset.GetMatrixArray()[i]=0;
1490 fVTime0OffsetCounter.GetMatrixArray()[i]=0;
1491 fVMeanQ.GetMatrixArray()[i]=0;
1492 fVMeanQCounter.GetMatrixArray()[i]=0;
1495 //_____________________________________________________________________
1496 void AliTPCCalibCE::ResetPad()
1499 // Reset pad infos -- Should be called after a pad has been processed
1501 for (Int_t i=fFirstTimeBin; i<fLastTimeBin+1; ++i)
1502 fPadSignal.GetMatrixArray()[i] = 0;
1508 //_____________________________________________________________________
1509 void AliTPCCalibCE::Merge(AliTPCCalibCE *ce)
1512 // Merge ce to the current AliTPCCalibCE
1516 for (Int_t iSec=0; iSec<72; ++iSec){
1517 TH2S *hRefQmerge = ce->GetHistoQ(iSec);
1518 TH2S *hRefT0merge = ce->GetHistoT0(iSec);
1519 TH2S *hRefRMSmerge = ce->GetHistoRMS(iSec);
1523 TDirectory *dir = hRefQmerge->GetDirectory(); hRefQmerge->SetDirectory(0);
1524 TH2S *hRefQ = GetHistoQ(iSec);
1525 if ( hRefQ ) hRefQ->Add(hRefQmerge);
1527 TH2S *hist = new TH2S(*hRefQmerge);
1528 hist->SetDirectory(0);
1529 fHistoQArray.AddAt(hist, iSec);
1531 hRefQmerge->SetDirectory(dir);
1534 TDirectory *dir = hRefT0merge->GetDirectory(); hRefT0merge->SetDirectory(0);
1535 TH2S *hRefT0 = GetHistoT0(iSec);
1536 if ( hRefT0 ) hRefT0->Add(hRefT0merge);
1538 TH2S *hist = new TH2S(*hRefT0merge);
1539 hist->SetDirectory(0);
1540 fHistoT0Array.AddAt(hist, iSec);
1542 hRefT0merge->SetDirectory(dir);
1544 if ( hRefRMSmerge ){
1545 TDirectory *dir = hRefRMSmerge->GetDirectory(); hRefRMSmerge->SetDirectory(0);
1546 TH2S *hRefRMS = GetHistoRMS(iSec);
1547 if ( hRefRMS ) hRefRMS->Add(hRefRMSmerge);
1549 TH2S *hist = new TH2S(*hRefRMSmerge);
1550 hist->SetDirectory(0);
1551 fHistoRMSArray.AddAt(hist, iSec);
1553 hRefRMSmerge->SetDirectory(dir);
1558 // merge time information
1561 Int_t nCEevents = ce->GetNeventsProcessed();
1562 for (Int_t iSec=0; iSec<72; ++iSec){
1563 TObjArray *arrPol1CE = ce->GetParamArrayPol1(iSec);
1564 TObjArray *arrPol2CE = ce->GetParamArrayPol2(iSec);
1565 TVectorF *vMeanTimeCE = ce->GetTMeanEvents(iSec);
1566 TVectorF *vMeanQCE = ce->GetQMeanEvents(iSec);
1568 TObjArray *arrPol1 = 0x0;
1569 TObjArray *arrPol2 = 0x0;
1570 TVectorF *vMeanTime = 0x0;
1571 TVectorF *vMeanQ = 0x0;
1574 if ( arrPol1CE && arrPol2CE ){
1575 arrPol1 = GetParamArrayPol1(iSec,kTRUE);
1576 arrPol2 = GetParamArrayPol2(iSec,kTRUE);
1577 arrPol1->Expand(fNevents+nCEevents);
1578 arrPol2->Expand(fNevents+nCEevents);
1580 if ( vMeanTimeCE && vMeanQCE ){
1581 vMeanTime = GetTMeanEvents(iSec,kTRUE);
1582 vMeanQ = GetQMeanEvents(iSec,kTRUE);
1583 vMeanTime->ResizeTo(fNevents+nCEevents);
1584 vMeanQ->ResizeTo(fNevents+nCEevents);
1588 for (Int_t iEvent=0; iEvent<nCEevents; ++iEvent){
1589 if ( arrPol1CE && arrPol2CE ){
1590 TVectorD *paramPol1 = (TVectorD*)(arrPol1CE->UncheckedAt(iEvent));
1591 TVectorD *paramPol2 = (TVectorD*)(arrPol2CE->UncheckedAt(iEvent));
1592 if ( paramPol1 && paramPol2 ){
1593 GetParamArrayPol1(iSec,kTRUE)->AddAt(new TVectorD(*paramPol1), fNevents+iEvent);
1594 GetParamArrayPol2(iSec,kTRUE)->AddAt(new TVectorD(*paramPol2), fNevents+iEvent);
1597 if ( vMeanTimeCE && vMeanQCE ){
1598 vMeanTime->GetMatrixArray()[fNevents+iEvent]=vMeanTimeCE->GetMatrixArray()[iEvent];
1599 vMeanQ->GetMatrixArray()[fNevents+iEvent]=vMeanQCE->GetMatrixArray()[iEvent];
1606 TVectorD* eventTimes = ce->GetEventTimes();
1607 TVectorD* eventIds = ce->GetEventIds();
1608 fVEventTime.ResizeTo(fNevents+nCEevents);
1609 fVEventNumber.ResizeTo(fNevents+nCEevents);
1611 for (Int_t iEvent=0; iEvent<nCEevents; ++iEvent){
1612 Double_t evTime = eventTimes->GetMatrixArray()[iEvent];
1613 Double_t evId = eventIds->GetMatrixArray()[iEvent];
1614 fVEventTime.GetMatrixArray()[fNevents+iEvent] = evTime;
1615 fVEventNumber.GetMatrixArray()[fNevents+iEvent] = evId;
1617 fNevents+=nCEevents; //increase event counter
1620 //_____________________________________________________________________
1621 TGraph *AliTPCCalibCE::MakeGraphTimeCE(Int_t sector, Int_t xVariable, Int_t fitType, Int_t fitParameter)
1624 // Make graph from fit parameters of pol1 fit, pol2 fit, mean arrival time or mean Q for ROC 'sector'
1625 // xVariable: 0-event time, 1-event id, 2-internal event counter
1626 // fitType: 0-pol1 fit, 1-pol2 fit, 2-mean time, 3-mean Q
1627 // fitParameter: fit parameter ( 0-2 for pol1 ([0]+[1]*x+[2]*y),
1628 // 0-5 for pol2 ([0]+[1]*x+[2]*y+[3]*x*x+[4]*y*y+[5]*x*y),
1629 // not used for mean time and mean Q )
1630 // for an example see class description at the beginning
1633 Double_t *x = new Double_t[fNevents];
1634 Double_t *y = new Double_t[fNevents];
1636 TVectorD *xVar = 0x0;
1637 TObjArray *aType = 0x0;
1641 if ( (sector<0) || (sector>71) ) return 0x0;
1642 if ( (xVariable<0) || (xVariable>2) ) return 0x0;
1643 if ( (fitType<0) || (fitType>3) ) return 0x0;
1645 if ( (fitParameter<0) || (fitParameter>2) ) return 0x0;
1646 aType = &fParamArrayEventPol1;
1647 if ( aType->At(sector)==0x0 ) return 0x0;
1649 else if ( fitType==1 ){
1650 if ( (fitParameter<0) || (fitParameter>5) ) return 0x0;
1651 aType = &fParamArrayEventPol2;
1652 if ( aType->At(sector)==0x0 ) return 0x0;
1656 if ( xVariable == 0 ) xVar = &fVEventTime;
1657 if ( xVariable == 1 ) xVar = &fVEventNumber;
1658 if ( xVariable == 2 ) {
1659 xVar = new TVectorD(fNevents);
1660 for ( Int_t i=0;i<fNevents; ++i) (*xVar)[i]=i;
1663 for (Int_t ievent =0; ievent<fNevents; ++ievent){
1665 TObjArray *events = (TObjArray*)(aType->At(sector));
1666 if ( events->GetSize()<=ievent ) break;
1667 TVectorD *v = (TVectorD*)(events->At(ievent));
1668 if ( (v!=0x0) && ((*xVar)[ievent]>0) ) { x[npoints]=(*xVar)[ievent]; y[npoints]=(*v)[fitParameter]; npoints++;}
1669 } else if (fitType == 2) {
1670 Double_t xValue=(*xVar)[ievent];
1671 Double_t yValue=(*GetTMeanEvents(sector))[ievent];
1672 if ( yValue>0 && xValue>0 ) { x[npoints]=xValue; y[npoints]=yValue;npoints++;}
1673 }else if (fitType == 3) {
1674 Double_t xValue=(*xVar)[ievent];
1675 Double_t yValue=(*GetQMeanEvents(sector))[ievent];
1676 if ( yValue>0 && xValue>0 ) { x[npoints]=xValue; y[npoints]=yValue;npoints++;}
1680 TGraph *gr = new TGraph(npoints);
1681 //sort xVariable increasing
1682 Int_t *sortIndex = new Int_t[npoints];
1683 TMath::Sort(npoints,x,sortIndex);
1684 for (Int_t i=0;i<npoints;++i){
1685 gr->SetPoint(i,x[sortIndex[i]],y[sortIndex[i]]);
1689 if ( xVariable == 2 ) delete xVar;
1695 //_____________________________________________________________________
1696 void AliTPCCalibCE::Analyse()
1699 // Calculate calibration constants
1703 TVectorD paramT0(3);
1704 TVectorD paramRMS(3);
1705 TMatrixD dummy(3,3);
1707 Float_t channelCounter=0;
1712 for (Int_t iSec=0; iSec<72; ++iSec){
1713 TH2S *hT0 = GetHistoT0(iSec);
1714 if (!hT0 ) continue;
1716 AliTPCCalROC *rocQ = GetCalRocQ (iSec,kTRUE);
1717 AliTPCCalROC *rocT0 = GetCalRocT0 (iSec,kTRUE);
1718 AliTPCCalROC *rocT0Err = GetCalRocT0Err (iSec,kTRUE);
1719 AliTPCCalROC *rocRMS = GetCalRocRMS(iSec,kTRUE);
1720 AliTPCCalROC *rocOut = GetCalRocOutliers(iSec,kTRUE);
1722 TH2S *hQ = GetHistoQ(iSec);
1723 TH2S *hRMS = GetHistoRMS(iSec);
1725 Short_t *arrayhQ = hQ->GetArray();
1726 Short_t *arrayhT0 = hT0->GetArray();
1727 Short_t *arrayhRMS = hRMS->GetArray();
1729 UInt_t nChannels = fROC->GetNChannels(iSec);
1737 for (UInt_t iChannel=0; iChannel<nChannels; ++iChannel){
1740 Float_t cogTime0 = -1000;
1741 Float_t cogQ = -1000;
1742 Float_t cogRMS = -1000;
1748 Int_t offsetQ = (fNbinsQ+2)*(iChannel+1)+1;
1749 Int_t offsetT0 = (fNbinsT0+2)*(iChannel+1)+1;
1750 Int_t offsetRMS = (fNbinsRMS+2)*(iChannel+1)+1;
1752 cogQ = AliMathBase::GetCOG(arrayhQ+offsetQ,fNbinsQ,fXminQ,fXmaxQ,&rms);
1754 cogTime0 = AliMathBase::GetCOG(arrayhT0+offsetT0,fNbinsT0,fXminT0,fXmaxT0,&rmsT0);
1756 cogRMS = AliMathBase::GetCOG(arrayhRMS+offsetRMS,fNbinsRMS,fXminRMS,fXmaxRMS,&rms);
1761 //outlier specifications
1762 if ( (cogQ < ??) && (cogTime0 > ??) && (cogTime0<??) && ( cogRMS>??) ){
1769 rocQ->SetValue(iChannel, cogQ*cogQ);
1770 rocT0->SetValue(iChannel, cogTime0);
1771 rocT0Err->SetValue(iChannel, rmsT0);
1772 rocRMS->SetValue(iChannel, cogRMS);
1773 rocOut->SetValue(iChannel, cogOut);
1777 if ( fDebugLevel > 0 ){
1778 if ( !fDebugStreamer ) {
1780 TDirectory *backup = gDirectory;
1781 fDebugStreamer = new TTreeSRedirector("debugCalibCEAnalysis.root");
1782 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
1785 while ( iChannel > (fROC->GetRowIndexes(iSec)[row]+fROC->GetNPads(iSec,row)-1) ) row++;
1786 pad = iChannel-fROC->GetRowIndexes(iSec)[row];
1787 padc = pad-(fROC->GetNPads(iSec,row)/2);
1789 (*fDebugStreamer) << "DataEnd" <<
1790 "Sector=" << iSec <<
1794 "PadSec=" << iChannel <<
1796 "T0=" << cogTime0 <<
1805 if ( channelCounter>0 ){
1806 fMeanT0rms/=channelCounter;
1807 fMeanQrms/=channelCounter;
1808 fMeanRMSrms/=channelCounter;
1810 if ( fDebugStreamer ) fDebugStreamer->GetFile()->Write();
1811 // delete fDebugStreamer;
1812 // fDebugStreamer = 0x0;
1814 //_____________________________________________________________________
1815 void AliTPCCalibCE::DumpToFile(const Char_t *filename, const Char_t *dir, Bool_t append)
1818 // Write class to file
1827 option = "recreate";
1829 TDirectory *backup = gDirectory;
1830 TFile f(filename,option.Data());
1832 if ( !sDir.IsNull() ){
1833 f.mkdir(sDir.Data());
1839 if ( backup ) backup->cd();