]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/AliTPCCalibCE.cxx
Bug fixes (Jens)
[u/mrichter/AliRoot.git] / TPC / AliTPCCalibCE.cxx
CommitLineData
75d8233f 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16
17
18
19
75d8233f 20
21
22/* $Id$ */
23
24
25
26//Root includes
27#include <TObjArray.h>
28#include <TH1F.h>
29#include <TH2S.h>
30#include <TString.h>
31#include <TVectorF.h>
32#include <TVectorD.h>
33#include <TMatrixD.h>
34#include <TMath.h>
35#include <TGraph.h>
7fb602b1 36#include <TString.h>
75d8233f 37
38#include <TDirectory.h>
39#include <TSystem.h>
40#include <TFile.h>
41
42//AliRoot includes
43#include "AliRawReader.h"
44#include "AliRawReaderRoot.h"
45#include "AliRawReaderDate.h"
46#include "AliRawEventHeaderBase.h"
47#include "AliTPCRawStream.h"
48#include "AliTPCcalibDB.h"
49#include "AliTPCCalROC.h"
50#include "AliTPCCalPad.h"
51#include "AliTPCROC.h"
52#include "AliTPCParam.h"
53#include "AliTPCCalibCE.h"
75d8233f 54#include "AliMathBase.h"
55#include "TTreeStream.h"
56
57//date
58#include "event.h"
7fb602b1 59ClassImp(AliTPCCalibCE)
75d8233f 60
7fb602b1 61//////////////////////////////////////////////////////////////////////////////////////
62// Implementation of the TPC Central Electrode calibration
63//
64// Origin: Jens Wiechula, Marian Ivanov J.Wiechula@gsi.de, Marian.Ivanov@cern.ch
65//
66//
67//
68// *************************************************************************************
69// * Class Description *
70// *************************************************************************************
71//
72/* BEGIN_HTML
73 <h4>The AliTPCCalibCE class is used to get calibration data from the Central Electrode
74 using laser runs.</h4>
75
76 The information retrieved is
77 <ul style="list-style-type: square;">
78 <li>Time arrival from the CE</li>
79 <li>Signal width</li>
80 <li>Signal sum</li>
81 </ul>
82
83<h4>Overview:</h4>
84 <ol style="list-style-type: upper-roman;">
85 <li><a href="#working">Working principle</a></li>
86 <li><a href="#user">User interface for filling data</a></li>
87 <li><a href="#info">Stored information</a></li>
88 </ol>
89
90 <h3><a name="working">I. Working principle</a></h3>
91
92 <h4>Raw laser data is processed by calling one of the ProcessEvent(...) functions
93 (see below). These in the end call the Update(...) function.</h4>
94
95 <ul style="list-style-type: square;">
96 <li>the Update(...) function:<br />
97 In this function the array fPadSignal is filled with the adc signals between the specified range
98 fFirstTimeBin and fLastTimeBin for the current pad.
99 before going to the next pad the ProcessPad() function is called, which analyses the data for one pad
100 stored in fPadSignal.
101 </li>
102 <ul style="list-style-type: square;">
103 <li>the ProcessPad() function:</li>
104 <ol style="list-style-type: decimal;">
105 <li>Find Pedestal and Noise information</li>
106 <ul style="list-style-type: square;">
107 <li>use database information which has to be set by calling<br />
108 SetPedestalDatabase(AliTPCCalPad *pedestalTPC, AliTPCCalPad *padNoiseTPC)</li>
109 <li>if no information from the pedestal data base
110 is available the informaion is calculated on the fly
111 ( see FindPedestal() function )</li>
112 </ul>
113 <li>Find local maxima of the pad signal</li>
114 <ul style="list-style-type: square;">
115 <li>maxima arise from the laser tracks, the CE and also periodic postpeaks after the CE signal have
116 have been observed ( see FindLocalMaxima(...) )</li>
117 </ul>
118 <li>Find the CE signal information</li>
119 <ul style="list-style-type: square;">
120 <li>to find the position of the CE signal the Tmean information from the previos event is used
121 as the CE signal the local maximum closest to this Tmean is identified</li>
122 <li>calculate mean = T0, RMS = signal width and Q sum in a range of -4+7 timebins around Q max position
123 the Q sum is scaled by pad area (see FindPulserSignal(...) function)</li>
124 </ul>
125 <li>Fill a temprary array for the T0 information (GetPadTimesEvent(fCurrentSector,kTRUE)) (why see below)</li>
126 <li>Fill the Q sum and RMS values in the histograms (GetHisto[RMS,Q](ROC,kTRUE))</li>
127 </ol>
128 </ul>
129 </ul>
130
131 <h4>At the end of each event the EndEvent() function is called</h4>
132
133 <ul style="list-style-type: square;">
134 <li>the EndEvent() function:</li>
135 <ul style="list-style-type: square;">
136 <li>calculate the mean T0 for side A and side C. Fill T0 histogram with Time0-<Time0 for side[A,C]>
137 This is done to overcome syncronisation problems between the trigger and the fec clock.</li>
138 <li>calculate Mean T for each ROC using the COG aroud the median of the LocalMaxima distribution in one sector</li>
139 <li>calculate Mean Q</li>
140 <li>calculate Global fit parameters for Pol1 and Pol2 fits</li>
141 </ul>
142 </ul>
143
144 <h4>After accumulating the desired statistics the Analyse() function has to be called.</h4>
145 <ul style="list-style-type: square;">
146 <li>the Analyse() function:</li>
147 <ul style="list-style-type: square;">
148 <li>calculate the mean values of T0, RMS, Q for each pad, using
149 the AliMathBase::GetCOG(...) function</li>
150 <li>fill the calibration storage classes (AliTPCCalROC) for each ROC</li>
151 (The calibration information is stored in the TObjArrays fCalRocArrayT0, fCalRocArrayRMS and fCalRocArrayQ</li>
152 </ul>
153 </ul>
154
155 <h3><a name="user">II. User interface for filling data</a></h3>
156
157 <h4>To Fill information one of the following functions can be used:</h4>
158
159 <ul style="list-style-type: none;">
160 <li> Bool_t ProcessEvent(eventHeaderStruct *event);</li>
161 <ul style="list-style-type: square;">
162 <li>process Date event</li>
163 <li>use AliTPCRawReaderDate and call ProcessEvent(AliRawReader *rawReader)</li>
164 </ul>
165 <br />
166
167 <li> Bool_t ProcessEvent(AliRawReader *rawReader);</li>
168 <ul style="list-style-type: square;">
169 <li>process AliRawReader event</li>
170 <li>use AliTPCRawStream to loop over data and call ProcessEvent(AliTPCRawStream *rawStream)</li>
171 </ul>
172 <br />
173
174 <li> Bool_t ProcessEvent(AliTPCRawStream *rawStream);</li>
175 <ul style="list-style-type: square;">
176 <li>process event from AliTPCRawStream</li>
177 <li>call Update function for signal filling</li>
178 </ul>
179 <br />
180
181 <li> Int_t Update(const Int_t isector, const Int_t iRow, const Int_t
182 iPad, const Int_t iTimeBin, const Float_t signal);</li>
183 <ul style="list-style-type: square;">
184 <li>directly fill signal information (sector, row, pad, time bin, pad)
185 to the reference histograms</li>
186 </ul>
187 </ul>
188
189 <h4>It is also possible to merge two independently taken calibrations using the function</h4>
190
191 <ul style="list-style-type: none;">
192 <li> void Merge(AliTPCCalibSignal *sig)</li>
193 <ul style="list-style-type: square;">
194 <li>copy histograms in 'sig' if they do not exist in this instance</li>
195 <li>Add histograms in 'sig' to the histograms in this instance if the allready exist</li>
196 <li>After merging call Analyse again!</li>
197 </ul>
198 </ul>
199
200
201 <h4>example: filling data using root raw data:</h4>
202 <pre>
203 void fillCE(Char_t *filename)
204 {
205 rawReader = new AliRawReaderRoot(fileName);
206 if ( !rawReader ) return;
207 AliTPCCalibCE *calib = new AliTPCCalibCE;
208 while (rawReader->NextEvent()){
209 calib->ProcessEvent(rawReader);
210 }
211 calib->Analyse();
212 calib->DumpToFile("CEData.root");
213 delete rawReader;
214 delete calib;
215 }
216 </pre>
217
218 <h3><a name="info">III. What kind of information is stored and how to retrieve it</a></h4>
219
220 <h4><a name="info:stored">III.1 Stored information</a></h4>
221 <ul style="list-style-type: none;">
222 <li>Histograms:</li>
223 <ul style="list-style-type: none;">
224 <li>For each ROC three TH2S histos 'Reference Histograms' (ROC channel vs. [Time0, signal width, Q sum])
225 is created when it is filled for the first time (GetHisto[T0,RMS,Q](ROC,kTRUE)). The histos are
226 stored in the TObjArrays fHistoT0Array, fHistoRMSArray and fHistoQArray.</li>
227 </ul>
228 <br />
229
230 <li>Calibration Data:</li>
231 <ul style="list-style-type: none;">
232 <li>For each ROC three types of calibration data (AliTPCCalROC) is stored: for the mean arrival Time,
233 the signal width and the signal Sum. The AliTPCCalROC objects are stored in the TObjArrays
234 fCalRocArrayT0, fCalRocArrayRMS , fCalRocArrayQ. The object for each roc is created the first time it
235 is accessed (GetCalRoc[T0,RMS,Q](ROC,kTRUE));</li>
236 </ul>
237 <br />
238
239 <li>For each event the following information is stored:</li>
240
241 <ul style="list-style-type: square;">
242 <li>event time ( TVectorD fVEventTime )</li>
243 <li>event id ( TVectorD fVEventNumber )</li>
244 <br />
245 <li>mean arrival time for each ROC ( TObjArray fTMeanArrayEvent )</li>
246 <li>mean Q for each ROC ( TObjArray fQMeanArrayEvent )</li>
247 <li>parameters of a plane fit for each ROC ( TObjArray fParamArrayEventPol1 )</li>
248 <li>parameters of a 2D parabola fit for each ROC ( TObjArray fParamArrayEventPol2 )</li>
249 </ul>
250 </ul>
251
252 <h4><a name="info:retrieve">III.2 Retrieving information</a></h4>
253 <ul style="list-style-type: none;">
254 <li>Accessing the 'Reference Histograms' (Time0, signal width and Q sum information pad by pad):</li>
255 <ul style="list-style-type: square;">
256 <li>TH2F *GetHistoT0(Int_t sector);</li>
257 <li>TH2F *GetHistoRMS(Int_t sector);</li>
258 <li>TH2F *GetHistoQ(Int_t sector);</li>
259 </ul>
260 <br />
261
262 <li>Accessing the calibration storage objects:</li>
263 <ul style="list-style-type: square;">
264 <li>AliTPCCalROC *GetCalRocT0(Int_t sector); // for the Time0 values</li>
265 <li>AliTPCCalROC *GetCalRocRMS(Int_t sector); // for the signal width values</li>
266 <li>AliTPCCalROC *GetCalRocQ(Int_t sector); // for the Q sum values</li>
267 </ul>
268 <br />
269
270 <li>Accessin the event by event information:</li>
271 <ul style="list-style-type: square;">
272 <li>The event by event information can be displayed using the</li>
273 <li>MakeGraphTimeCE(Int_t sector, Int_t xVariable, Int_t fitType, Int_t fitParameter)</li>
274 <li>which creates a graph from the specified variables</li>
275 </ul>
276 </ul>
277
278 <h4>example for visualisation:</h4>
279 <pre>
280 //if the file "CEData.root" was created using the above example one could do the following:
281 TFile fileCE("CEData.root")
282 AliTPCCalibCE *ce = (AliTPCCalibCE*)fileCE->Get("AliTPCCalibCE");
283 ce->GetCalRocT0(0)->Draw("colz");
284 ce->GetCalRocRMS(0)->Draw("colz");
285
286 //or use the AliTPCCalPad functionality:
287 AliTPCCalPad padT0(ped->GetCalPadT0());
288 AliTPCCalPad padSigWidth(ped->GetCalPadRMS());
289 padT0->MakeHisto2D()->Draw("colz"); //Draw A-Side Time0 Information
290 padSigWidth->MakeHisto2D()->Draw("colz"); //Draw A-Side signal width Information
291
292 //display event by event information:
293 //Draw mean arrival time as a function of the event time for oroc sector A00
294 ce->MakeGraphTimeCE(36, 0, 2)->Draw("alp");
295 //Draw first derivative in local x from a plane fit as a function of the event time for oroc sector A00
296 ce->MakeGraphTimeCE(36, 0, 0, 1)->Draw("alp");
297 </pre>
298END_HTML */
299//////////////////////////////////////////////////////////////////////////////////////
300
301
302AliTPCCalibCE::AliTPCCalibCE() :
75d8233f 303 TObject(),
304 fFirstTimeBin(650),
305 fLastTimeBin(1000),
306 fNbinsT0(200),
307 fXminT0(-5),
308 fXmaxT0(5),
309 fNbinsQ(200),
bf57d87d 310 fXminQ(1),
311 fXmaxQ(40),
75d8233f 312 fNbinsRMS(100),
bf57d87d 313 fXminRMS(0.1),
314 fXmaxRMS(5.1),
75d8233f 315 fLastSector(-1),
316 fOldRCUformat(kTRUE),
317 fROC(AliTPCROC::Instance()),
318 fParam(new AliTPCParam),
319 fPedestalTPC(0x0),
320 fPadNoiseTPC(0x0),
321 fPedestalROC(0x0),
322 fPadNoiseROC(0x0),
75d8233f 323 fCalRocArrayT0(72),
324 fCalRocArrayQ(72),
325 fCalRocArrayRMS(72),
326 fCalRocArrayOutliers(72),
327 fHistoQArray(72),
328 fHistoT0Array(72),
329 fHistoRMSArray(72),
330 fHistoTmean(72),
75d8233f 331 fParamArrayEventPol1(72),
332 fParamArrayEventPol2(72),
7fb602b1 333 fTMeanArrayEvent(72),
334 fQMeanArrayEvent(72),
335 fVEventTime(10),
336 fVEventNumber(10),
75d8233f 337 fNevents(0),
338 fTimeStamp(0),
7fb602b1 339 fEventId(-1),
75d8233f 340 fRunNumber(-1),
341 fOldRunNumber(-1),
342 fPadTimesArrayEvent(72),
343 fPadQArrayEvent(72),
344 fPadRMSArrayEvent(72),
345 fPadPedestalArrayEvent(72),
346 fCurrentChannel(-1),
347 fCurrentSector(-1),
348 fCurrentRow(-1),
349 fMaxPadSignal(-1),
350 fMaxTimeBin(-1),
351 fPadSignal(1024),
352 fPadPedestal(0),
353 fPadNoise(0),
354 fVTime0Offset(72),
355 fVTime0OffsetCounter(72),
bf57d87d 356 fVMeanQ(72),
357 fVMeanQCounter(72),
75d8233f 358 fEvent(-1),
359 fDebugStreamer(0x0),
360 fDebugLevel(0)
361{
362 //
363 // AliTPCSignal default constructor
364 //
365// fHTime0 = new TH1F("hTime0Event","hTime0Event",(fLastTimeBin-fFirstTimeBin)*10,fFirstTimeBin,fLastTimeBin);
366}
367//_____________________________________________________________________
368AliTPCCalibCE::AliTPCCalibCE(const AliTPCCalibCE &sig) :
369 TObject(sig),
370 fFirstTimeBin(sig.fFirstTimeBin),
371 fLastTimeBin(sig.fLastTimeBin),
372 fNbinsT0(sig.fNbinsT0),
373 fXminT0(sig.fXminT0),
374 fXmaxT0(sig.fXmaxT0),
375 fNbinsQ(sig.fNbinsQ),
376 fXminQ(sig.fXminQ),
377 fXmaxQ(sig.fXmaxQ),
378 fNbinsRMS(sig.fNbinsRMS),
379 fXminRMS(sig.fXminRMS),
380 fXmaxRMS(sig.fXmaxRMS),
381 fLastSector(-1),
382 fOldRCUformat(kTRUE),
383 fROC(AliTPCROC::Instance()),
384 fParam(new AliTPCParam),
385 fPedestalTPC(0x0),
386 fPadNoiseTPC(0x0),
387 fPedestalROC(0x0),
388 fPadNoiseROC(0x0),
75d8233f 389 fCalRocArrayT0(72),
390 fCalRocArrayQ(72),
391 fCalRocArrayRMS(72),
392 fCalRocArrayOutliers(72),
393 fHistoQArray(72),
394 fHistoT0Array(72),
395 fHistoRMSArray(72),
396 fHistoTmean(72),
75d8233f 397 fParamArrayEventPol1(72),
398 fParamArrayEventPol2(72),
7fb602b1 399 fTMeanArrayEvent(72),
400 fQMeanArrayEvent(72),
75d8233f 401 fVEventTime(1000),
402 fVEventNumber(1000),
403 fNevents(sig.fNevents),
404 fTimeStamp(0),
7fb602b1 405 fEventId(-1),
75d8233f 406 fRunNumber(-1),
407 fOldRunNumber(-1),
408 fPadTimesArrayEvent(72),
409 fPadQArrayEvent(72),
410 fPadRMSArrayEvent(72),
411 fPadPedestalArrayEvent(72),
412 fCurrentChannel(-1),
413 fCurrentSector(-1),
414 fCurrentRow(-1),
415 fMaxPadSignal(-1),
416 fMaxTimeBin(-1),
417 fPadSignal(1024),
418 fPadPedestal(0),
bf57d87d 419 fPadNoise(0),
75d8233f 420 fVTime0Offset(72),
421 fVTime0OffsetCounter(72),
bf57d87d 422 fVMeanQ(72),
423 fVMeanQCounter(72),
75d8233f 424 fEvent(-1),
425 fDebugStreamer(0x0),
426 fDebugLevel(sig.fDebugLevel)
427{
428 //
7fb602b1 429 // AliTPCSignal copy constructor
75d8233f 430 //
431
7fb602b1 432 for (Int_t iSec = 0; iSec < 72; ++iSec){
75d8233f 433 const AliTPCCalROC *calQ = (AliTPCCalROC*)sig.fCalRocArrayQ.UncheckedAt(iSec);
434 const AliTPCCalROC *calT0 = (AliTPCCalROC*)sig.fCalRocArrayT0.UncheckedAt(iSec);
435 const AliTPCCalROC *calRMS = (AliTPCCalROC*)sig.fCalRocArrayRMS.UncheckedAt(iSec);
436 const AliTPCCalROC *calOut = (AliTPCCalROC*)sig.fCalRocArrayOutliers.UncheckedAt(iSec);
437
438 const TH2S *hQ = (TH2S*)sig.fHistoQArray.UncheckedAt(iSec);
439 const TH2S *hT0 = (TH2S*)sig.fHistoT0Array.UncheckedAt(iSec);
440 const TH2S *hRMS = (TH2S*)sig.fHistoRMSArray.UncheckedAt(iSec);
441
442 if ( calQ != 0x0 ) fCalRocArrayQ.AddAt(new AliTPCCalROC(*calQ), iSec);
443 if ( calT0 != 0x0 ) fCalRocArrayT0.AddAt(new AliTPCCalROC(*calT0), iSec);
444 if ( calRMS != 0x0 ) fCalRocArrayRMS.AddAt(new AliTPCCalROC(*calRMS), iSec);
445 if ( calOut != 0x0 ) fCalRocArrayOutliers.AddAt(new AliTPCCalROC(*calOut), iSec);
446
447 if ( hQ != 0x0 ){
7fb602b1 448// TDirectory *dir = hQ->GetDirectory();
449// hQ->SetDirectory(0);
75d8233f 450 TH2S *hNew = new TH2S(*hQ);
451 hNew->SetDirectory(0);
452 fHistoQArray.AddAt(hNew,iSec);
7fb602b1 453// hQ->SetDirectory(dir);
75d8233f 454 }
455 if ( hT0 != 0x0 ){
7fb602b1 456// TDirectory *dir = hT0->GetDirectory();
457// hT0->SetDirectory(0);
75d8233f 458 TH2S *hNew = new TH2S(*hT0);
459 hNew->SetDirectory(0);
7fb602b1 460 fHistoT0Array.AddAt(hNew,iSec);
461// hT0->SetDirectory(dir);
75d8233f 462 }
463 if ( hRMS != 0x0 ){
7fb602b1 464// TDirectory *dir = hRMS->GetDirectory();
465// hRMS->SetDirectory(0);
75d8233f 466 TH2S *hNew = new TH2S(*hRMS);
467 hNew->SetDirectory(0);
7fb602b1 468 fHistoRMSArray.AddAt(hNew,iSec);
469// hRMS->SetDirectory(dir);
75d8233f 470 }
471 }
75d8233f 472
7fb602b1 473 //copy fit parameters event by event
474 TObjArray *arr=0x0;
475 for (Int_t iSec=0; iSec<72; ++iSec){
476 arr = (TObjArray*)sig.fParamArrayEventPol1.UncheckedAt(iSec);
477 if ( arr ){
478 TObjArray *arrEvents = new TObjArray(arr->GetSize());
479 fParamArrayEventPol1.AddAt(arrEvents, iSec);
480 for (Int_t iEvent=0; iEvent<arr->GetSize(); ++iEvent)
481 if ( TVectorD *vec=(TVectorD*)arr->UncheckedAt(iEvent) )
482 arrEvents->AddAt(new TVectorD(*vec),iEvent);
483 }
484
485 arr = (TObjArray*)sig.fParamArrayEventPol2.UncheckedAt(iSec);
486 if ( arr ){
487 TObjArray *arrEvents = new TObjArray(arr->GetSize());
488 fParamArrayEventPol2.AddAt(arrEvents, iSec);
489 for (Int_t iEvent=0; iEvent<arr->GetSize(); ++iEvent)
490 if ( TVectorD *vec=(TVectorD*)arr->UncheckedAt(iEvent) )
491 arrEvents->AddAt(new TVectorD(*vec),iEvent);
492 }
493
494 TVectorF *vMeanTime = (TVectorF*)sig.fTMeanArrayEvent.UncheckedAt(iSec);
495 TVectorF *vMeanQ = (TVectorF*)sig.fQMeanArrayEvent.UncheckedAt(iSec);
496 if ( vMeanTime )
497 fTMeanArrayEvent.AddAt(new TVectorF(*vMeanTime), iSec);
498 if ( vMeanQ )
499 fQMeanArrayEvent.AddAt(new TVectorF(*vMeanQ), iSec);
500 }
501
502
503 fVEventTime.ResizeTo(sig.fVEventTime);
504 fVEventNumber.ResizeTo(sig.fVEventNumber);
505 fVEventTime.SetElements(sig.fVEventTime.GetMatrixArray());
506 fVEventNumber.SetElements(sig.fVEventNumber.GetMatrixArray());
507
75d8233f 508}
509//_____________________________________________________________________
510AliTPCCalibCE& AliTPCCalibCE::operator = (const AliTPCCalibCE &source)
511{
512 //
513 // assignment operator
514 //
515 if (&source == this) return *this;
516 new (this) AliTPCCalibCE(source);
517
518 return *this;
519}
520//_____________________________________________________________________
521AliTPCCalibCE::~AliTPCCalibCE()
522{
523 //
524 // destructor
525 //
526
527 fCalRocArrayT0.Delete();
528 fCalRocArrayQ.Delete();
529 fCalRocArrayRMS.Delete();
7fb602b1 530 fCalRocArrayOutliers.Delete();
75d8233f 531
532 fHistoQArray.Delete();
533 fHistoT0Array.Delete();
534 fHistoRMSArray.Delete();
535
7fb602b1 536 fHistoTmean.Delete();
537
538 fParamArrayEventPol1.Delete();
539 fParamArrayEventPol2.Delete();
540 fTMeanArrayEvent.Delete();
541 fQMeanArrayEvent.Delete();
542
75d8233f 543 fPadTimesArrayEvent.Delete();
544 fPadQArrayEvent.Delete();
545 fPadRMSArrayEvent.Delete();
546 fPadPedestalArrayEvent.Delete();
547
548 if ( fDebugStreamer) delete fDebugStreamer;
549// if ( fHTime0 ) delete fHTime0;
550 delete fROC;
551 delete fParam;
552}
553//_____________________________________________________________________
7fb602b1 554Int_t AliTPCCalibCE::Update(const Int_t icsector,
75d8233f 555 const Int_t icRow,
556 const Int_t icPad,
557 const Int_t icTimeBin,
558 const Float_t csignal)
559{
560 //
561 // Signal filling methode on the fly pedestal and Time offset correction if necessary.
562 // no extra analysis necessary. Assumes knowledge of the signal shape!
563 // assumes that it is looped over consecutive time bins of one pad
564 //
565 if ( (icTimeBin>fLastTimeBin) || (icTimeBin<fFirstTimeBin) ) return 0;
566
567 Int_t iChannel = fROC->GetRowIndexes(icsector)[icRow]+icPad; // global pad position in sector
568
569 //init first pad and sector in this event
570 if ( fCurrentChannel == -1 ) {
571 fCurrentChannel = iChannel;
572 fCurrentSector = icsector;
573 fCurrentRow = icRow;
574 }
575
576 //process last pad if we change to a new one
577 if ( iChannel != fCurrentChannel ){
578 ProcessPad();
579 fCurrentChannel = iChannel;
580 fCurrentSector = icsector;
581 fCurrentRow = icRow;
582 }
583
584 //fill signals for current pad
bf57d87d 585 fPadSignal.GetMatrixArray()[icTimeBin]=csignal;
75d8233f 586 if ( csignal > fMaxPadSignal ){
587 fMaxPadSignal = csignal;
588 fMaxTimeBin = icTimeBin;
589 }
590 return 0;
591}
592//_____________________________________________________________________
593void AliTPCCalibCE::FindPedestal(Float_t part)
594{
595 //
596 // find pedestal and noise for the current pad. Use either database or
597 // truncated mean with part*100%
598 //
7fb602b1 599 Bool_t noPedestal = kTRUE;
600
601 //use pedestal database if set
bf57d87d 602 if (fPedestalTPC&&fPadNoiseTPC){
75d8233f 603 //only load new pedestals if the sector has changed
604 if ( fCurrentSector!=fLastSector ){
605 fPedestalROC = fPedestalTPC->GetCalROC(fCurrentSector);
606 fPadNoiseROC = fPadNoiseTPC->GetCalROC(fCurrentSector);
607 fLastSector=fCurrentSector;
608 }
609
bf57d87d 610 if ( fPedestalROC&&fPadNoiseROC ){
75d8233f 611 fPadPedestal = fPedestalROC->GetValue(fCurrentChannel);
612 fPadNoise = fPadNoiseROC->GetValue(fCurrentChannel);
613 noPedestal = kFALSE;
614 }
615
616 }
617
618 //if we are not running with pedestal database, or for the current sector there is no information
619 //available, calculate the pedestal and noise on the fly
620 if ( noPedestal ) {
621 const Int_t kPedMax = 100; //maximum pedestal value
622 Float_t max = 0;
623 Float_t maxPos = 0;
624 Int_t median = -1;
625 Int_t count0 = 0;
626 Int_t count1 = 0;
627 //
bf57d87d 628 Float_t padSignal=0;
629 //
75d8233f 630 UShort_t histo[kPedMax];
631 memset(histo,0,kPedMax*sizeof(UShort_t));
bf57d87d 632
7fb602b1 633 //fill pedestal histogram
634 for (Int_t i=fFirstTimeBin; i<=fLastTimeBin; ++i){
bf57d87d 635 padSignal = fPadSignal.GetMatrixArray()[i];
636 if (padSignal<=0) continue;
637 if (padSignal>max && i>10) {
638 max = padSignal;
75d8233f 639 maxPos = i;
640 }
bf57d87d 641 if (padSignal>kPedMax-1) continue;
642 histo[int(padSignal+0.5)]++;
75d8233f 643 count0++;
644 }
7fb602b1 645 //find median
646 for (Int_t i=1; i<kPedMax; ++i){
75d8233f 647 if (count1<count0*0.5) median=i;
648 count1+=histo[i];
649 }
650 // truncated mean
651 //
652 Float_t count=histo[median] ,mean=histo[median]*median, rms=histo[median]*median*median ;
653 //
7fb602b1 654 for (Int_t idelta=1; idelta<10; ++idelta){
75d8233f 655 if (median-idelta<=0) continue;
656 if (median+idelta>kPedMax) continue;
657 if (count<part*count1){
658 count+=histo[median-idelta];
659 mean +=histo[median-idelta]*(median-idelta);
660 rms +=histo[median-idelta]*(median-idelta)*(median-idelta);
661 count+=histo[median+idelta];
662 mean +=histo[median+idelta]*(median+idelta);
663 rms +=histo[median+idelta]*(median+idelta)*(median+idelta);
664 }
665 }
666 fPadPedestal = 0;
667 fPadNoise = 0;
668 if ( count > 0 ) {
669 mean/=count;
670 rms = TMath::Sqrt(TMath::Abs(rms/count-mean*mean));
671 fPadPedestal = mean;
672 fPadNoise = rms;
673 }
674 }
675}
676//_____________________________________________________________________
677void AliTPCCalibCE::FindCESignal(TVectorD &param, Float_t &qSum, const TVectorF maxima)
678{
679 //
680 // Find position, signal width and height of the CE signal (last signal)
681 // param[0] = Qmax, param[1] = mean time, param[2] = rms;
682 // maxima: array of local maxima of the pad signal use the one closest to the mean CE position
683 //
684
685 Float_t ceQmax =0, ceQsum=0, ceTime=0, ceRMS=0;
686 Int_t cemaxpos = 0;
687 Float_t ceSumThreshold = 8.*fPadNoise; // threshold for the signal sum
688 const Int_t kCemin = 4; // range for the analysis of the ce signal +- channels from the peak
689 const Int_t kCemax = 7;
690
bf57d87d 691 Float_t minDist = 25; //initial minimum distance betweek roc mean ce signal and pad ce signal
692
75d8233f 693 // find maximum closest to the sector mean from the last event
7fb602b1 694 for ( Int_t imax=0; imax<maxima.GetNrows(); ++imax){
695 // get sector mean of last event
696 Float_t tmean = (*GetTMeanEvents(fCurrentSector))[fNevents-1];
75d8233f 697 if ( TMath::Abs( tmean-maxima[imax] ) < minDist ) {
698 minDist = tmean-maxima[imax];
699 cemaxpos = (Int_t)maxima[imax];
700 }
701 }
702
703 if (cemaxpos!=0){
bf57d87d 704 ceQmax = fPadSignal.GetMatrixArray()[cemaxpos]-fPadPedestal;
7fb602b1 705 for (Int_t i=cemaxpos-kCemin; i<cemaxpos+kCemax; ++i){
706 if ( (i>fFirstTimeBin) && (i<fLastTimeBin) ){
707 Float_t signal = fPadSignal.GetMatrixArray()[i]-fPadPedestal;
708 if (signal>0) {
709 ceTime+=signal*(i+0.5);
710 ceRMS +=signal*(i+0.5)*(i+0.5);
711 ceQsum+=signal;
712 }
75d8233f 713 }
714 }
715 }
716 if (ceQmax&&ceQsum>ceSumThreshold) {
717 ceTime/=ceQsum;
718 ceRMS = TMath::Sqrt(TMath::Abs(ceRMS/ceQsum-ceTime*ceTime));
bf57d87d 719 fVTime0Offset.GetMatrixArray()[fCurrentSector]+=ceTime; // mean time for each sector
720 fVTime0OffsetCounter.GetMatrixArray()[fCurrentSector]++;
721
722 //Normalise Q to pad area of irocs
723 Float_t norm = fParam->GetPadPitchWidth(fCurrentSector)*fParam->GetPadPitchLength(fCurrentSector,fCurrentRow);
724
725 ceQsum/=norm;
726 fVMeanQ.GetMatrixArray()[fCurrentSector]+=ceQsum;
727 fVMeanQCounter.GetMatrixArray()[fCurrentSector]++;
75d8233f 728 } else {
729 ceQmax=0;
730 ceTime=0;
731 ceRMS =0;
732 ceQsum=0;
733 }
734 param[0] = ceQmax;
735 param[1] = ceTime;
736 param[2] = ceRMS;
737 qSum = ceQsum;
738}
739//_____________________________________________________________________
740Bool_t AliTPCCalibCE::IsPeak(Int_t pos, Int_t tminus, Int_t tplus)
741{
742 //
743 // Check if 'pos' is a Maximum. Consider 'tminus' timebins before
744 // and 'tplus' timebins after 'pos'
745 //
7fb602b1 746 if ( (pos-tminus)<fFirstTimeBin || (pos+tplus)>fLastTimeBin ) return kFALSE;
747 for (Int_t iTime = pos; iTime>pos-tminus; --iTime)
75d8233f 748 if ( fPadSignal[iTime-1] >= fPadSignal[iTime] ) return kFALSE;
7fb602b1 749 for (Int_t iTime = pos, iTime2=pos; iTime<pos+tplus; ++iTime, ++iTime2){
75d8233f 750 if ( (iTime==pos) && (fPadSignal[iTime+1]==fPadSignal[iTime]) ) // allow two timebins with same adc value
7fb602b1 751 ++iTime2;
75d8233f 752 if ( fPadSignal[iTime2+1] >= fPadSignal[iTime2] ) return kFALSE;
753 }
754 return kTRUE;
755}
756//_____________________________________________________________________
757void AliTPCCalibCE::FindLocalMaxima(TVectorF &maxima)
758{
759 //
760 // Find local maxima on the pad signal and Histogram them
761 //
762 Float_t ceThreshold = 5.*fPadNoise; // threshold for the signal
763 Int_t count = 0;
764 Int_t tminus = 2;
765 Int_t tplus = 3;
7fb602b1 766 for (Int_t i=fLastTimeBin-tplus-1; i>=fFirstTimeBin+tminus; --i){
75d8233f 767 if ( (fPadSignal[i]-fPadPedestal)>ceThreshold && IsPeak(i,tminus,tplus) ){
7fb602b1 768 if (count<maxima.GetNrows()){
bf57d87d 769 maxima.GetMatrixArray()[count++]=i;
75d8233f 770 GetHistoTmean(fCurrentSector,kTRUE)->Fill(i);
7fb602b1 771 }
75d8233f 772 }
773 }
774}
775//_____________________________________________________________________
7fb602b1 776void AliTPCCalibCE::ProcessPad()
75d8233f 777{
778 //
779 // Process data of current pad
780 //
781 FindPedestal();
782
7fb602b1 783 TVectorF maxima(15); // the expected maximum number of maxima in the complete TPC should be 8 laser beam layers
784 // + central electrode and possibly post peaks from the CE signal
785 // however if we are on a high noise pad a lot more peaks due to the noise might occur
75d8233f 786 FindLocalMaxima(maxima);
787 if ( (fNevents == 0) || (fOldRunNumber!=fRunNumber) ) return; // return because we don't have Time0 info for the CE yet
788
789
790
791 TVectorD param(3);
792 Float_t Qsum;
793 FindCESignal(param, Qsum, maxima);
794
795 Double_t meanT = param[1];
796 Double_t sigmaT = param[2];
797
798 //Fill Event T0 counter
bf57d87d 799 (*GetPadTimesEvent(fCurrentSector,kTRUE)).GetMatrixArray()[fCurrentChannel] = meanT;
75d8233f 800
801 //Fill Q histogram
bf57d87d 802 GetHistoQ(fCurrentSector,kTRUE)->Fill( TMath::Sqrt(Qsum), fCurrentChannel );
75d8233f 803
804 //Fill RMS histogram
805 GetHistoRMS(fCurrentSector,kTRUE)->Fill( sigmaT, fCurrentChannel );
806
807
808 //Fill debugging info
809 if ( fDebugLevel>0 ){
bf57d87d 810 (*GetPadPedestalEvent(fCurrentSector,kTRUE)).GetMatrixArray()[fCurrentChannel]=fPadPedestal;
811 (*GetPadRMSEvent(fCurrentSector,kTRUE)).GetMatrixArray()[fCurrentChannel]=sigmaT;
812 (*GetPadQEvent(fCurrentSector,kTRUE)).GetMatrixArray()[fCurrentChannel]=Qsum;
75d8233f 813 }
814
815 ResetPad();
816}
817//_____________________________________________________________________
7fb602b1 818void AliTPCCalibCE::EndEvent()
75d8233f 819{
820 //
821 // Process data of current pad
822 // The Functions 'SetTimeStamp' and 'SetRunNumber' should be called
823 // before the EndEvent function to set the event timestamp and number!!!
824 // This is automatically done if the ProcessEvent(AliRawReader *rawReader)
825 // function was called
826 //
827
828 //check if last pad has allready been processed, if not do so
829 if ( fMaxTimeBin>-1 ) ProcessPad();
830
831 TVectorD param(3);
832 TMatrixD dummy(3,3);
7fb602b1 833// TVectorF vMeanTime(72);
834// TVectorF vMeanQ(72);
835 AliTPCCalROC *calIroc=new AliTPCCalROC(0);
836 AliTPCCalROC *calOroc=new AliTPCCalROC(36);
75d8233f 837
838 //find mean time0 offset for side A and C
839 Double_t time0Side[2]; //time0 for side A:0 and C:0
840 Double_t time0SideCount[2]; //time0 counter for side A:0 and C:0
841 time0Side[0]=0;time0Side[1]=0;time0SideCount[0]=0;time0SideCount[1]=0;
7fb602b1 842 for ( Int_t iSec = 0; iSec<72; ++iSec ){
bf57d87d 843 time0Side[(iSec/18)%2] += fVTime0Offset.GetMatrixArray()[iSec];
844 time0SideCount[(iSec/18)%2] += fVTime0OffsetCounter.GetMatrixArray()[iSec];
75d8233f 845 }
bf57d87d 846 if ( time0SideCount[0] >0 )
847 time0Side[0]/=time0SideCount[0];
848 if ( time0SideCount[1] >0 )
849 time0Side[1]/=time0SideCount[1];
75d8233f 850 // end find time0 offset
bf57d87d 851
75d8233f 852 //loop over all ROCs, fill CE Time histogram corrected for the mean Time0 of each ROC
7fb602b1 853 for ( Int_t iSec = 0; iSec<72; ++iSec ){
bf57d87d 854 //find median and then calculate the mean around it
7fb602b1 855 TH1S *hMeanT = GetHistoTmean(iSec); //histogram with local maxima position information
bf57d87d 856 if ( !hMeanT ) continue;
7fb602b1 857
75d8233f 858 Double_t entries = hMeanT->GetEntries();
859 Double_t sum = 0;
860 Short_t *arr = hMeanT->GetArray()+1;
861 Int_t ibin=0;
7fb602b1 862 for ( ibin=0; ibin<hMeanT->GetNbinsX(); ++ibin){
75d8233f 863 sum+=arr[ibin];
864 if ( sum>=(entries/2) ) break;
865 }
866 Int_t delta = 4;
867 Int_t firstBin = fFirstTimeBin+ibin-delta;
868 Int_t lastBin = fFirstTimeBin+ibin+delta;
869 if ( firstBin<fFirstTimeBin ) firstBin=fFirstTimeBin;
870 if ( lastBin>fLastTimeBin ) lastBin =fLastTimeBin;
bf57d87d 871 Float_t median =AliMathBase::GetCOG(arr+ibin-delta,2*delta,firstBin,lastBin);
7fb602b1 872
873 // check boundaries for ebye info of mean time
874 TVectorF *vMeanTime=GetTMeanEvents(iSec,kTRUE);
875 Int_t vSize=vMeanTime->GetNrows();
876 if ( vSize < fNevents+1 )
877 vMeanTime->ResizeTo(vSize+100);
878
879 vMeanTime->GetMatrixArray()[fNevents]=median;
bf57d87d 880 // end find median
881
882 TVectorF *vTimes = GetPadTimesEvent(iSec);
7fb602b1 883 if ( !vTimes ) continue; //continue if no time information for this sector is available
884
885
bf57d87d 886 AliTPCCalROC calIrocOutliers(0);
887 AliTPCCalROC calOrocOutliers(36);
888
889 // calculate mean Q of the sector
890 Float_t meanQ = 0;
891 if ( fVMeanQCounter.GetMatrixArray()[iSec]>0 ) meanQ=fVMeanQ.GetMatrixArray()[iSec]/fVMeanQCounter.GetMatrixArray()[iSec];
7fb602b1 892 TVectorF *vMeanQ=GetQMeanEvents(iSec,kTRUE);
893 if ( vSize < fNevents+1 ) // vSize is the same as for vMeanTime!
894 vMeanQ->ResizeTo(vSize+100);
75d8233f 895
7fb602b1 896 vMeanQ->GetMatrixArray()[fNevents]=meanQ;
897
898 for ( UInt_t iChannel=0; iChannel<fROC->GetNChannels(iSec); ++iChannel ){
bf57d87d 899 Float_t Time = (*vTimes).GetMatrixArray()[iChannel];
75d8233f 900
901 //set values for temporary roc calibration class
bf57d87d 902 if ( iSec < 36 ) {
7fb602b1 903 calIroc->SetValue(iChannel, Time);
bf57d87d 904 if ( Time == 0 ) calIrocOutliers.SetValue(iChannel,1);
905
906 } else {
7fb602b1 907 calOroc->SetValue(iChannel, Time);
bf57d87d 908 if ( Time == 0 ) calOrocOutliers.SetValue(iChannel,1);
909 }
75d8233f 910
911 if ( (fNevents>0) && (fOldRunNumber==fRunNumber) )
912 GetHistoT0(iSec,kTRUE)->Fill( Time-time0Side[(iSec/18)%2],iChannel );
913
914
915
916 //------------------------------- Debug start ------------------------------
917 if ( fDebugLevel>0 ){
918 if ( !fDebugStreamer ) {
919 //debug stream
920 TDirectory *backup = gDirectory;
921 fDebugStreamer = new TTreeSRedirector("debugCalibCE.root");
922 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
923 }
924
925 Int_t row=0;
926 Int_t pad=0;
927 Int_t padc=0;
928
929 Float_t Q = (*GetPadQEvent(iSec))[iChannel];
930 Float_t RMS = (*GetPadRMSEvent(iSec))[iChannel];
931
932 UInt_t channel=iChannel;
933 Int_t sector=iSec;
934
935 while ( channel > (fROC->GetRowIndexes(sector)[row]+fROC->GetNPads(sector,row)-1) ) row++;
936 pad = channel-fROC->GetRowIndexes(sector)[row];
937 padc = pad-(fROC->GetNPads(sector,row)/2);
938
939// TH1F *h1 = new TH1F(Form("hSignalD%d.%d.%d",sector,row,pad),
940// Form("hSignalD%d.%d.%d",sector,row,pad),
941// fLastTimeBin-fFirstTimeBin,
942// fFirstTimeBin,fLastTimeBin);
943// h1->SetDirectory(0);
944//
7fb602b1 945// for (Int_t i=fFirstTimeBin; i<fLastTimeBin+1; ++i)
75d8233f 946// h1->Fill(i,fPadSignal(i));
947
bf57d87d 948 Double_t T0Sec = 0;
949 if (fVTime0OffsetCounter.GetMatrixArray()[iSec]>0)
950 T0Sec = fVTime0Offset.GetMatrixArray()[iSec]/fVTime0OffsetCounter.GetMatrixArray()[iSec];
951 Double_t T0Side = time0Side[(iSec/18)%2];
75d8233f 952 (*fDebugStreamer) << "DataPad" <<
953 "Event=" << fNevents <<
7fb602b1 954 "RunNumber=" << fRunNumber <<
bf57d87d 955 "TimeStamp=" << fTimeStamp <<
75d8233f 956 "Sector="<< sector <<
957 "Row=" << row<<
958 "Pad=" << pad <<
959 "PadC=" << padc <<
960 "PadSec="<< channel <<
961 "Time0Sec=" << T0Sec <<
bf57d87d 962 "Time0Side=" << T0Side <<
75d8233f 963 "Time=" << Time <<
964 "RMS=" << RMS <<
965 "Sum=" << Q <<
bf57d87d 966 "MeanQ=" << meanQ <<
967 // "hist.=" << h1 <<
75d8233f 968 "\n";
969
bf57d87d 970 // delete h1;
971
75d8233f 972 }
973 //----------------------------- Debug end ------------------------------
974 }// end channel loop
975 hMeanT->Reset();
976
977 TVectorD paramPol1(3);
978 TVectorD paramPol2(6);
979 TMatrixD matPol1(3,3);
980 TMatrixD matPol2(6,6);
bf57d87d 981 Float_t chi2Pol1=0;
982 Float_t chi2Pol2=0;
75d8233f 983
984 if ( (fNevents>0) && (fOldRunNumber==fRunNumber) ){
985 if ( iSec < 36 ){
7fb602b1 986 calIroc->GlobalFit(&calIrocOutliers,0,paramPol1,matPol1,chi2Pol1,0);
987 calIroc->GlobalFit(&calIrocOutliers,0,paramPol2,matPol2,chi2Pol2,1);
75d8233f 988 } else {
7fb602b1 989 calOroc->GlobalFit(&calOrocOutliers,0,paramPol1,matPol1,chi2Pol1,0);
990 calOroc->GlobalFit(&calOrocOutliers,0,paramPol2,matPol2,chi2Pol2,1);
75d8233f 991 }
992
993 GetParamArrayPol1(iSec,kTRUE)->AddAtAndExpand(new TVectorD(paramPol1), fNevents);
994 GetParamArrayPol2(iSec,kTRUE)->AddAtAndExpand(new TVectorD(paramPol2), fNevents);
995 }
bf57d87d 996// printf("events: %d -- size: %d\n",fNevents,GetParamArrayPol1(iSec)->GetSize());
75d8233f 997
998 //------------------------------- Debug start ------------------------------
999 if ( fDebugLevel>0 ){
bf57d87d 1000 if ( !fDebugStreamer ) {
1001 //debug stream
1002 TDirectory *backup = gDirectory;
1003 fDebugStreamer = new TTreeSRedirector("debugCalibCE.root");
1004 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
1005 }
75d8233f 1006 (*fDebugStreamer) << "DataRoc" <<
1007 "Event=" << fEvent <<
7fb602b1 1008 "RunNumber=" << fRunNumber <<
75d8233f 1009 "TimeStamp=" << fTimeStamp <<
1010 "Sector="<< iSec <<
1011 "hMeanT.=" << hMeanT <<
1012 "median=" << median <<
1013 "paramPol1.=" << &paramPol1 <<
1014 "paramPol2.=" << &paramPol2 <<
1015 "matPol1.=" << &matPol1 <<
1016 "matPol2.=" << &matPol2 <<
1017 "chi2Pol1=" << chi2Pol1 <<
1018 "chi2Pol2=" << chi2Pol2 <<
1019 "\n";
1020 }
1021 //------------------------------- Debug end ------------------------------
1022 }// end sector loop
1023
7fb602b1 1024// fTMeanArrayEvent.AddAtAndExpand(new TVectorF(vMeanTime),fNevents);
1025// fQMeanArrayEvent.AddAtAndExpand(new TVectorF(vMeanQ),fNevents);
1026 if ( fVEventTime.GetNrows() < fNevents+1 ) {
1027 fVEventTime.ResizeTo((Int_t)(fVEventTime.GetNrows()+100));
1028 fVEventNumber.ResizeTo((Int_t)(fVEventNumber.GetNrows()+100));
75d8233f 1029 }
7fb602b1 1030 fVEventTime.GetMatrixArray()[fNevents] = fTimeStamp;
1031 fVEventNumber.GetMatrixArray()[fNevents] = fEventId;
75d8233f 1032
1033 fNevents++;
1034 fOldRunNumber = fRunNumber;
1035
7fb602b1 1036 delete calIroc;
1037 delete calOroc;
75d8233f 1038}
1039//_____________________________________________________________________
7fb602b1 1040Bool_t AliTPCCalibCE::ProcessEvent(AliTPCRawStream *rawStream)
75d8233f 1041{
1042 //
1043 // Event Processing loop - AliTPCRawStream
1044 // The Function 'SetTimeStamp' should be called for each event to set the event time stamp!!!
1045 //
1046
1047 rawStream->SetOldRCUFormat(fOldRCUformat);
1048
1049 ResetEvent();
1050
1051 Bool_t withInput = kFALSE;
1052
1053 while (rawStream->Next()) {
1054
1055 Int_t isector = rawStream->GetSector(); // current sector
1056 Int_t iRow = rawStream->GetRow(); // current row
1057 Int_t iPad = rawStream->GetPad(); // current pad
1058 Int_t iTimeBin = rawStream->GetTime(); // current time bin
1059 Float_t signal = rawStream->GetSignal(); // current ADC signal
1060
1061 Update(isector,iRow,iPad,iTimeBin,signal);
1062 withInput = kTRUE;
1063 }
1064
1065 if (withInput){
1066 EndEvent();
1067 }
1068
1069 return withInput;
1070}
1071//_____________________________________________________________________
1072Bool_t AliTPCCalibCE::ProcessEvent(AliRawReader *rawReader)
1073{
1074 //
1075 // Event processing loop - AliRawReader
1076 //
1077
1078
1079 AliTPCRawStream rawStream(rawReader);
1080 AliRawEventHeaderBase* eventHeader = (AliRawEventHeaderBase*)rawReader->GetEventHeader();
1081 if (eventHeader){
1082 fTimeStamp = eventHeader->Get("Timestamp");
7fb602b1 1083 fRunNumber = eventHeader->Get("RunNb");
75d8233f 1084 }
7fb602b1 1085 fEventId = *rawReader->GetEventId();
75d8233f 1086
1087
7fb602b1 1088 rawReader->Select("TPC");
75d8233f 1089
1090 return ProcessEvent(&rawStream);
1091}
1092//_____________________________________________________________________
1093Bool_t AliTPCCalibCE::ProcessEvent(eventHeaderStruct *event)
1094{
1095 //
1096 // Event processing loop - date event
1097 //
1098 AliRawReader *rawReader = new AliRawReaderDate((void*)event);
1099 Bool_t result=ProcessEvent(rawReader);
1100 delete rawReader;
1101 return result;
1102
1103}
1104//_____________________________________________________________________
7fb602b1 1105TH2S* AliTPCCalibCE::GetHisto(Int_t sector, TObjArray *arr,
75d8233f 1106 Int_t nbinsY, Float_t ymin, Float_t ymax,
1107 Char_t *type, Bool_t force)
1108{
1109 //
1110 // return pointer to TH2S histogram of 'type'
1111 // if force is true create a new histogram if it doesn't exist allready
1112 //
1113 if ( !force || arr->UncheckedAt(sector) )
1114 return (TH2S*)arr->UncheckedAt(sector);
1115
7fb602b1 1116 // if we are forced and histogram doesn't exist yet create it
75d8233f 1117 Char_t name[255], title[255];
1118
1119 sprintf(name,"hCalib%s%.2d",type,sector);
1120 sprintf(title,"%s calibration histogram sector %.2d",type,sector);
1121
1122 // new histogram with Q calib information. One value for each pad!
1123 TH2S* hist = new TH2S(name,title,
1124 nbinsY, ymin, ymax,
1125 fROC->GetNChannels(sector),0,fROC->GetNChannels(sector));
1126 hist->SetDirectory(0);
1127 arr->AddAt(hist,sector);
1128 return hist;
1129}
1130//_____________________________________________________________________
7fb602b1 1131TH2S* AliTPCCalibCE::GetHistoT0(Int_t sector, Bool_t force)
75d8233f 1132{
1133 //
1134 // return pointer to T0 histogram
1135 // if force is true create a new histogram if it doesn't exist allready
1136 //
1137 TObjArray *arr = &fHistoT0Array;
1138 return GetHisto(sector, arr, fNbinsT0, fXminT0, fXmaxT0, "T0", force);
1139}
1140//_____________________________________________________________________
7fb602b1 1141TH2S* AliTPCCalibCE::GetHistoQ(Int_t sector, Bool_t force)
75d8233f 1142{
1143 //
1144 // return pointer to Q histogram
1145 // if force is true create a new histogram if it doesn't exist allready
1146 //
1147 TObjArray *arr = &fHistoQArray;
1148 return GetHisto(sector, arr, fNbinsQ, fXminQ, fXmaxQ, "Q", force);
1149}
1150//_____________________________________________________________________
7fb602b1 1151TH2S* AliTPCCalibCE::GetHistoRMS(Int_t sector, Bool_t force)
75d8233f 1152{
1153 //
1154 // return pointer to Q histogram
1155 // if force is true create a new histogram if it doesn't exist allready
1156 //
1157 TObjArray *arr = &fHistoRMSArray;
1158 return GetHisto(sector, arr, fNbinsRMS, fXminRMS, fXmaxRMS, "RMS", force);
1159}
1160//_____________________________________________________________________
1161TH1S* AliTPCCalibCE::GetHisto(Int_t sector, TObjArray *arr,
1162 Char_t *type, Bool_t force)
1163{
1164 //
1165 // return pointer to TH1S histogram
1166 // if force is true create a new histogram if it doesn't exist allready
1167 //
1168 if ( !force || arr->UncheckedAt(sector) )
1169 return (TH1S*)arr->UncheckedAt(sector);
1170
1171 // if we are forced and histogram doesn't yes exist create it
1172 Char_t name[255], title[255];
1173
1174 sprintf(name,"hCalib%s%.2d",type,sector);
1175 sprintf(title,"%s calibration histogram sector %.2d",type,sector);
1176
1177 // new histogram with Q calib information. One value for each pad!
1178 TH1S* hist = new TH1S(name,title,
1179 fLastTimeBin-fFirstTimeBin,fFirstTimeBin,fLastTimeBin);
1180 hist->SetDirectory(0);
1181 arr->AddAt(hist,sector);
1182 return hist;
1183}
1184//_____________________________________________________________________
1185TH1S* AliTPCCalibCE::GetHistoTmean(Int_t sector, Bool_t force)
1186{
1187 //
1188 // return pointer to Q histogram
1189 // if force is true create a new histogram if it doesn't exist allready
1190 //
1191 TObjArray *arr = &fHistoTmean;
1192 return GetHisto(sector, arr, "LastTmean", force);
1193}
1194//_____________________________________________________________________
7fb602b1 1195TVectorF* AliTPCCalibCE::GetVectSector(Int_t sector, TObjArray *arr, UInt_t size, Bool_t force)
75d8233f 1196{
1197 //
1198 // return pointer to Pad Info from 'arr' for the current event and sector
1199 // if force is true create it if it doesn't exist allready
1200 //
1201 if ( !force || arr->UncheckedAt(sector) )
1202 return (TVectorF*)arr->UncheckedAt(sector);
1203
7fb602b1 1204 TVectorF *vect = new TVectorF(size);
75d8233f 1205 arr->AddAt(vect,sector);
1206 return vect;
1207}
1208//_____________________________________________________________________
7fb602b1 1209TVectorF* AliTPCCalibCE::GetPadTimesEvent(Int_t sector, Bool_t force)
75d8233f 1210{
1211 //
1212 // return pointer to Pad Times Array for the current event and sector
1213 // if force is true create it if it doesn't exist allready
1214 //
1215 TObjArray *arr = &fPadTimesArrayEvent;
7fb602b1 1216 return GetVectSector(sector,arr,fROC->GetNChannels(sector),force);
75d8233f 1217}
1218//_____________________________________________________________________
7fb602b1 1219TVectorF* AliTPCCalibCE::GetPadQEvent(Int_t sector, Bool_t force)
75d8233f 1220{
1221 //
1222 // return pointer to Pad Q Array for the current event and sector
1223 // if force is true create it if it doesn't exist allready
1224 // for debugging purposes only
1225 //
1226
1227 TObjArray *arr = &fPadQArrayEvent;
7fb602b1 1228 return GetVectSector(sector,arr,fROC->GetNChannels(sector),force);
75d8233f 1229}
1230//_____________________________________________________________________
7fb602b1 1231TVectorF* AliTPCCalibCE::GetPadRMSEvent(Int_t sector, Bool_t force)
75d8233f 1232{
1233 //
1234 // return pointer to Pad RMS Array for the current event and sector
1235 // if force is true create it if it doesn't exist allready
1236 // for debugging purposes only
1237 //
1238 TObjArray *arr = &fPadRMSArrayEvent;
7fb602b1 1239 return GetVectSector(sector,arr,fROC->GetNChannels(sector),force);
75d8233f 1240}
1241//_____________________________________________________________________
7fb602b1 1242TVectorF* AliTPCCalibCE::GetPadPedestalEvent(Int_t sector, Bool_t force)
75d8233f 1243{
1244 //
1245 // return pointer to Pad RMS Array for the current event and sector
1246 // if force is true create it if it doesn't exist allready
1247 // for debugging purposes only
1248 //
1249 TObjArray *arr = &fPadPedestalArrayEvent;
7fb602b1 1250 return GetVectSector(sector,arr,fROC->GetNChannels(sector),force);
1251}
1252//_____________________________________________________________________
1253TVectorF* AliTPCCalibCE::GetTMeanEvents(Int_t sector, Bool_t force)
1254{
1255 //
1256 // return pointer to the EbyE info of the mean arrival time for 'sector'
1257 // if force is true create it if it doesn't exist allready
1258 //
1259 TObjArray *arr = &fTMeanArrayEvent;
1260 return GetVectSector(sector,arr,100,force);
75d8233f 1261}
1262//_____________________________________________________________________
7fb602b1 1263TVectorF* AliTPCCalibCE::GetQMeanEvents(Int_t sector, Bool_t force)
1264{
1265 //
1266 // return pointer to the EbyE info of the mean arrival time for 'sector'
1267 // if force is true create it if it doesn't exist allready
1268 //
1269 TObjArray *arr = &fQMeanArrayEvent;
1270 return GetVectSector(sector,arr,100,force);
1271}
1272//_____________________________________________________________________
1273AliTPCCalROC* AliTPCCalibCE::GetCalRoc(Int_t sector, TObjArray* arr, Bool_t force)
75d8233f 1274{
1275 //
1276 // return pointer to ROC Calibration
1277 // if force is true create a new histogram if it doesn't exist allready
1278 //
1279 if ( !force || arr->UncheckedAt(sector) )
1280 return (AliTPCCalROC*)arr->UncheckedAt(sector);
1281
1282 // if we are forced and histogram doesn't yes exist create it
1283
1284 // new AliTPCCalROC for T0 information. One value for each pad!
1285 AliTPCCalROC *croc = new AliTPCCalROC(sector);
75d8233f 1286 arr->AddAt(croc,sector);
1287 return croc;
1288}
1289//_____________________________________________________________________
7fb602b1 1290AliTPCCalROC* AliTPCCalibCE::GetCalRocT0(Int_t sector, Bool_t force)
75d8233f 1291{
1292 //
1293 // return pointer to Carge ROC Calibration
1294 // if force is true create a new histogram if it doesn't exist allready
1295 //
1296 TObjArray *arr = &fCalRocArrayT0;
1297 return GetCalRoc(sector, arr, force);
1298}
1299//_____________________________________________________________________
7fb602b1 1300AliTPCCalROC* AliTPCCalibCE::GetCalRocQ(Int_t sector, Bool_t force)
75d8233f 1301{
1302 //
1303 // return pointer to T0 ROC Calibration
1304 // if force is true create a new histogram if it doesn't exist allready
1305 //
1306 TObjArray *arr = &fCalRocArrayQ;
1307 return GetCalRoc(sector, arr, force);
1308}
1309//_____________________________________________________________________
7fb602b1 1310AliTPCCalROC* AliTPCCalibCE::GetCalRocRMS(Int_t sector, Bool_t force)
75d8233f 1311{
1312 //
1313 // return pointer to signal width ROC Calibration
1314 // if force is true create a new histogram if it doesn't exist allready
1315 //
1316 TObjArray *arr = &fCalRocArrayRMS;
1317 return GetCalRoc(sector, arr, force);
1318}
1319//_____________________________________________________________________
1320AliTPCCalROC* AliTPCCalibCE::GetCalRocOutliers(Int_t sector, Bool_t force)
1321{
1322 //
1323 // return pointer to Outliers
1324 // if force is true create a new histogram if it doesn't exist allready
1325 //
1326 TObjArray *arr = &fCalRocArrayOutliers;
1327 return GetCalRoc(sector, arr, force);
1328}
1329//_____________________________________________________________________
1330TObjArray* AliTPCCalibCE::GetParamArray(Int_t sector, TObjArray* arr, Bool_t force)
1331{
1332 //
1333 // return pointer to TObjArray of fit parameters
1334 // if force is true create a new histogram if it doesn't exist allready
1335 //
1336 if ( !force || arr->UncheckedAt(sector) )
1337 return (TObjArray*)arr->UncheckedAt(sector);
1338
1339 // if we are forced and array doesn't yes exist create it
1340
1341 // new TObjArray for parameters
1342 TObjArray *newArr = new TObjArray;
1343 arr->AddAt(newArr,sector);
1344 return newArr;
1345}
1346//_____________________________________________________________________
1347TObjArray* AliTPCCalibCE::GetParamArrayPol1(Int_t sector, Bool_t force)
1348{
1349 //
1350 // return pointer to TObjArray of fit parameters from plane fit
1351 // if force is true create a new histogram if it doesn't exist allready
1352 //
1353 TObjArray *arr = &fParamArrayEventPol1;
1354 return GetParamArray(sector, arr, force);
1355}
1356//_____________________________________________________________________
1357TObjArray* AliTPCCalibCE::GetParamArrayPol2(Int_t sector, Bool_t force)
1358{
1359 //
1360 // return pointer to TObjArray of fit parameters from parabola fit
1361 // if force is true create a new histogram if it doesn't exist allready
1362 //
1363 TObjArray *arr = &fParamArrayEventPol2;
1364 return GetParamArray(sector, arr, force);
1365}
1366//_____________________________________________________________________
7fb602b1 1367void AliTPCCalibCE::ResetEvent()
75d8233f 1368{
1369 //
1370 // Reset global counters -- Should be called before each event is processed
1371 //
1372 fLastSector=-1;
1373 fCurrentSector=-1;
1374 fCurrentRow=-1;
1375 fCurrentChannel=-1;
1376
1377 ResetPad();
1378
1379 fPadTimesArrayEvent.Delete();
1380 fPadQArrayEvent.Delete();
1381 fPadRMSArrayEvent.Delete();
1382 fPadPedestalArrayEvent.Delete();
1383
7fb602b1 1384 for ( Int_t i=0; i<72; ++i ){
bf57d87d 1385 fVTime0Offset.GetMatrixArray()[i]=0;
1386 fVTime0OffsetCounter.GetMatrixArray()[i]=0;
1387 fVMeanQ.GetMatrixArray()[i]=0;
1388 fVMeanQCounter.GetMatrixArray()[i]=0;
75d8233f 1389 }
1390}
1391//_____________________________________________________________________
7fb602b1 1392void AliTPCCalibCE::ResetPad()
75d8233f 1393{
1394 //
1395 // Reset pad infos -- Should be called after a pad has been processed
1396 //
7fb602b1 1397 for (Int_t i=fFirstTimeBin; i<fLastTimeBin+1; ++i)
bf57d87d 1398 fPadSignal.GetMatrixArray()[i] = 0;
75d8233f 1399 fMaxTimeBin = -1;
1400 fMaxPadSignal = -1;
1401 fPadPedestal = -1;
1402 fPadNoise = -1;
1403}
1404//_____________________________________________________________________
7fb602b1 1405void AliTPCCalibCE::Merge(AliTPCCalibCE *ce)
1406{
1407 //
1408 // Merge ce to the current AliTPCCalibCE
1409 //
1410
1411 //merge histograms
1412 for (Int_t iSec=0; iSec<72; ++iSec){
1413 TH2S *hRefQmerge = ce->GetHistoQ(iSec);
1414 TH2S *hRefT0merge = ce->GetHistoT0(iSec);
1415 TH2S *hRefRMSmerge = ce->GetHistoRMS(iSec);
1416
1417
1418 if ( hRefQmerge ){
1419 TDirectory *dir = hRefQmerge->GetDirectory(); hRefQmerge->SetDirectory(0);
1420 TH2S *hRefQ = GetHistoQ(iSec);
1421 if ( hRefQ ) hRefQ->Add(hRefQmerge);
1422 else {
1423 TH2S *hist = new TH2S(*hRefQmerge);
1424 hist->SetDirectory(0);
1425 fHistoQArray.AddAt(hist, iSec);
1426 }
1427 hRefQmerge->SetDirectory(dir);
1428 }
1429 if ( hRefT0merge ){
1430 TDirectory *dir = hRefT0merge->GetDirectory(); hRefT0merge->SetDirectory(0);
1431 TH2S *hRefT0 = GetHistoT0(iSec);
1432 if ( hRefT0 ) hRefT0->Add(hRefT0merge);
1433 else {
1434 TH2S *hist = new TH2S(*hRefT0merge);
1435 hist->SetDirectory(0);
1436 fHistoT0Array.AddAt(hist, iSec);
1437 }
1438 hRefT0merge->SetDirectory(dir);
1439 }
1440 if ( hRefRMSmerge ){
1441 TDirectory *dir = hRefRMSmerge->GetDirectory(); hRefRMSmerge->SetDirectory(0);
1442 TH2S *hRefRMS = GetHistoRMS(iSec);
1443 if ( hRefRMS ) hRefRMS->Add(hRefRMSmerge);
1444 else {
1445 TH2S *hist = new TH2S(*hRefRMSmerge);
1446 hist->SetDirectory(0);
1447 fHistoRMSArray.AddAt(hist, iSec);
1448 }
1449 hRefRMSmerge->SetDirectory(dir);
1450 }
1451
1452 }
1453
1454 // merge time information
1455
1456
1457 Int_t nCEevents = ce->GetNeventsProcessed();
1458 for (Int_t iSec=0; iSec<72; ++iSec){
1459 TObjArray *arrPol1CE = ce->GetParamArrayPol1(iSec);
1460 TObjArray *arrPol2CE = ce->GetParamArrayPol2(iSec);
1461 TVectorF *vMeanTimeCE = ce->GetTMeanEvents(iSec);
1462 TVectorF *vMeanQCE = ce->GetQMeanEvents(iSec);
1463
1464 TObjArray *arrPol1 = 0x0;
1465 TObjArray *arrPol2 = 0x0;
1466 TVectorF *vMeanTime = 0x0;
1467 TVectorF *vMeanQ = 0x0;
1468
1469 //resize arrays
1470 if ( arrPol1CE && arrPol2CE ){
1471 arrPol1 = GetParamArrayPol1(iSec,kTRUE);
1472 arrPol2 = GetParamArrayPol2(iSec,kTRUE);
1473 arrPol1->Expand(fNevents+nCEevents);
1474 arrPol2->Expand(fNevents+nCEevents);
1475 }
1476 if ( vMeanTimeCE && vMeanQCE ){
1477 vMeanTime = GetTMeanEvents(iSec);
1478 vMeanQCE = GetQMeanEvents(iSec);
1479 vMeanTime->ResizeTo(fNevents+nCEevents);
1480 vMeanQ->ResizeTo(fNevents+nCEevents);
1481 }
1482
1483
1484 for (Int_t iEvent=0; iEvent<nCEevents; ++iEvent){
1485 if ( arrPol1CE && arrPol2CE ){
1486 TVectorD *paramPol1 = (TVectorD*)(arrPol1CE->UncheckedAt(iEvent));
1487 TVectorD *paramPol2 = (TVectorD*)(arrPol2CE->UncheckedAt(iEvent));
1488 if ( paramPol1 && paramPol2 ){
1489 GetParamArrayPol1(iSec,kTRUE)->AddAt(new TVectorD(*paramPol1), fNevents+iEvent);
1490 GetParamArrayPol2(iSec,kTRUE)->AddAt(new TVectorD(*paramPol2), fNevents+iEvent);
1491 }
1492 }
1493 if ( vMeanTimeCE && vMeanQCE ){
1494 vMeanTime->GetMatrixArray()[fNevents+iEvent]=vMeanTimeCE->GetMatrixArray()[iEvent];
1495 vMeanQ->GetMatrixArray()[fNevents+iEvent]=vMeanQCE->GetMatrixArray()[iEvent];
1496 }
1497 }
1498 }
1499
1500
1501
1502 TVectorD* eventTimes = ce->GetEventTimes();
1503 TVectorD* eventIds = ce->GetEventIds();
1504 fVEventTime.ResizeTo(fNevents+nCEevents);
1505 fVEventNumber.ResizeTo(fNevents+nCEevents);
1506
1507 for (Int_t iEvent=0; iEvent<nCEevents; ++iEvent){
1508 Double_t evTime = eventTimes->GetMatrixArray()[iEvent];
1509 Double_t evId = eventIds->GetMatrixArray()[iEvent];
1510 fVEventTime.GetMatrixArray()[fNevents+iEvent] = evTime;
1511 fVEventNumber.GetMatrixArray()[fNevents+iEvent] = evId;
1512 }
1513 fNevents+=nCEevents; //increase event counter
1514
1515}
1516//_____________________________________________________________________
1517TGraph *AliTPCCalibCE::MakeGraphTimeCE(Int_t sector, Int_t xVariable, Int_t fitType, Int_t fitParameter)
75d8233f 1518{
1519 //
7fb602b1 1520 // Make graph from fit parameters of pol1 fit, pol2 fit, mean arrival time or mean Q for ROC 'sector'
1521 // xVariable: 0-event time, 1-event id, 2-internal event counter
1522 // fitType: 0-pol1 fit, 1-pol2 fit, 2-mean time, 3-mean Q
1523 // fitParameter: fit parameter ( 0-2 for pol1 ([0]+[1]*x+[2]*y),
1524 // 0-5 for pol2 ([0]+[1]*x+[2]*y+[3]*x*x+[4]*y*y+[5]*x*y),
1525 // not used for mean time and mean Q )
1526 // for an example see class description at the beginning
75d8233f 1527 //
1528
1529 Double_t *x = new Double_t[fNevents];
1530 Double_t *y = new Double_t[fNevents];
1531
1532 TVectorD *xVar = 0x0;
1533 TObjArray *aType = 0x0;
1534 Int_t npoints=0;
1535
1536 // sanity checks
1537 if ( (sector<0) || (sector>71) ) return 0x0;
1538 if ( (xVariable<0) || (xVariable>2) ) return 0x0;
bf57d87d 1539 if ( (fitType<0) || (fitType>3) ) return 0x0;
75d8233f 1540 if ( fitType==0 ){
1541 if ( (fitParameter<0) || (fitParameter>2) ) return 0x0;
1542 aType = &fParamArrayEventPol1;
1543 if ( aType->At(sector)==0x0 ) return 0x0;
1544 }
1545 else if ( fitType==1 ){
1546 if ( (fitParameter<0) || (fitParameter>5) ) return 0x0;
1547 aType = &fParamArrayEventPol2;
1548 if ( aType->At(sector)==0x0 ) return 0x0;
1549 }
1550
1551
1552 if ( xVariable == 0 ) xVar = &fVEventTime;
1553 if ( xVariable == 1 ) xVar = &fVEventNumber;
1554 if ( xVariable == 2 ) {
1555 xVar = new TVectorD(fNevents);
7fb602b1 1556 for ( Int_t i=0;i<fNevents; ++i) (*xVar)[i]=i;
75d8233f 1557 }
1558
7fb602b1 1559 for (Int_t ievent =0; ievent<fNevents; ++ievent){
75d8233f 1560 if ( fitType<2 ){
1561 TObjArray *events = (TObjArray*)(aType->At(sector));
1562 if ( events->GetSize()<=ievent ) break;
1563 TVectorD *v = (TVectorD*)(events->At(ievent));
7fb602b1 1564 if ( (v!=0x0) && ((*xVar)[ievent]>0) ) { x[npoints]=(*xVar)[ievent]; y[npoints]=(*v)[fitParameter]; npoints++;}
75d8233f 1565 } else if (fitType == 2) {
7fb602b1 1566 Double_t xValue=(*xVar)[ievent];
1567 Double_t yValue=(*GetTMeanEvents(sector))[ievent];
1568 if ( yValue>0 && xValue>0 ) { x[npoints]=xValue; y[npoints]=yValue;npoints++;}
bf57d87d 1569 }else if (fitType == 3) {
7fb602b1 1570 Double_t xValue=(*xVar)[ievent];
1571 Double_t yValue=(*GetQMeanEvents(sector))[ievent];
1572 if ( yValue>0 && xValue>0 ) { x[npoints]=xValue; y[npoints]=yValue;npoints++;}
75d8233f 1573 }
1574 }
1575
1576 TGraph *gr = new TGraph(npoints);
1577 //sort xVariable increasing
1578 Int_t *sortIndex = new Int_t[npoints];
1579 TMath::Sort(npoints,x,sortIndex);
7fb602b1 1580 for (Int_t i=0;i<npoints;++i){
75d8233f 1581 gr->SetPoint(i,x[sortIndex[i]],y[sortIndex[i]]);
1582 }
1583
1584
1585 if ( xVariable == 2 ) delete xVar;
1586 delete x;
1587 delete y;
1588 delete sortIndex;
1589 return gr;
1590}
1591//_____________________________________________________________________
1592void AliTPCCalibCE::Analyse()
1593{
1594 //
1595 // Calculate calibration constants
1596 //
1597
1598 TVectorD paramQ(3);
1599 TVectorD paramT0(3);
1600 TVectorD paramRMS(3);
1601 TMatrixD dummy(3,3);
1602
7fb602b1 1603 for (Int_t iSec=0; iSec<72; ++iSec){
75d8233f 1604 TH2S *hT0 = GetHistoT0(iSec);
1605 if (!hT0 ) continue;
1606
1607 AliTPCCalROC *rocQ = GetCalRocQ (iSec,kTRUE);
1608 AliTPCCalROC *rocT0 = GetCalRocT0 (iSec,kTRUE);
1609 AliTPCCalROC *rocRMS = GetCalRocRMS(iSec,kTRUE);
1610 AliTPCCalROC *rocOut = GetCalRocOutliers(iSec,kTRUE);
1611
1612 TH2S *hQ = GetHistoQ(iSec);
1613 TH2S *hRMS = GetHistoRMS(iSec);
1614
1615 Short_t *array_hQ = hQ->GetArray();
1616 Short_t *array_hT0 = hT0->GetArray();
1617 Short_t *array_hRMS = hRMS->GetArray();
1618
1619 UInt_t nChannels = fROC->GetNChannels(iSec);
1620
1621 //debug
1622 Int_t row=0;
1623 Int_t pad=0;
1624 Int_t padc=0;
1625 //! debug
1626
7fb602b1 1627 for (UInt_t iChannel=0; iChannel<nChannels; ++iChannel){
75d8233f 1628
1629
1630 Float_t cogTime0 = -1000;
1631 Float_t cogQ = -1000;
1632 Float_t cogRMS = -1000;
1633 Float_t cogOut = 0;
1634
1635
1636 Int_t offsetQ = (fNbinsQ+2)*(iChannel+1)+1;
1637 Int_t offsetT0 = (fNbinsT0+2)*(iChannel+1)+1;
1638 Int_t offsetRMS = (fNbinsRMS+2)*(iChannel+1)+1;
1639
75d8233f 1640 cogQ = AliMathBase::GetCOG(array_hQ+offsetQ,fNbinsQ,fXminQ,fXmaxQ);
1641 cogTime0 = AliMathBase::GetCOG(array_hT0+offsetT0,fNbinsT0,fXminT0,fXmaxT0);
1642 cogRMS = AliMathBase::GetCOG(array_hRMS+offsetRMS,fNbinsRMS,fXminRMS,fXmaxRMS);
1643
1644
1645
1646 /*
7fb602b1 1647 //outlier specifications
75d8233f 1648 if ( (cogQ < ??) && (cogTime0 > ??) && (cogTime0<??) && ( cogRMS>??) ){
1649 cogOut = 1;
1650 cogTime0 = 0;
1651 cogQ = 0;
1652 cogRMS = 0;
1653 }
1654*/
1655 rocQ->SetValue(iChannel, cogQ*cogQ);
1656 rocT0->SetValue(iChannel, cogTime0);
1657 rocRMS->SetValue(iChannel, cogRMS);
1658 rocOut->SetValue(iChannel, cogOut);
1659
1660
1661 //debug
1662 if ( fDebugLevel > 0 ){
1663 if ( !fDebugStreamer ) {
1664 //debug stream
1665 TDirectory *backup = gDirectory;
1666 fDebugStreamer = new TTreeSRedirector("debugCalibCEAnalysis.root");
1667 if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer
1668 }
1669
1670 while ( iChannel > (fROC->GetRowIndexes(iSec)[row]+fROC->GetNPads(iSec,row)-1) ) row++;
1671 pad = iChannel-fROC->GetRowIndexes(iSec)[row];
1672 padc = pad-(fROC->GetNPads(iSec,row)/2);
1673
1674 (*fDebugStreamer) << "DataEnd" <<
1675 "Sector=" << iSec <<
1676 "Pad=" << pad <<
1677 "PadC=" << padc <<
1678 "Row=" << row <<
1679 "PadSec=" << iChannel <<
1680 "Q=" << cogQ <<
1681 "T0=" << cogTime0 <<
1682 "RMS=" << cogRMS <<
1683 "\n";
1684 }
1685 //! debug
1686
1687 }
1688
1689 }
7fb602b1 1690 if ( fDebugStreamer ) fDebugStreamer->GetFile()->Write();
75d8233f 1691// delete fDebugStreamer;
bf57d87d 1692// fDebugStreamer = 0x0;
75d8233f 1693}
1694//_____________________________________________________________________
1695void AliTPCCalibCE::DumpToFile(const Char_t *filename, const Char_t *dir, Bool_t append)
1696{
1697 //
1698 // Write class to file
1699 //
1700
1701 TString sDir(dir);
1702 TString option;
1703
1704 if ( append )
1705 option = "update";
1706 else
1707 option = "recreate";
1708
1709 TDirectory *backup = gDirectory;
1710 TFile f(filename,option.Data());
1711 f.cd();
1712 if ( !sDir.IsNull() ){
1713 f.mkdir(sDir.Data());
1714 f.cd(sDir);
1715 }
1716 this->Write();
1717 f.Close();
1718
1719 if ( backup ) backup->cd();
1720}