7e684c91 |
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 | |
20 | //------------------------------------------------------- |
21 | // Implementation of the TPC pulser calibration |
22 | // |
23 | // Origin: Jens Wiechula, Marian Ivanov J.Wiechula@gsi.de, Marian.Ivanov@cern.ch |
24 | // |
25 | // |
26 | //------------------------------------------------------- |
27 | |
28 | |
29 | /* $Id$ */ |
30 | |
31 | |
32 | |
33 | //Root includes |
34 | #include <TObjArray.h> |
35 | #include <TH1F.h> |
36 | #include <TH1D.h> |
37 | #include <TH2F.h> |
38 | #include <TH2S.h> |
39 | #include <TH1S.h> |
40 | #include <TString.h> |
41 | #include <TVectorF.h> |
42 | #include <TMath.h> |
43 | #include <TF1.h> |
44 | |
45 | |
46 | #include <TStopwatch.h> |
47 | #include <TCanvas.h> |
48 | #include <TROOT.h> |
49 | #include <TDirectory.h> |
50 | #include <TSystem.h> |
51 | #include <TFile.h> |
52 | |
53 | //AliRoot includes |
54 | #include "AliRawReader.h" |
55 | #include "AliRawReaderRoot.h" |
56 | #include "AliTPCRawStream.h" |
57 | #include "AliTPCCalROC.h" |
58 | #include "AliTPCCalPad.h" |
59 | #include "AliTPCROC.h" |
60 | #include "AliTPCParam.h" |
61 | #include "AliTPCCalibSignal.h" |
62 | #include "AliTPCcalibDB.h" |
63 | |
64 | #include "TTreeStream.h" |
65 | ClassImp(AliTPCCalibSignal) /*FOLD00*/ |
66 | |
67 | AliTPCCalibSignal::AliTPCCalibSignal() : /*FOLD00*/ |
68 | TObject(), |
69 | fFirstTimeBin(60), |
70 | fLastTimeBin(120), |
71 | fFirstTimeBinT0(-15), |
72 | fLastTimeBinT0(15), |
73 | fLastSector(-1), |
74 | fROC(AliTPCROC::Instance()), |
75 | fParam(new AliTPCParam), |
76 | fPedestalTPC(0), |
77 | fBpedestal(kFALSE), |
78 | fCalRocArrayT0(72), |
79 | fCalRocArrayQ(72), |
80 | fCalRocArrayRMS(72), |
81 | fCalRocArrayOutliers(72), |
82 | fHistoQArray(72), |
83 | fHistoT0Array(72), |
84 | fHistoRMSArray(72), |
85 | fPadTimesArrayEvent(72), |
86 | fPadQArrayEvent(72), |
87 | fPadRMSArrayEvent(72), |
88 | fPadPedestalArrayEvent(72), |
89 | fCurrentChannel(-1), |
90 | fCurrentSector(-1), |
91 | fCurrentRow(-1), |
92 | fMaxPadSignal(-1), |
93 | fMaxTimeBin(-1), |
94 | fPadSignal(1024), |
95 | fVTime0Offset1(72), |
96 | fVTime0Offset1Counter(72), |
97 | fEvent(-1), |
98 | fDebugStreamer(0x0), |
99 | fDebugLevel(0) |
100 | { |
101 | // |
102 | // AliTPCSignal default constructor |
103 | // |
104 | |
105 | //debug stream |
106 | TDirectory *backup = gDirectory; |
107 | fDebugStreamer = new TTreeSRedirector("deb2.root"); |
108 | if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer |
109 | |
110 | } |
111 | //_____________________________________________________________________ |
112 | AliTPCCalibSignal::AliTPCCalibSignal(const AliTPCCalibSignal &sig) : |
113 | TObject(sig), |
114 | fFirstTimeBin(sig.fFirstTimeBin), |
115 | fLastTimeBin(sig.fLastTimeBin), |
116 | fFirstTimeBinT0(sig.fFirstTimeBinT0), |
117 | fLastTimeBinT0(sig.fLastTimeBinT0), |
118 | fLastSector(-1), |
119 | fROC(AliTPCROC::Instance()), |
120 | fParam(new AliTPCParam), |
121 | fPedestalTPC(sig.fPedestalTPC), |
122 | fBpedestal(sig.fBpedestal), |
123 | fCalRocArrayT0(72), |
124 | fCalRocArrayQ(72), |
125 | fCalRocArrayRMS(72), |
126 | fCalRocArrayOutliers(72), |
127 | fHistoQArray(72), |
128 | fHistoT0Array(72), |
129 | fHistoRMSArray(72), |
130 | fPadTimesArrayEvent(72), |
131 | fPadQArrayEvent(72), |
132 | fPadRMSArrayEvent(72), |
133 | fPadPedestalArrayEvent(72), |
134 | fCurrentChannel(-1), |
135 | fCurrentSector(-1), |
136 | fCurrentRow(-1), |
137 | fMaxPadSignal(-1), |
138 | fMaxTimeBin(-1), |
139 | fPadSignal(1024), |
140 | fVTime0Offset1(72), |
141 | fVTime0Offset1Counter(72), |
142 | fEvent(-1), |
143 | fDebugStreamer(0x0), |
144 | fDebugLevel(sig.fDebugLevel) |
145 | { |
146 | // |
147 | // AliTPCSignal default constructor |
148 | // |
149 | |
150 | for (Int_t iSec = 0; iSec < 72; iSec++){ |
151 | const AliTPCCalROC *calQ = (AliTPCCalROC*)sig.fCalRocArrayQ.UncheckedAt(iSec); |
152 | const AliTPCCalROC *calT0 = (AliTPCCalROC*)sig.fCalRocArrayT0.UncheckedAt(iSec); |
153 | const AliTPCCalROC *calRMS = (AliTPCCalROC*)sig.fCalRocArrayRMS.UncheckedAt(iSec); |
154 | const AliTPCCalROC *calOut = (AliTPCCalROC*)sig.fCalRocArrayOutliers.UncheckedAt(iSec); |
155 | |
156 | const TH2S *hQ = (TH2S*)sig.fHistoQArray.UncheckedAt(iSec); |
157 | const TH2S *hT0 = (TH2S*)sig.fHistoT0Array.UncheckedAt(iSec); |
158 | const TH2S *hRMS = (TH2S*)sig.fHistoRMSArray.UncheckedAt(iSec); |
159 | |
160 | if ( calQ != 0x0 ) fCalRocArrayQ.AddAt(new AliTPCCalROC(*calQ), iSec); |
161 | if ( calT0 != 0x0 ) fCalRocArrayT0.AddAt(new AliTPCCalROC(*calT0), iSec); |
162 | if ( calRMS != 0x0 ) fCalRocArrayRMS.AddAt(new AliTPCCalROC(*calRMS), iSec); |
163 | if ( calOut != 0x0 ) fCalRocArrayOutliers.AddAt(new AliTPCCalROC(*calOut), iSec); |
164 | |
165 | if ( hQ != 0x0 ){ |
166 | TH2S *hNew = new TH2S(*hQ); |
167 | hNew->SetDirectory(0); |
168 | fHistoQArray.AddAt(hNew,iSec); |
169 | } |
170 | if ( hT0 != 0x0 ){ |
171 | TH2S *hNew = new TH2S(*hT0); |
172 | hNew->SetDirectory(0); |
173 | fHistoQArray.AddAt(hNew,iSec); |
174 | } |
175 | if ( hRMS != 0x0 ){ |
176 | TH2S *hNew = new TH2S(*hRMS); |
177 | hNew->SetDirectory(0); |
178 | fHistoQArray.AddAt(hNew,iSec); |
179 | } |
180 | } |
181 | |
182 | |
183 | //debug stream |
184 | TDirectory *backup = gDirectory; |
185 | fDebugStreamer = new TTreeSRedirector("deb2.root"); |
186 | if ( backup ) backup->cd(); //we don't want to be cd'd to the debug streamer |
187 | |
188 | } |
189 | //_____________________________________________________________________ |
190 | AliTPCCalibSignal& AliTPCCalibSignal::operator = (const AliTPCCalibSignal &source) |
191 | { |
192 | // |
193 | // assignment operator |
194 | // |
195 | if (&source == this) return *this; |
196 | new (this) AliTPCCalibSignal(source); |
197 | |
198 | return *this; |
199 | } |
200 | //_____________________________________________________________________ |
201 | AliTPCCalibSignal::~AliTPCCalibSignal() |
202 | { |
203 | // |
204 | // destructor |
205 | // |
206 | |
207 | fCalRocArrayT0.Delete(); |
208 | fCalRocArrayQ.Delete(); |
209 | fCalRocArrayRMS.Delete(); |
210 | |
211 | fHistoQArray.Delete(); |
212 | fHistoT0Array.Delete(); |
213 | fHistoRMSArray.Delete(); |
214 | |
215 | fPadTimesArrayEvent.Delete(); |
216 | fPadQArrayEvent.Delete(); |
217 | fPadRMSArrayEvent.Delete(); |
218 | fPadPedestalArrayEvent.Delete(); |
219 | |
220 | if ( fDebugStreamer) delete fDebugStreamer; |
221 | delete fROC; |
222 | delete fParam; |
223 | } |
224 | //_____________________________________________________________________ |
225 | Int_t AliTPCCalibSignal::Update(const Int_t icsector, /*FOLD00*/ |
226 | const Int_t icRow, |
227 | const Int_t icPad, |
228 | const Int_t icTimeBin, |
229 | const Float_t csignal) |
230 | { |
231 | // |
232 | // Signal filling methode on the fly pedestal and Time offset correction if necessary. |
233 | // no extra analysis necessary. Assumes knowledge of the signal shape! |
234 | // assumes that it is looped over consecutive time bins of one pad |
235 | // |
236 | if ( (icTimeBin>fLastTimeBin) || (icTimeBin<fFirstTimeBin) ) return 0; |
237 | |
238 | Int_t iChannel = fROC->GetRowIndexes(icsector)[icRow]+icPad; // global pad position in sector |
239 | |
240 | //init first pad and sector in this event |
241 | if ( fCurrentChannel == -1 ) { |
242 | fCurrentChannel = iChannel; |
243 | fCurrentSector = icsector; |
244 | fCurrentRow = icRow; |
245 | } |
246 | |
247 | //process last pad if we change to a new one |
248 | if ( iChannel != fCurrentChannel ){ |
249 | ProcessPad(); |
250 | fCurrentChannel = iChannel; |
251 | fCurrentSector = icsector; |
252 | fCurrentRow = icRow; |
253 | } |
254 | |
255 | if ( fDebugLevel > 6 ) |
256 | if ( icTimeBin == fLastTimeBin ) |
257 | printf("Filling sector: %d, channel: %d\n",icsector,iChannel); |
258 | |
259 | //fill signals for current pad |
260 | fPadSignal[icTimeBin]=csignal; |
261 | if ( csignal > fMaxPadSignal ){ |
262 | fMaxPadSignal = csignal; |
263 | fMaxTimeBin = icTimeBin; |
264 | } |
265 | return 0; |
266 | } |
267 | //_____________________________________________________________________ |
268 | void AliTPCCalibSignal::ProcessPad() /*FOLD00*/ |
269 | { |
270 | // |
271 | // Process data of current pad |
272 | // |
273 | if ( fDebugLevel > 4 ) |
274 | printf("process: sector-pad: %.2d-%.4d ... ", fCurrentSector, fCurrentChannel); |
275 | |
276 | Float_t pedestal = 0; |
277 | |
278 | if ( fBpedestal ){ |
279 | //!!!!!!! does not work like this |
280 | //use pedestal database |
281 | AliTPCCalROC *pedestalROC = 0x0; |
282 | |
283 | //only load new pedestals if the sector has changed |
284 | if ( fCurrentSector!=fLastSector ){ |
285 | pedestalROC = fPedestalTPC->GetCalROC(fCurrentSector); |
286 | fLastSector=fCurrentSector; |
287 | } |
288 | |
289 | pedestal = pedestalROC->GetValue(fCurrentChannel); |
290 | |
291 | } else { |
292 | if ( fDebugLevel > 4 ) |
293 | printf("pedestals ... "); |
294 | |
295 | //find pedestal for pad on the fly |
296 | //using a few timebins before the signal |
297 | Int_t pminus1 = 10, pminus2=5; |
298 | Float_t sumN=0; |
299 | |
300 | for (Int_t i=fMaxTimeBin-pminus1; i<fMaxTimeBin-pminus2+1; i++){ |
301 | if ( i>fFirstTimeBin && i<fLastTimeBin ){ |
302 | pedestal+=fPadSignal[i]; |
303 | sumN+=1.; |
304 | } |
305 | } |
306 | |
307 | if ( sumN>0 ) pedestal/=sumN; |
308 | if ( fDebugLevel > 4 ) |
309 | printf("%.2f ... ",pedestal); |
310 | } |
311 | |
312 | |
313 | |
314 | //!!!! check borders |
315 | //find signal mean and sigma |
316 | Int_t tminus = 2, tplus=7; |
317 | Double_t meanT=0, sigmaT=0, Qsum=0; |
318 | |
319 | if ( fDebugLevel > 4 ) |
320 | printf(" mean +- sigma (sum) ... "); |
321 | |
322 | for (Int_t i=fMaxTimeBin-tminus; i<fMaxTimeBin+tplus; i++){ |
323 | if ( i>fFirstTimeBin && i<fLastTimeBin ){ |
324 | Double_t val=fPadSignal[i]-pedestal; |
325 | meanT+=val*(i+.5); //+.5: center of the timebin |
326 | sigmaT+=val*(i+.5)*(i+.5); |
327 | Qsum+=val; |
328 | } |
329 | } |
330 | |
331 | |
332 | |
333 | //!!!! What to do if Qsum == 0??? |
334 | //!!!! Should there be some threshold for max - pedestal and/or Qsum??? |
335 | //!!!! What if Qsum < 0 |
336 | //!!!! only fill time0 offset if Qsum > 0??? |
337 | if ( Qsum > 0 ){ |
338 | meanT/=Qsum; |
339 | sigmaT/=Qsum; |
340 | sigmaT = TMath::Sqrt(TMath::Abs(meanT*meanT - sigmaT)); |
341 | |
342 | //fill Time0 offset data for this event |
343 | fVTime0Offset1[fCurrentSector]+=meanT; |
344 | fVTime0Offset1Counter[fCurrentSector]++; |
345 | } else { |
346 | Qsum=0; |
347 | meanT = fLastTimeBinT0+1; //put to overflow bin |
348 | sigmaT = fLastTimeBinT0-fFirstTimeBinT0; //put to overflow bin |
349 | } |
350 | |
351 | if ( fDebugLevel > 4 ) |
352 | printf("%.3f +- %.3f (%.3f) ... ",meanT,sigmaT,Qsum); |
353 | |
354 | |
355 | if ( fDebugLevel > 4 ) |
356 | printf("filling ... "); |
357 | |
358 | |
359 | //Fill Event T0 counter |
360 | (*GetPadTimesEvent(fCurrentSector,kTRUE))[fCurrentChannel] = meanT; |
361 | |
362 | |
363 | //Normalise Q to pad area of irocs |
364 | Float_t norm = fParam->GetPadPitchWidth(0)*fParam->GetPadPitchLength(0,0)/( |
365 | fParam->GetPadPitchWidth(fCurrentSector)*fParam->GetPadPitchLength(fCurrentSector,fCurrentRow)); |
366 | |
367 | // if (fCurrentChannel == 0) printf("sec, norm: %d, %f\n", fCurrentSector, norm); |
368 | |
369 | //Fill Q histogram |
370 | GetHistoQ(fCurrentSector,kTRUE)->Fill(fCurrentChannel, TMath::Sqrt(Qsum*norm)); |
371 | |
372 | //Fill RMS histogram |
373 | GetHistoRMS(fCurrentSector,kTRUE)->Fill(fCurrentChannel, sigmaT); |
374 | |
375 | |
376 | //Fill debugging info |
377 | if ( fDebugLevel>0 ){ |
378 | (*GetPadPedestalEvent(fCurrentSector,kTRUE))[fCurrentChannel]=pedestal; |
379 | (*GetPadRMSEvent(fCurrentSector,kTRUE))[fCurrentChannel]=sigmaT; |
380 | (*GetPadQEvent(fCurrentSector,kTRUE))[fCurrentChannel]=Qsum; |
381 | } |
382 | |
383 | if ( fDebugLevel > 4 ) |
384 | printf("reset pad ..."); |
385 | |
386 | ResetPad(); |
387 | |
388 | if ( fDebugLevel > 4 ) |
389 | printf("end\n"); |
390 | } |
391 | //_____________________________________________________________________ |
392 | void AliTPCCalibSignal::EndEvent() /*FOLD00*/ |
393 | { |
394 | // |
395 | // Process data of current pad |
396 | // |
397 | printf("end event\n"); |
398 | for ( Int_t iSec = 0; iSec<72; iSec++ ){ |
399 | TVectorF *vTimes = GetPadTimesEvent(iSec); |
400 | if ( !vTimes ) continue; |
401 | |
402 | for ( UInt_t iChannel=0; iChannel<fROC->GetNChannels(iSec); iChannel++ ){ |
403 | Float_t Time0 = fVTime0Offset1[iSec]/fVTime0Offset1Counter[iSec]; |
404 | Float_t Time = (*vTimes)[iChannel]; |
405 | |
406 | GetHistoT0(iSec,kTRUE)->Fill(iChannel,Time-Time0); |
407 | |
408 | |
409 | //Debug start |
410 | if ( fDebugLevel>0 ){ |
411 | Int_t row=0; |
412 | Int_t pad=0; |
413 | Int_t padc=0; |
414 | |
415 | Float_t Q = (*GetPadQEvent(iSec))[iChannel]; |
416 | Float_t RMS = (*GetPadRMSEvent(iSec))[iChannel]; |
417 | |
418 | UInt_t channel=iChannel; |
419 | Int_t sector=iSec; |
420 | |
421 | while ( channel > (fROC->GetRowIndexes(sector)[row]+fROC->GetNPads(sector,row)-1) ) row++; |
422 | pad = channel-fROC->GetRowIndexes(sector)[row]; |
423 | padc = pad-(fROC->GetNPads(sector,row)/2); |
424 | |
425 | TH1F *h1 = new TH1F(Form("hSignalD%d.%d.%d",sector,row,pad), |
426 | Form("hSignalD%d.%d.%d",sector,row,pad), |
427 | fLastTimeBin-fFirstTimeBin, |
428 | fFirstTimeBin,fLastTimeBin); |
429 | h1->SetDirectory(0); |
430 | |
431 | for (Int_t i=fFirstTimeBin; i<fLastTimeBin+1; i++) |
432 | h1->Fill(i,fPadSignal(i)); |
433 | |
434 | (*fDebugStreamer) << "DataPad" << |
435 | "Event=" << fEvent << |
436 | "Sector="<< sector << |
437 | "Row=" << row<< |
438 | "Pad=" << pad << |
439 | "PadC=" << padc << |
440 | "PadSec="<< channel << |
441 | "Time0=" << Time0 << |
442 | "Time=" << Time << |
443 | "RMS=" << RMS << |
444 | "Sum=" << Q << |
445 | "hist.=" << h1 << |
446 | "\n"; |
447 | |
448 | delete h1; |
449 | } |
450 | //Debug end |
451 | |
452 | } |
453 | } |
454 | |
455 | } |
456 | //_____________________________________________________________________ |
457 | Bool_t AliTPCCalibSignal::ProcessEvent(AliRawReader *rawReader) /*FOLD00*/ |
458 | { |
459 | // |
460 | // |
461 | // |
462 | |
463 | |
464 | AliTPCRawStream input(rawReader); |
465 | |
466 | rawReader->Select("TPC"); |
467 | |
468 | input.SetOldRCUFormat(1); |
469 | printf("start event processing\n"); |
470 | |
471 | ResetEvent(); |
472 | |
473 | Bool_t withInput = kFALSE; |
474 | |
475 | while (input.Next()) { |
476 | |
477 | Int_t isector = input.GetSector(); // current sector |
478 | Int_t iRow = input.GetRow(); // current row |
479 | Int_t iPad = input.GetPad(); // current pad |
480 | Int_t iTimeBin = input.GetTime(); // current time bin |
481 | Float_t signal = input.GetSignal(); // current ADC signal |
482 | |
483 | Update(isector,iRow,iPad,iTimeBin,signal); |
484 | withInput = kTRUE; |
485 | } |
486 | |
487 | if (withInput){ |
488 | ProcessPad(); |
489 | EndEvent(); |
490 | } |
491 | |
492 | printf("end event processing\n"); |
493 | if ( fDebugLevel>0 ) |
494 | fDebugStreamer->GetFile()->Write(); |
495 | return withInput; |
496 | } |
497 | //_____________________________________________________________________ |
498 | TH2S* AliTPCCalibSignal::GetHisto(Int_t sector, TObjArray *arr, /*FOLD00*/ |
499 | Int_t nbinsY, Float_t ymin, Float_t ymax, |
500 | Char_t *type, Bool_t force) |
501 | { |
502 | // |
503 | // return pointer to Q histogram |
504 | // if force is true create a new histogram if it doesn't exist allready |
505 | // |
506 | if ( !force || arr->UncheckedAt(sector) ) |
507 | return (TH2S*)arr->UncheckedAt(sector); |
508 | |
509 | // if we are forced and histogram doesn't yes exist create it |
510 | Char_t name[255], title[255]; |
511 | |
512 | sprintf(name,"hCalib%s%.2d",type,sector); |
513 | sprintf(title,"%s calibration histogram sector %.2d",type,sector); |
514 | |
515 | // new histogram with Q calib information. One value for each pad! |
516 | TH2S* hist = new TH2S(name,title, |
517 | fROC->GetNChannels(sector),0,fROC->GetNChannels(sector), |
518 | nbinsY, ymin, ymax); |
519 | hist->SetDirectory(0); |
520 | arr->AddAt(hist,sector); |
521 | return hist; |
522 | } |
523 | //_____________________________________________________________________ |
524 | TH2S* AliTPCCalibSignal::GetHistoT0(Int_t sector, Bool_t force) /*FOLD00*/ |
525 | { |
526 | // |
527 | // return pointer to T0 histogram |
528 | // if force is true create a new histogram if it doesn't exist allready |
529 | // |
530 | TObjArray *arr = &fHistoT0Array; |
531 | return GetHisto(sector, arr, 200, -2, 2, "T0", force); |
532 | } |
533 | //_____________________________________________________________________ |
534 | TH2S* AliTPCCalibSignal::GetHistoQ(Int_t sector, Bool_t force) /*FOLD00*/ |
535 | { |
536 | // |
537 | // return pointer to Q histogram |
538 | // if force is true create a new histogram if it doesn't exist allready |
539 | // |
540 | TObjArray *arr = &fHistoQArray; |
541 | return GetHisto(sector, arr, 150, 24, 55, "Q", force); |
542 | } |
543 | //_____________________________________________________________________ |
544 | TH2S* AliTPCCalibSignal::GetHistoRMS(Int_t sector, Bool_t force) /*FOLD00*/ |
545 | { |
546 | // |
547 | // return pointer to Q histogram |
548 | // if force is true create a new histogram if it doesn't exist allready |
549 | // |
550 | TObjArray *arr = &fHistoRMSArray; |
551 | return GetHisto(sector, arr, 100, 0, 5, "RMS", force); |
552 | } |
553 | //_____________________________________________________________________ |
554 | TVectorF* AliTPCCalibSignal::GetPadInfoEvent(Int_t sector, TObjArray *arr, Bool_t force) /*FOLD00*/ |
555 | { |
556 | // |
557 | // return pointer to Pad Info from 'arr' for the current event and sector |
558 | // if force is true create it if it doesn't exist allready |
559 | // |
560 | if ( !force || arr->UncheckedAt(sector) ) |
561 | return (TVectorF*)arr->UncheckedAt(sector); |
562 | |
563 | TVectorF *vect = new TVectorF(fROC->GetNChannels(sector)); |
564 | arr->AddAt(vect,sector); |
565 | return vect; |
566 | } |
567 | //_____________________________________________________________________ |
568 | TVectorF* AliTPCCalibSignal::GetPadTimesEvent(Int_t sector, Bool_t force) /*FOLD00*/ |
569 | { |
570 | // |
571 | // return pointer to Pad Times Array for the current event and sector |
572 | // if force is true create it if it doesn't exist allready |
573 | // |
574 | TObjArray *arr = &fPadTimesArrayEvent; |
575 | return GetPadInfoEvent(sector,arr,force); |
576 | } |
577 | //_____________________________________________________________________ |
578 | TVectorF* AliTPCCalibSignal::GetPadQEvent(Int_t sector, Bool_t force) /*FOLD00*/ |
579 | { |
580 | // |
581 | // return pointer to Pad Q Array for the current event and sector |
582 | // if force is true create it if it doesn't exist allready |
583 | // for debugging purposes only |
584 | // |
585 | |
586 | TObjArray *arr = &fPadQArrayEvent; |
587 | return GetPadInfoEvent(sector,arr,force); |
588 | } |
589 | //_____________________________________________________________________ |
590 | TVectorF* AliTPCCalibSignal::GetPadRMSEvent(Int_t sector, Bool_t force) /*FOLD00*/ |
591 | { |
592 | // |
593 | // return pointer to Pad RMS Array for the current event and sector |
594 | // if force is true create it if it doesn't exist allready |
595 | // for debugging purposes only |
596 | // |
597 | TObjArray *arr = &fPadRMSArrayEvent; |
598 | return GetPadInfoEvent(sector,arr,force); |
599 | } |
600 | //_____________________________________________________________________ |
601 | TVectorF* AliTPCCalibSignal::GetPadPedestalEvent(Int_t sector, Bool_t force) /*FOLD00*/ |
602 | { |
603 | // |
604 | // return pointer to Pad RMS Array for the current event and sector |
605 | // if force is true create it if it doesn't exist allready |
606 | // for debugging purposes only |
607 | // |
608 | TObjArray *arr = &fPadPedestalArrayEvent; |
609 | return GetPadInfoEvent(sector,arr,force); |
610 | } |
611 | //_____________________________________________________________________ |
612 | AliTPCCalROC* AliTPCCalibSignal::GetCalRoc(Int_t sector, TObjArray* arr, Bool_t force) /*FOLD00*/ |
613 | { |
614 | // |
615 | // return pointer to ROC Calibration |
616 | // if force is true create a new histogram if it doesn't exist allready |
617 | // |
618 | if ( !force || arr->UncheckedAt(sector) ) |
619 | return (AliTPCCalROC*)arr->UncheckedAt(sector); |
620 | |
621 | // if we are forced and histogram doesn't yes exist create it |
622 | |
623 | // new AliTPCCalROC for T0 information. One value for each pad! |
624 | AliTPCCalROC *croc = new AliTPCCalROC(sector); |
625 | //init values |
626 | for ( UInt_t iChannel = 0; iChannel<croc->GetNchannels(); iChannel++){ |
627 | croc->SetValue(iChannel, 0); |
628 | } |
629 | arr->AddAt(croc,sector); |
630 | return croc; |
631 | } |
632 | //_____________________________________________________________________ |
633 | AliTPCCalROC* AliTPCCalibSignal::GetCalRocT0(Int_t sector, Bool_t force) /*FOLD00*/ |
634 | { |
635 | // |
636 | // return pointer to Carge ROC Calibration |
637 | // if force is true create a new histogram if it doesn't exist allready |
638 | // |
639 | TObjArray *arr = &fCalRocArrayT0; |
640 | return GetCalRoc(sector, arr, force); |
641 | } |
642 | //_____________________________________________________________________ |
643 | AliTPCCalROC* AliTPCCalibSignal::GetCalRocQ(Int_t sector, Bool_t force) /*FOLD00*/ |
644 | { |
645 | // |
646 | // return pointer to T0 ROC Calibration |
647 | // if force is true create a new histogram if it doesn't exist allready |
648 | // |
649 | TObjArray *arr = &fCalRocArrayQ; |
650 | return GetCalRoc(sector, arr, force); |
651 | } |
652 | //_____________________________________________________________________ |
653 | AliTPCCalROC* AliTPCCalibSignal::GetCalRocRMS(Int_t sector, Bool_t force) /*FOLD00*/ |
654 | { |
655 | // |
656 | // return pointer to signal width ROC Calibration |
657 | // if force is true create a new histogram if it doesn't exist allready |
658 | // |
659 | TObjArray *arr = &fCalRocArrayRMS; |
660 | return GetCalRoc(sector, arr, force); |
661 | } |
662 | //_____________________________________________________________________ |
663 | AliTPCCalROC* AliTPCCalibSignal::GetCalRocOutliers(Int_t sector, Bool_t force) |
664 | { |
665 | // |
666 | // return pointer to Outliers |
667 | // if force is true create a new histogram if it doesn't exist allready |
668 | // |
669 | TObjArray *arr = &fCalRocArrayOutliers; |
670 | return GetCalRoc(sector, arr, force); |
671 | } |
672 | //_____________________________________________________________________ |
673 | void AliTPCCalibSignal::ResetEvent() /*FOLD00*/ |
674 | { |
675 | // |
676 | // Reset global counters -- Should be called before each event is processed |
677 | // |
678 | fLastSector=-1; |
679 | fCurrentSector=-1; |
680 | fCurrentRow=-1; |
681 | fCurrentChannel=-1; |
682 | |
683 | ResetPad(); |
684 | |
685 | fPadTimesArrayEvent.Delete(); |
686 | fPadQArrayEvent.Delete(); |
687 | fPadRMSArrayEvent.Delete(); |
688 | fPadPedestalArrayEvent.Delete(); |
689 | |
690 | for ( Int_t i=0; i<72; i++ ){ |
691 | fVTime0Offset1[i]=0; |
692 | fVTime0Offset1Counter[i]=0; |
693 | } |
694 | } |
695 | //_____________________________________________________________________ |
696 | void AliTPCCalibSignal::ResetPad() /*FOLD00*/ |
697 | { |
698 | // |
699 | // Reset pad infos -- Should be called after a pad has been processed |
700 | // |
701 | for (Int_t i=fFirstTimeBin; i<fLastTimeBin+1; i++) |
702 | fPadSignal[i] = 0; |
703 | fMaxTimeBin = -1; |
704 | fMaxPadSignal = -1; |
705 | } |
706 | //_____________________________________________________________________ |
707 | void AliTPCCalibSignal::Analyse() /*FOLD00*/ |
708 | { |
709 | // |
710 | // Calculate calibration constants |
711 | // |
712 | |
713 | |
714 | for (Int_t iSec=0; iSec<72; iSec++){ |
715 | TH2S *hT0 = GetHistoT0(iSec); |
716 | if (!hT0 ) continue; |
717 | |
718 | AliTPCCalROC *rocQ = GetCalRocQ (iSec,kTRUE); |
719 | AliTPCCalROC *rocT0 = GetCalRocT0 (iSec,kTRUE); |
720 | AliTPCCalROC *rocRMS = GetCalRocRMS(iSec,kTRUE); |
721 | AliTPCCalROC *rocOut = GetCalRocOutliers(iSec,kTRUE); |
722 | |
723 | TH2S *hQ = GetHistoQ(iSec); |
724 | TH2S *hRMS = GetHistoRMS(iSec); |
725 | |
726 | //debug |
727 | Int_t row=0; |
728 | Int_t pad=0; |
729 | Int_t padc=0; |
730 | //! debug |
731 | |
732 | for (UInt_t iChannel=0; iChannel<fROC->GetNChannels(iSec); iChannel++){ |
733 | |
734 | |
735 | Float_t cogTime0 = -1000; |
736 | Float_t cogQ = -1000; |
737 | Float_t cogRMS = -1000; |
738 | Float_t cogOut = 0; |
739 | |
740 | hQ->SetAxisRange(iChannel,iChannel); |
741 | hT0->SetAxisRange(iChannel,iChannel); |
742 | hRMS->SetAxisRange(iChannel,iChannel); |
743 | |
744 | cogTime0 = hT0->GetMean(2); |
745 | cogQ = hQ->GetMean(2); |
746 | cogRMS = hRMS->GetMean(2); |
747 | /* |
748 | if ( (cogQ < ??) && (cogTime0 > ??) && (cogTime0<??) && ( cogRMS>??) ){ |
749 | cogOut = 1; |
750 | cogTime0 = 0; |
751 | cogQ = 0; |
752 | cogRMS = 0; |
753 | } |
754 | */ |
755 | rocQ->SetValue(iChannel, cogQ*cogQ); |
756 | rocT0->SetValue(iChannel, cogTime0); |
757 | rocRMS->SetValue(iChannel, cogRMS); |
758 | rocOut->SetValue(iChannel, cogOut); |
759 | |
760 | |
761 | //debug |
762 | if ( fDebugLevel > 0 ){ |
763 | while ( iChannel > (fROC->GetRowIndexes(iSec)[row]+fROC->GetNPads(iSec,row)-1) ) row++; |
764 | pad = iChannel-fROC->GetRowIndexes(iSec)[row]; |
765 | padc = pad-(fROC->GetNPads(iSec,row)/2); |
766 | |
767 | (*fDebugStreamer) << "DataEnd" << |
768 | "Sector=" << iSec << |
769 | "Pad=" << pad << |
770 | "PadC=" << padc << |
771 | "Row=" << row << |
772 | "PadSec=" << iChannel << |
773 | "Q=" << cogQ << |
774 | "T0=" << cogTime0 << |
775 | "RMS=" << cogRMS << |
776 | "\n"; |
777 | } |
778 | //! debug |
779 | |
780 | } |
781 | |
782 | } |
783 | delete fDebugStreamer; |
784 | fDebugStreamer = 0x0; |
785 | } |
786 | //_____________________________________________________________________ |
787 | void AliTPCCalibSignal::DumpToFile(const Char_t *filename, const Char_t *dir, Bool_t append) |
788 | { |
789 | // |
790 | // Write class to file |
791 | // |
792 | |
793 | TDirectory *backup = gDirectory; |
794 | TString sDir(dir); |
795 | TString option; |
796 | |
797 | if ( append ) |
798 | option = "update"; |
799 | else |
800 | option = "recreate"; |
801 | |
802 | TFile f(filename,option.Data()); |
803 | if ( !sDir.IsNull() ){ |
804 | f.mkdir(sDir.Data()); |
805 | f.cd(sDir); |
806 | } |
807 | gDirectory->WriteTObject(this); |
808 | f.Close(); |
809 | |
810 | if ( backup ) backup->cd(); |
811 | |
812 | } |