Introducing event specie in QA (Yves)
[u/mrichter/AliRoot.git] / TPC / AliTPCdataQA.cxx
CommitLineData
0ffacf98 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/* $Id$ */
18
266f8637 19/*
20 February 2008
21
22 The code has been heavily modified so that now the RAW data is
23 "expanded" for each sector and stored in a big signal array. Then a
24 simple version of the code in AliTPCclustererMI is used to identify
25 the local maxima and these are then used for QA. This gives a better
26 estimate of the charge (both max and total) and also limits the
27 effect of noise.
28
29 Implementation:
30
31 In Update the RAW signals >= 3 ADC channels are stored in the arrays.
32
33 There are 3 arrays:
34 Float_t** fAllBins 2d array [row][bin(pad, time)] ADC signal
35 Int_t** fAllSigBins 2d array [row][signal#] bin(with signal)
36 Int_t* fAllNSigBins; 1d array [row] Nsignals
37
38 This is done sector by sector.
39
40 When data from a new sector is encountered, the method
41 FindLocalMaxima is called on the data from the previous sector, and
42 the calibration/data objects are updated with the "cluster"
43 info. Finally the arrays are cleared.
44
45 The requirements for a local maxima is:
46 Charge in bin is >= 5 ADC channels.
47 Charge in bin is larger than all the 8 neighboring bins.
48 At least one of the two pad neighbors has a signal.
49 At least one of the two time neighbors has a signal.
50
51 Before accessing the data it is expected that the Analyse method is
52 called. This normalizes some of the data objects to per event or per
53 cluster.
54 If more data is passed to the class after Analyse has been called
55 the normalization is reversed and Analyse has to be called again.
56*/
57
0ffacf98 58
f11b3071 59// stl includes
60#include <iostream>
61
62using namespace std;
63
0ffacf98 64//Root includes
65#include <TH1F.h>
66#include <TH2F.h>
67#include <TString.h>
68#include <TMath.h>
69#include <TF1.h>
70#include <TRandom.h>
71#include <TDirectory.h>
72#include <TFile.h>
266f8637 73#include <TError.h>
ac940b58 74#include <TMap.h>
0ffacf98 75//AliRoot includes
76#include "AliRawReader.h"
77#include "AliRawReaderRoot.h"
78#include "AliRawReaderDate.h"
79#include "AliTPCRawStream.h"
80#include "AliTPCCalROC.h"
81#include "AliTPCROC.h"
82#include "AliMathBase.h"
83#include "TTreeStream.h"
84#include "AliTPCRawStreamFast.h"
85
86//date
87#include "event.h"
88#include "AliTPCCalPad.h"
258cd111 89#include "AliTPCPreprocessorOnline.h"
0ffacf98 90
91//header file
92#include "AliTPCdataQA.h"
93
0ffacf98 94ClassImp(AliTPCdataQA)
95
336156cc 96AliTPCdataQA::AliTPCdataQA() : /*FOLD00*/
0ffacf98 97 fFirstTimeBin(60),
98 fLastTimeBin(1000),
99 fAdcMin(1),
100 fAdcMax(100),
0ffacf98 101 fMapping(NULL),
f11b3071 102 fPedestal(0),
103 fNoise(0),
266f8637 104 fNLocalMaxima(0),
0ffacf98 105 fMaxCharge(0),
f11b3071 106 fMeanCharge(0),
107 fNoThreshold(0),
266f8637 108 fNTimeBins(0),
109 fNPads(0),
110 fTimePosition(0),
c94a79e1 111 fOverThreshold10(0),
112 fOverThreshold20(0),
113 fOverThreshold30(0),
266f8637 114 fEventCounter(0),
115 fIsAnalysed(kFALSE),
116 fAllBins(0),
117 fAllSigBins(0),
118 fAllNSigBins(0),
119 fRowsMax(0),
120 fPadsMax(0),
121 fTimeBinsMax(0)
0ffacf98 122{
123 //
124 // default constructor
125 //
126}
127
57acd2d2 128//_____________________________________________________________________
129AliTPCdataQA::AliTPCdataQA(AliRecoParam::EventSpecie_t es) :
130fFirstTimeBin(60),
131fLastTimeBin(1000),
132fAdcMin(1),
133fAdcMax(100),
134fMapping(NULL),
135fPedestal(0),
136fNoise(0),
137fNLocalMaxima(0),
138fMaxCharge(0),
139fMeanCharge(0),
140fNoThreshold(0),
141fNTimeBins(0),
142fNPads(0),
143fTimePosition(0),
144fOverThreshold10(0),
145fOverThreshold20(0),
146fOverThreshold30(0),
147fEventCounter(0),
148fIsAnalysed(kFALSE),
149fAllBins(0),
150fAllSigBins(0),
151fAllNSigBins(0),
152fRowsMax(0),
153fPadsMax(0),
154fTimeBinsMax(0)
155{
156// ctor creating the histogram
157 char * name = Form("TPCRAW_%s", AliRecoParam::GetEventSpecieName(es)) ;
158 TH1F(name, name,100,0,100) ;
159}
0ffacf98 160
161//_____________________________________________________________________
162AliTPCdataQA::AliTPCdataQA(const AliTPCdataQA &ped) : /*FOLD00*/
336156cc 163 TH1F(ped),
0ffacf98 164 fFirstTimeBin(ped.GetFirstTimeBin()),
165 fLastTimeBin(ped.GetLastTimeBin()),
166 fAdcMin(ped.GetAdcMin()),
167 fAdcMax(ped.GetAdcMax()),
266f8637 168 fMapping(NULL),
169 fPedestal(0),
170 fNoise(0),
171 fNLocalMaxima(0),
172 fMaxCharge(0),
173 fMeanCharge(0),
174 fNoThreshold(0),
266f8637 175 fNTimeBins(0),
176 fNPads(0),
177 fTimePosition(0),
c94a79e1 178 fOverThreshold10(0),
179 fOverThreshold20(0),
180 fOverThreshold30(0),
266f8637 181 fEventCounter(ped.GetEventCounter()),
182 fIsAnalysed(ped.GetIsAnalysed()),
183 fAllBins(0),
184 fAllSigBins(0),
185 fAllNSigBins(0),
186 fRowsMax(0),
187 fPadsMax(0),
188 fTimeBinsMax(0)
0ffacf98 189{
190 //
191 // copy constructor
192 //
266f8637 193 if(ped.GetNLocalMaxima())
194 fNLocalMaxima = new AliTPCCalPad(*ped.GetNLocalMaxima());
195 if(ped.GetMaxCharge())
196 fMaxCharge = new AliTPCCalPad(*ped.GetMaxCharge());
197 if(ped.GetMeanCharge())
198 fMeanCharge = new AliTPCCalPad(*ped.GetMeanCharge());
199 if(ped.GetNoThreshold())
200 fNoThreshold = new AliTPCCalPad(*ped.GetNoThreshold());
201 if(ped.GetNTimeBins())
202 fNTimeBins = new AliTPCCalPad(*ped.GetNTimeBins());
203 if(ped.GetNPads())
204 fNPads = new AliTPCCalPad(*ped.GetNPads());
205 if(ped.GetTimePosition())
206 fTimePosition = new AliTPCCalPad(*ped.GetTimePosition());
207 if(ped.GetOverThreshold10())
208 fOverThreshold10 = new AliTPCCalPad(*ped.GetOverThreshold10());
209 if(ped.GetOverThreshold20())
210 fOverThreshold20 = new AliTPCCalPad(*ped.GetOverThreshold20());
211 if(ped.GetOverThreshold30())
212 fOverThreshold30 = new AliTPCCalPad(*ped.GetOverThreshold30());
0ffacf98 213}
214
ac940b58 215//_____________________________________________________________________
8ba97cc8 216AliTPCdataQA::AliTPCdataQA(const TMap *config) : /*FOLD00*/
ac940b58 217 TH1F("TPCRAW","TPCRAW",100,0,100),
218 fFirstTimeBin(60),
219 fLastTimeBin(1000),
220 fAdcMin(1),
221 fAdcMax(100),
222 fMapping(NULL),
223 fPedestal(0),
224 fNoise(0),
225 fNLocalMaxima(0),
226 fMaxCharge(0),
227 fMeanCharge(0),
228 fNoThreshold(0),
229 fNTimeBins(0),
230 fNPads(0),
231 fTimePosition(0),
232 fOverThreshold10(0),
233 fOverThreshold20(0),
234 fOverThreshold30(0),
235 fEventCounter(0),
236 fIsAnalysed(kFALSE),
237 fAllBins(0),
238 fAllSigBins(0),
239 fAllNSigBins(0),
240 fRowsMax(0),
241 fPadsMax(0),
242 fTimeBinsMax(0)
243{
244 //
245 // default constructor
246 //
247 if (config->GetValue("FirstTimeBin")) fFirstTimeBin = ((TObjString*)config->GetValue("FirstTimeBin"))->GetString().Atoi();
248 if (config->GetValue("LastTimeBin")) fLastTimeBin = ((TObjString*)config->GetValue("LastTimeBin"))->GetString().Atoi();
249 if (config->GetValue("AdcMin")) fAdcMin = ((TObjString*)config->GetValue("AdcMin"))->GetString().Atoi();
250 if (config->GetValue("AdcMax")) fAdcMax = ((TObjString*)config->GetValue("AdcMax"))->GetString().Atoi();
251}
0ffacf98 252
253//_____________________________________________________________________
254AliTPCdataQA& AliTPCdataQA::operator = (const AliTPCdataQA &source)
255{
256 //
257 // assignment operator
258 //
259 if (&source == this) return *this;
260 new (this) AliTPCdataQA(source);
261
262 return *this;
263}
264
265
266//_____________________________________________________________________
267AliTPCdataQA::~AliTPCdataQA() /*FOLD00*/
268{
269 //
270 // destructor
271 //
272
273 // do not delete fMapping, because we do not own it.
266f8637 274 // do not delete fMapping, because we do not own it.
275 // do not delete fNoise and fPedestal, because we do not own them.
276
277 delete fNLocalMaxima;
278 delete fMaxCharge;
279 delete fMeanCharge;
280 delete fNoThreshold;
281 delete fNTimeBins;
282 delete fNPads;
283 delete fTimePosition;
284 delete fOverThreshold10;
285 delete fOverThreshold20;
286 delete fOverThreshold30;
287
288 for (Int_t iRow = 0; iRow < fRowsMax; iRow++) {
289 delete [] fAllBins[iRow];
290 delete [] fAllSigBins[iRow];
291 }
292 delete [] fAllBins;
293 delete [] fAllSigBins;
294 delete [] fAllNSigBins;
0ffacf98 295}
296
0ffacf98 297//_____________________________________________________________________
298Bool_t AliTPCdataQA::ProcessEventFast(AliTPCRawStreamFast *rawStreamFast)
299{
300 //
301 // Event Processing loop - AliTPCRawStream
302 //
303 Bool_t withInput = kFALSE;
266f8637 304 Int_t nSignals = 0;
305 Int_t lastSector = -1;
0ffacf98 306
307 while ( rawStreamFast->NextDDL() ){
308 while ( rawStreamFast->NextChannel() ){
266f8637 309
310 Int_t iSector = rawStreamFast->GetSector(); // current sector
311 Int_t iRow = rawStreamFast->GetRow(); // current row
312 Int_t iPad = rawStreamFast->GetPad(); // current pad
313 // Call local maxima finder if the data is in a new sector
314 if(iSector != lastSector) {
315
316 if(nSignals>0)
317 FindLocalMaxima(lastSector);
318
319 CleanArrays();
320 lastSector = iSector;
321 nSignals = 0;
322 }
323
324 while ( rawStreamFast->NextBunch() ){
325 Int_t startTbin = (Int_t)rawStreamFast->GetStartTimeBin();
326 Int_t endTbin = (Int_t)rawStreamFast->GetEndTimeBin();
327
328 for (Int_t iTimeBin = startTbin; iTimeBin < endTbin; iTimeBin++){
329 Float_t signal = rawStreamFast->GetSignals()[iTimeBin-startTbin];
330 nSignals += Update(iSector,iRow,iPad,iTimeBin+1,signal);
331 withInput = kTRUE;
0ffacf98 332 }
266f8637 333 }
0ffacf98 334 }
335 }
266f8637 336
0ffacf98 337 return withInput;
338}
339//_____________________________________________________________________
340Bool_t AliTPCdataQA::ProcessEventFast(AliRawReader *rawReader)
341{
342 //
343 // Event processing loop - AliRawReader
344 //
345 AliTPCRawStreamFast *rawStreamFast = new AliTPCRawStreamFast(rawReader, (AliAltroMapping**)fMapping);
346 Bool_t res=ProcessEventFast(rawStreamFast);
c75bf2f1 347 if(res)
348 fEventCounter++; // only increment event counter if there is TPC data
349 // otherwise Analyse (called in QA) fails
350
0ffacf98 351 delete rawStreamFast;
352 return res;
353}
354
355//_____________________________________________________________________
356Bool_t AliTPCdataQA::ProcessEvent(AliTPCRawStream *rawStream)
357{
358 //
359 // Event Processing loop - AliTPCRawStream
360 //
361
0ffacf98 362 Bool_t withInput = kFALSE;
266f8637 363 Int_t nSignals = 0;
364 Int_t lastSector = -1;
0ffacf98 365
366 while (rawStream->Next()) {
367
368 Int_t iSector = rawStream->GetSector(); // current ROC
369 Int_t iRow = rawStream->GetRow(); // current row
370 Int_t iPad = rawStream->GetPad(); // current pad
371 Int_t iTimeBin = rawStream->GetTime(); // current time bin
372 Float_t signal = rawStream->GetSignal(); // current ADC signal
266f8637 373
374 // Call local maxima finder if the data is in a new sector
375 if(iSector != lastSector) {
376
377 if(nSignals>0)
378 FindLocalMaxima(lastSector);
379
380 CleanArrays();
381 lastSector = iSector;
382 nSignals = 0;
383 }
0ffacf98 384
266f8637 385 // Sometimes iRow==-1 if there is problems to read the data
386 if(iRow>=0) {
387 nSignals += Update(iSector,iRow,iPad,iTimeBin,signal);
388 withInput = kTRUE;
389 }
0ffacf98 390 }
391
392 return withInput;
393}
394
395
396//_____________________________________________________________________
397Bool_t AliTPCdataQA::ProcessEvent(AliRawReader *rawReader)
398{
399 //
400 // Event processing loop - AliRawReader
401 //
402
403 // if fMapping is NULL the rawstream will crate its own mapping
404 AliTPCRawStream rawStream(rawReader, (AliAltroMapping**)fMapping);
405 rawReader->Select("TPC");
c75bf2f1 406 Bool_t res = ProcessEvent(&rawStream);
407
408 if(res)
409 fEventCounter++; // only increment event counter if there is TPC data
410 // otherwise Analyse (called in QA) fails
411 return res;
0ffacf98 412}
413
414
415//_____________________________________________________________________
416Bool_t AliTPCdataQA::ProcessEvent(eventHeaderStruct *event)
417{
418 //
419 // process date event
420 //
421
422 AliRawReader *rawReader = new AliRawReaderDate((void*)event);
423 Bool_t result=ProcessEvent(rawReader);
424 delete rawReader;
425 return result;
426}
427
428
429
430//_____________________________________________________________________
431void AliTPCdataQA::DumpToFile(const Char_t *filename, const Char_t *dir, Bool_t append) /*FOLD00*/
432{
433 //
434 // Write class to file
435 //
436
437 TString sDir(dir);
438 TString option;
439
440 if ( append )
441 option = "update";
442 else
443 option = "recreate";
444
445 TDirectory *backup = gDirectory;
446 TFile f(filename,option.Data());
447 f.cd();
448 if ( !sDir.IsNull() ){
449 f.mkdir(sDir.Data());
450 f.cd(sDir);
451 }
452 this->Write();
453 f.Close();
454
455 if ( backup ) backup->cd();
456}
457
458
459//_____________________________________________________________________
266f8637 460Int_t AliTPCdataQA::Update(const Int_t iSector, /*FOLD00*/
461 const Int_t iRow,
462 const Int_t iPad,
463 const Int_t iTimeBin,
464 Float_t signal)
0ffacf98 465{
466 //
467 // Signal filling method
468 //
266f8637 469
470 //
471 // Define the calibration objects the first time Update is called
472 // NB! This has to be done first even if the data is rejected by the time
473 // cut to make sure that the objects are available in Analyse
474 //
475 if (!fNLocalMaxima) fNLocalMaxima = new AliTPCCalPad("NLocalMaxima","NLocalMaxima");
0ffacf98 476 if (!fMaxCharge) fMaxCharge = new AliTPCCalPad("MaxCharge","MaxCharge");
f11b3071 477 if (!fMeanCharge) fMeanCharge = new AliTPCCalPad("MeanCharge","MeanCharge");
478 if (!fNoThreshold) fNoThreshold = new AliTPCCalPad("NoThreshold","NoThreshold");
266f8637 479 if (!fNTimeBins) fNTimeBins = new AliTPCCalPad("NTimeBins","NTimeBins");
480 if (!fNPads) fNPads = new AliTPCCalPad("NPads","NPads");
481 if (!fTimePosition) fTimePosition = new AliTPCCalPad("TimePosition","TimePosition");
0ffacf98 482 if (!fOverThreshold10) fOverThreshold10 = new AliTPCCalPad("OverThreshold10","OverThreshold10");
483 if (!fOverThreshold20) fOverThreshold20 = new AliTPCCalPad("OverThreshold20","OverThreshold20");
484 if (!fOverThreshold30) fOverThreshold30 = new AliTPCCalPad("OverThreshold30","OverThreshold30");
266f8637 485 // Make the arrays for expanding the data
f11b3071 486
266f8637 487 if (!fAllBins)
488 MakeArrays();
489
490 //
491 // If Analyse has been previously called we need now to denormalize the data
492 // as more data is coming
493 //
494 if(fIsAnalysed == kTRUE) {
495
496 const Int_t nTimeBins = fLastTimeBin - fFirstTimeBin +1;
497 const Float_t denormalization = Float_t(fEventCounter * nTimeBins);
498 fNoThreshold->Multiply(denormalization);
499
500 fMeanCharge->Multiply(fNLocalMaxima);
501 fMaxCharge->Multiply(fNLocalMaxima);
502 fNTimeBins->Multiply(fNLocalMaxima);
503 fNPads->Multiply(fNLocalMaxima);
504 fTimePosition->Multiply(fNLocalMaxima);
505 fIsAnalysed = kFALSE;
506 }
f11b3071 507
266f8637 508 //
509 // TimeBin cut
510 //
511 if (iTimeBin<fFirstTimeBin) return 0;
512 if (iTimeBin>fLastTimeBin) return 0;
513
f11b3071 514 // if pedestal calibrations are loaded subtract pedestals
515 if(fPedestal) {
516
266f8637 517 Float_t ped = fPedestal->GetCalROC(iSector)->GetValue(iRow, iPad);
518 // Don't use data from pads where pedestals are abnormally small or large
519 if(ped<10 || ped>90)
f11b3071 520 return 0;
266f8637 521 signal -= ped;
f11b3071 522 }
266f8637 523
524 // In fNoThreshold we fill all data to estimate the ZS volume
525 Float_t count = fNoThreshold->GetCalROC(iSector)->GetValue(iRow, iPad);
526 fNoThreshold->GetCalROC(iSector)->SetValue(iRow, iPad,count+1);
527
f11b3071 528 // Require at least 3 ADC channels
266f8637 529 if (signal < 3.0)
f11b3071 530 return 0;
531
532 // if noise calibrations are loaded require at least 3*sigmaNoise
533 if(fNoise) {
266f8637 534
535 Float_t noise = fNoise->GetCalROC(iSector)->GetValue(iRow, iPad);
536
537 if(signal < noise*3.0)
f11b3071 538 return 0;
539 }
266f8637 540
f11b3071 541 //
266f8637 542 // This signal is ok and we store it in the cluster map
0ffacf98 543 //
f11b3071 544
266f8637 545 SetExpandDigit(iRow, iPad, iTimeBin, signal);
546
547 return 1; // signal was accepted
f11b3071 548}
266f8637 549
f11b3071 550//_____________________________________________________________________
266f8637 551void AliTPCdataQA::FindLocalMaxima(const Int_t iSector)
f11b3071 552{
553 //
266f8637 554 // This method is called after the data from each sector has been
555 // exapanded into an array
556 // Loop over the signals and identify local maxima and fill the
557 // calibration objects with the information
f11b3071 558 //
266f8637 559
560 Int_t nLocalMaxima = 0;
561 const Int_t maxTimeBin = fTimeBinsMax+4; // Used to step between neighboring pads
562 // Because we have tha pad-time data in a
563 // 1d array
564
565 for (Int_t iRow = 0; iRow < fRowsMax; iRow++) {
566
567 Float_t* allBins = fAllBins[iRow];
568 Int_t* sigBins = fAllSigBins[iRow];
569 const Int_t nSigBins = fAllNSigBins[iRow];
570
571 for (Int_t iSig = 0; iSig < nSigBins; iSig++) {
572
573 Int_t bin = sigBins[iSig];
574 Float_t *b = &allBins[bin];
575
576 //
577 // Now we check if this is a local maximum
578 //
579
580 Float_t qMax = b[0];
581
582 // First check that the charge is bigger than the threshold
583 if (qMax<5)
584 continue;
585
586 // Require at least one neighboring pad with signal
587 if (b[-maxTimeBin]+b[maxTimeBin]<=0) continue;
588
589 // Require at least one neighboring time bin with signal
590 if (b[-1]+b[1]<=0) continue;
591
592 //
593 // Check that this is a local maximum
594 // Note that the checking is done so that if 2 charges has the same
595 // qMax then only 1 cluster is generated
596 // (that is why there is BOTH > and >=)
597 //
598 if (b[-maxTimeBin] >= qMax) continue;
599 if (b[-1 ] >= qMax) continue;
600 if (b[+maxTimeBin] > qMax) continue;
601 if (b[+1 ] > qMax) continue;
602 if (b[-maxTimeBin-1] >= qMax) continue;
603 if (b[+maxTimeBin-1] >= qMax) continue;
604 if (b[+maxTimeBin+1] > qMax) continue;
605 if (b[-maxTimeBin+1] >= qMax) continue;
606
607 //
608 // Now we accept the local maximum and fill the calibration/data objects
609 //
610 nLocalMaxima++;
611
612 Int_t iPad, iTimeBin;
613 GetPadAndTimeBin(bin, iPad, iTimeBin);
614
615 Float_t count = fNLocalMaxima->GetCalROC(iSector)->GetValue(iRow, iPad);
616 fNLocalMaxima->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
617
618 count = fTimePosition->GetCalROC(iSector)->GetValue(iRow, iPad);
619 fTimePosition->GetCalROC(iSector)->SetValue(iRow, iPad, count+iTimeBin);
620
621 Float_t charge = fMaxCharge->GetCalROC(iSector)->GetValue(iRow, iPad);
622 fMaxCharge->GetCalROC(iSector)->SetValue(iRow, iPad, charge + qMax);
623
624 if(qMax>=10) {
625 count = fOverThreshold10->GetCalROC(iSector)->GetValue(iRow, iPad);
626 fOverThreshold10->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
627 }
628 if(qMax>=20) {
629 count = fOverThreshold20->GetCalROC(iSector)->GetValue(iRow, iPad);
630 fOverThreshold20->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
631 }
632 if(qMax>=30) {
633 count = fOverThreshold30->GetCalROC(iSector)->GetValue(iRow, iPad);
634 fOverThreshold30->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
635 }
636
637 //
638 // Calculate the total charge as the sum over the region:
639 //
640 // o o o o o
641 // o i i i o
642 // o i C i o
643 // o i i i o
644 // o o o o o
645 //
646 // with qmax at the center C.
647 //
648 // The inner charge (i) we always add, but we only add the outer
649 // charge (o) if the neighboring inner bin (i) has a signal.
650 //
651 Int_t minP = 0, maxP = 0, minT = 0, maxT = 0;
652 Float_t qTot = qMax;
653 for(Int_t i = -1; i<=1; i++) {
654 for(Int_t j = -1; j<=1; j++) {
655
656 if(i==0 && j==0)
657 continue;
658
77f88633 659 Float_t charge1 = GetQ(b, i, j, maxTimeBin, minT, maxT, minP, maxP);
660 qTot += charge1;
661 if(charge1>0) {
266f8637 662 // see if the next neighbor is also above threshold
663 if(i*j==0) {
664 qTot += GetQ(b, 2*i, 2*j, maxTimeBin, minT, maxT, minP, maxP);
665 } else {
666 // we are in a diagonal corner
667 qTot += GetQ(b, i, 2*j, maxTimeBin, minT, maxT, minP, maxP);
668 qTot += GetQ(b, 2*i, j, maxTimeBin, minT, maxT, minP, maxP);
669 qTot += GetQ(b, 2*i, 2*j, maxTimeBin, minT, maxT, minP, maxP);
670 }
671 }
672 }
673 }
674
675 charge = fMeanCharge->GetCalROC(iSector)->GetValue(iRow, iPad);
676 fMeanCharge->GetCalROC(iSector)->SetValue(iRow, iPad, charge + qTot);
677
678 count = fNTimeBins->GetCalROC(iSector)->GetValue(iRow, iPad);
679 fNTimeBins->GetCalROC(iSector)->SetValue(iRow, iPad, count + maxT-minT+1);
680
681 count = fNPads->GetCalROC(iSector)->GetValue(iRow, iPad);
682 fNPads->GetCalROC(iSector)->SetValue(iRow, iPad, count + maxP-minP+1);
683
684 } // end loop over signals
685 } // end loop over rows
f11b3071 686
266f8637 687 // cout << "Number of local maximas found: " << nLocalMaxima << endl;
0ffacf98 688}
11ccf1c1 689
f11b3071 690//_____________________________________________________________________
691void AliTPCdataQA::Analyse()
692{
11ccf1c1 693 //
f11b3071 694 // Calculate calibration constants
11ccf1c1 695 //
f11b3071 696
697 cout << "Analyse called" << endl;
698
266f8637 699 if(fIsAnalysed == kTRUE) {
700
701 cout << "No new data since Analyse was called last time" << endl;
702 return;
703 }
f11b3071 704
266f8637 705 if(fEventCounter==0) {
706
f11b3071 707 cout << "EventCounter == 0, Cannot analyse" << endl;
708 return;
709 }
266f8637 710
f11b3071 711 Int_t nTimeBins = fLastTimeBin - fFirstTimeBin +1;
c75bf2f1 712 cout << "EventCounter: " << fEventCounter << endl
f11b3071 713 << "TimeBins: " << nTimeBins << endl;
714
f11b3071 715 Float_t normalization = 1.0 / Float_t(fEventCounter * nTimeBins);
266f8637 716 fNoThreshold->Multiply(normalization);
717
718 fMeanCharge->Divide(fNLocalMaxima);
719 fMaxCharge->Divide(fNLocalMaxima);
720 fNTimeBins->Divide(fNLocalMaxima);
721 fNPads->Divide(fNLocalMaxima);
722 fTimePosition->Divide(fNLocalMaxima);
723
724 fIsAnalysed = kTRUE;
11ccf1c1 725}
258cd111 726
727
266f8637 728//_____________________________________________________________________
258cd111 729void AliTPCdataQA::MakeTree(const char *fname){
730 //
731 // Export result to the tree -located in the file
732 // This file can be analyzed using AliTPCCalibViewer
733 //
258cd111 734 AliTPCPreprocessorOnline preprocesor;
266f8637 735
736 if (fNLocalMaxima) preprocesor.AddComponent(fNLocalMaxima);
737 if (fMaxCharge) preprocesor.AddComponent(fMaxCharge);
738 if (fMeanCharge) preprocesor.AddComponent(fMeanCharge);
739 if (fNoThreshold) preprocesor.AddComponent(fNoThreshold);
740 if (fNTimeBins) preprocesor.AddComponent(fNTimeBins);
741 if (fNPads) preprocesor.AddComponent(fNPads);
742 if (fTimePosition) preprocesor.AddComponent(fTimePosition);
743 if (fOverThreshold10) preprocesor.AddComponent(fOverThreshold10);
744 if (fOverThreshold20) preprocesor.AddComponent(fOverThreshold20);
745 if (fOverThreshold30) preprocesor.AddComponent(fOverThreshold30);
746
258cd111 747 preprocesor.DumpToFile(fname);
748}
c322f08a 749
750
266f8637 751//_____________________________________________________________________
c322f08a 752void AliTPCdataQA::MakeArrays(){
753 //
266f8637 754 // The arrays for expanding the raw data are defined and
755 // som parameters are intialised
c322f08a 756 //
757 AliTPCROC * roc = AliTPCROC::Instance();
758 //
266f8637 759 // To make the array big enough for all sectors we take
760 // the dimensions from the outer row of an OROC (the last sector)
761 //
762 fRowsMax = roc->GetNRows(roc->GetNSector()-1);
763 fPadsMax = roc->GetNPads(roc->GetNSector()-1,fRowsMax-1);
764 fTimeBinsMax = fLastTimeBin - fFirstTimeBin +1;
765
766 //
767 // Since we have added 2 pads (TimeBins) before and after the real pads (TimeBins)
768 // to make sure that we can always query the exanded table even when the
769 // max is on the edge
770 //
771
c322f08a 772
266f8637 773 fAllBins = new Float_t*[fRowsMax];
774 fAllSigBins = new Int_t*[fRowsMax];
775 fAllNSigBins = new Int_t[fRowsMax];
776
777 for (Int_t iRow = 0; iRow < fRowsMax; iRow++) {
c322f08a 778 //
266f8637 779 Int_t maxBin = (fTimeBinsMax+4)*(fPadsMax+4);
c322f08a 780 fAllBins[iRow] = new Float_t[maxBin];
266f8637 781 memset(fAllBins[iRow],0,sizeof(Float_t)*maxBin); // set all values to 0
c322f08a 782 fAllSigBins[iRow] = new Int_t[maxBin];
266f8637 783 fAllNSigBins[iRow] = 0;
c322f08a 784 }
785}
786
787
266f8637 788//_____________________________________________________________________
c322f08a 789void AliTPCdataQA::CleanArrays(){
790 //
791 //
792 //
266f8637 793
794 for (Int_t iRow = 0; iRow < fRowsMax; iRow++) {
c322f08a 795 //
266f8637 796 Int_t maxBin = (fTimeBinsMax+4)*(fPadsMax+4);
c322f08a 797 memset(fAllBins[iRow],0,sizeof(Float_t)*maxBin);
798 fAllNSigBins[iRow]=0;
799 }
800}
801
266f8637 802//_____________________________________________________________________
803void AliTPCdataQA::GetPadAndTimeBin(Int_t bin, Int_t& iPad, Int_t& iTimeBin){
804 //
805 // Return pad and timebin for a given bin
c322f08a 806 //
266f8637 807
808 // Int_t bin = iPad*(fTimeBinsMax+4)+iTimeBin;
809 iTimeBin = bin%(fTimeBinsMax+4);
810 iPad = (bin-iTimeBin)/(fTimeBinsMax+4);
811
812 iPad -= 2;
813 iTimeBin -= 2;
814 iTimeBin += fFirstTimeBin;
815
816 R__ASSERT(iPad>=0 && iPad<=fPadsMax);
817 R__ASSERT(iTimeBin>=fFirstTimeBin && iTimeBin<=fLastTimeBin);
818}
819
820//_____________________________________________________________________
821void AliTPCdataQA::SetExpandDigit(const Int_t iRow, Int_t iPad,
822 Int_t iTimeBin, const Float_t signal)
823{
c322f08a 824 //
266f8637 825 //
c322f08a 826 //
266f8637 827 R__ASSERT(iRow>=0 && iRow<fRowsMax);
828 R__ASSERT(iPad>=0 && iPad<=fPadsMax);
829 R__ASSERT(iTimeBin>=fFirstTimeBin && iTimeBin<=fLastTimeBin);
830
831 iTimeBin -= fFirstTimeBin;
832 iPad += 2;
833 iTimeBin += 2;
c322f08a 834
266f8637 835 Int_t bin = iPad*(fTimeBinsMax+4)+iTimeBin;
836 fAllBins[iRow][bin] = signal;
837 fAllSigBins[iRow][fAllNSigBins[iRow]] = bin;
838 fAllNSigBins[iRow]++;
839}
840
841Float_t AliTPCdataQA::GetQ(const Float_t* adcArray, const Int_t time,
842 const Int_t pad, const Int_t maxTimeBins,
843 Int_t& timeMin, Int_t& timeMax,
844 Int_t& padMin, Int_t& padMax)
845{
846 //
847 // This methods return the charge in the bin time+pad*maxTimeBins
848 // If the charge is above 0 it also updates the padMin, padMax, timeMin
849 // and timeMax if necessary
850 //
851 Float_t charge = adcArray[time + pad*maxTimeBins];
852 if(charge > 0) {
853 timeMin = TMath::Min(time, timeMin); timeMax = TMath::Max(time, timeMax);
854 padMin = TMath::Min(pad, padMin); padMax = TMath::Max(pad, padMax);
855 }
856 return charge;
c322f08a 857}