TPC module
[u/mrichter/AliRoot.git] / TPC / TPCbase / 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/*
0ab2a4cc 20 July 2011:
21
22 Changes to accomodate updates of general DQM/QA changes to have per trigger
23 histograms (for a given event specie).
24
25 AliTPCdataQA has a new flag for only keeping DQM info event by
26 event!
27 The expert/DA functionality has been kept exactly the same!
28
29
1267cf3a 30 June 2010
31
32 This update should solve two problems mainly:
33 * The vs event histograms have been limited to a fixed size for the
34 DQM. The 500k seemed to be a big size but is no longer so, so we
35 need to dynamically expand the range. The non-trivial point is that
36 we also have to do it for the copy owned by AliTPCQADataMakerRec.
37 * The amoreGui now remembers the x-range of the first visualization so
38 the trick of setting the relevant event range as the histogram is
39 filled no longer works.
40
41 The fix is a bit crude but avoids creating a new histogram. Instead
42 the range is expanded (max events and events per bin is doubled) but
43 the number of bins is kept constant! In this way we can change just
44 double the max of the X-axis of the hist and rebin the data. The
45 same can easily be done for the copy owned by AliTPCQADataMakerRec.
46
47 CAUTION:
48 If we change the number of bins we could crash the whole system
49 because ROOT does not create space for extra bins! (but we do not do
50 this). In that way it is a crude solution.
51 The rebinning in the code only works for an even number of bins.
52
53 In addition to the above a bug in the reading of the config file was
54 also found and corrected. fAdcMax was set instead of fEventsPerBin.
55
56 Finally cout was changes to AliInfo.
57
266f8637 58 February 2008
59
60 The code has been heavily modified so that now the RAW data is
61 "expanded" for each sector and stored in a big signal array. Then a
829455ad 62 simple version of the code in AliTPCclusterer is used to identify
266f8637 63 the local maxima and these are then used for QA. This gives a better
64 estimate of the charge (both max and total) and also limits the
65 effect of noise.
66
67 Implementation:
68
69 In Update the RAW signals >= 3 ADC channels are stored in the arrays.
70
71 There are 3 arrays:
72 Float_t** fAllBins 2d array [row][bin(pad, time)] ADC signal
73 Int_t** fAllSigBins 2d array [row][signal#] bin(with signal)
74 Int_t* fAllNSigBins; 1d array [row] Nsignals
75
76 This is done sector by sector.
77
78 When data from a new sector is encountered, the method
79 FindLocalMaxima is called on the data from the previous sector, and
80 the calibration/data objects are updated with the "cluster"
81 info. Finally the arrays are cleared.
82
83 The requirements for a local maxima is:
84 Charge in bin is >= 5 ADC channels.
85 Charge in bin is larger than all the 8 neighboring bins.
86 At least one of the two pad neighbors has a signal.
87 At least one of the two time neighbors has a signal.
88
89 Before accessing the data it is expected that the Analyse method is
90 called. This normalizes some of the data objects to per event or per
91 cluster.
92 If more data is passed to the class after Analyse has been called
93 the normalization is reversed and Analyse has to be called again.
94*/
95
0ffacf98 96
97//Root includes
98#include <TH1F.h>
0ffacf98 99#include <TString.h>
100#include <TMath.h>
0ffacf98 101#include <TDirectory.h>
102#include <TFile.h>
266f8637 103#include <TError.h>
ac940b58 104#include <TMap.h>
6a50ff96 105#include <TProfile.h>
909e332a 106#include <TObjArray.h>
0ffacf98 107//AliRoot includes
108#include "AliRawReader.h"
109#include "AliRawReaderRoot.h"
110#include "AliRawReaderDate.h"
0c25417d 111#include "AliTPCRawStreamV3.h"
0ffacf98 112#include "AliTPCCalROC.h"
113#include "AliTPCROC.h"
114#include "AliMathBase.h"
115#include "TTreeStream.h"
0ffacf98 116
117//date
118#include "event.h"
119#include "AliTPCCalPad.h"
258cd111 120#include "AliTPCPreprocessorOnline.h"
0ffacf98 121
122//header file
123#include "AliTPCdataQA.h"
ce0175fa 124#include "AliLog.h"
0ffacf98 125
92ae9768 126
0ffacf98 127ClassImp(AliTPCdataQA)
128
336156cc 129AliTPCdataQA::AliTPCdataQA() : /*FOLD00*/
0ffacf98 130 fFirstTimeBin(60),
131 fLastTimeBin(1000),
909e332a 132 fAdcMin(3),
133 fAdcMax(1000),
134 fMinQMax(5.f),
135 fRequireNeighbouringPad(kTRUE),
0ffacf98 136 fMapping(NULL),
f11b3071 137 fPedestal(0),
138 fNoise(0),
266f8637 139 fNLocalMaxima(0),
0ffacf98 140 fMaxCharge(0),
f11b3071 141 fMeanCharge(0),
142 fNoThreshold(0),
266f8637 143 fNTimeBins(0),
144 fNPads(0),
145 fTimePosition(0),
c94a79e1 146 fOverThreshold10(0),
147 fOverThreshold20(0),
148 fOverThreshold30(0),
23c9ab21 149 fHistQVsTimeSideA(0),
150 fHistQVsTimeSideC(0),
151 fHistQMaxVsTimeSideA(0),
152 fHistQMaxVsTimeSideC(0),
ce0175fa 153 fHistOccupancyVsEvent(0),
154 fHistNclustersVsEvent(0),
266f8637 155 fEventCounter(0),
156 fIsAnalysed(kFALSE),
ce0175fa 157 fMaxEvents(500000), // Max events for event histograms
158 fEventsPerBin(1000), // Events per bin for event histograms
159 fSignalCounter(0), // Signal counter
160 fClusterCounter(0), // Cluster counter
909e332a 161 fActiveChambers(72),
266f8637 162 fAllBins(0),
163 fAllSigBins(0),
164 fAllNSigBins(0),
165 fRowsMax(0),
166 fPadsMax(0),
0ab2a4cc 167 fTimeBinsMax(0),
168 fIsDQM(kFALSE),
169 fHistOccVsSector(0x0),
92ae9768 170 fHistOcc2dVsSector(0x0),
0ab2a4cc 171 fHistQVsSector(0x0),
172 fHistQmaxVsSector(0x0),
173 fOccVec(0x0),
92ae9768 174 fOccMaxVec(0x0),
175 fOccVecFine(0x0),
176 fOccMaxVecFine(0x0)
0ffacf98 177{
178 //
179 // default constructor
180 //
909e332a 181
182 for (Int_t i=0; i<72; ++i) {fActiveChambers.SetBitNumber(i,kTRUE);}
0ffacf98 183}
184
57acd2d2 185//_____________________________________________________________________
0ffacf98 186AliTPCdataQA::AliTPCdataQA(const AliTPCdataQA &ped) : /*FOLD00*/
336156cc 187 TH1F(ped),
0ffacf98 188 fFirstTimeBin(ped.GetFirstTimeBin()),
189 fLastTimeBin(ped.GetLastTimeBin()),
190 fAdcMin(ped.GetAdcMin()),
191 fAdcMax(ped.GetAdcMax()),
909e332a 192 fMinQMax(ped.GetMinQMax()),
193 fRequireNeighbouringPad(ped.GetRequireNeighbouringPad()),
266f8637 194 fMapping(NULL),
195 fPedestal(0),
196 fNoise(0),
197 fNLocalMaxima(0),
198 fMaxCharge(0),
199 fMeanCharge(0),
200 fNoThreshold(0),
266f8637 201 fNTimeBins(0),
202 fNPads(0),
203 fTimePosition(0),
c94a79e1 204 fOverThreshold10(0),
205 fOverThreshold20(0),
206 fOverThreshold30(0),
23c9ab21 207 fHistQVsTimeSideA(0),
208 fHistQVsTimeSideC(0),
209 fHistQMaxVsTimeSideA(0),
210 fHistQMaxVsTimeSideC(0),
ce0175fa 211 fHistOccupancyVsEvent(0),
212 fHistNclustersVsEvent(0),
266f8637 213 fEventCounter(ped.GetEventCounter()),
214 fIsAnalysed(ped.GetIsAnalysed()),
ce0175fa 215 fMaxEvents(ped.GetMaxEvents()),
216 fEventsPerBin(ped.GetEventsPerBin()),
217 fSignalCounter(ped.GetSignalCounter()),
218 fClusterCounter(ped.GetClusterCounter()),
909e332a 219 fActiveChambers(ped.fActiveChambers),
266f8637 220 fAllBins(0),
221 fAllSigBins(0),
222 fAllNSigBins(0),
223 fRowsMax(0),
224 fPadsMax(0),
0ab2a4cc 225 fTimeBinsMax(0),
226 fIsDQM(ped.GetIsDQM()),
227 fHistOccVsSector(0x0),
92ae9768 228 fHistOcc2dVsSector(0x0),
0ab2a4cc 229 fHistQVsSector(0x0),
230 fHistQmaxVsSector(0x0),
231 fOccVec(0x0),
92ae9768 232 fOccMaxVec(0x0),
233 fOccVecFine(0x0),
234 fOccMaxVecFine(0x0)
0ffacf98 235{
236 //
237 // copy constructor
238 //
266f8637 239 if(ped.GetNLocalMaxima())
240 fNLocalMaxima = new AliTPCCalPad(*ped.GetNLocalMaxima());
241 if(ped.GetMaxCharge())
242 fMaxCharge = new AliTPCCalPad(*ped.GetMaxCharge());
243 if(ped.GetMeanCharge())
244 fMeanCharge = new AliTPCCalPad(*ped.GetMeanCharge());
245 if(ped.GetNoThreshold())
246 fNoThreshold = new AliTPCCalPad(*ped.GetNoThreshold());
247 if(ped.GetNTimeBins())
248 fNTimeBins = new AliTPCCalPad(*ped.GetNTimeBins());
249 if(ped.GetNPads())
250 fNPads = new AliTPCCalPad(*ped.GetNPads());
251 if(ped.GetTimePosition())
252 fTimePosition = new AliTPCCalPad(*ped.GetTimePosition());
253 if(ped.GetOverThreshold10())
254 fOverThreshold10 = new AliTPCCalPad(*ped.GetOverThreshold10());
255 if(ped.GetOverThreshold20())
256 fOverThreshold20 = new AliTPCCalPad(*ped.GetOverThreshold20());
257 if(ped.GetOverThreshold30())
258 fOverThreshold30 = new AliTPCCalPad(*ped.GetOverThreshold30());
1cb9ffdb 259 if(ped.GetHistQVsTimeSideA()) {
23c9ab21 260 fHistQVsTimeSideA = new TProfile(*ped.GetHistQVsTimeSideA());
1cb9ffdb 261 fHistQVsTimeSideA->SetDirectory(0);
262 }
263 if(ped.GetHistQVsTimeSideC()) {
23c9ab21 264 fHistQVsTimeSideC = new TProfile(*ped.GetHistQVsTimeSideC());
1cb9ffdb 265 fHistQVsTimeSideC->SetDirectory(0);
266 }
267 if(ped.GetHistQMaxVsTimeSideA()) {
23c9ab21 268 fHistQMaxVsTimeSideA = new TProfile(*ped.GetHistQMaxVsTimeSideA());
1cb9ffdb 269 fHistQMaxVsTimeSideA->SetDirectory(0);
270 }
271 if(ped.GetHistQMaxVsTimeSideC()) {
23c9ab21 272 fHistQMaxVsTimeSideC = new TProfile(*ped.GetHistQMaxVsTimeSideC());
1cb9ffdb 273 fHistQMaxVsTimeSideC->SetDirectory(0);
274 }
ce0175fa 275 if(ped.GetHistOccupancyVsEventConst()) {
276 fHistOccupancyVsEvent = new TH1F(*ped.GetHistOccupancyVsEventConst());
277 fHistOccupancyVsEvent->SetDirectory(0);
278 }
279 if(ped.GetHistNclustersVsEventConst()) {
280 fHistNclustersVsEvent = new TH1F(*ped.GetHistNclustersVsEventConst());
281 fHistNclustersVsEvent->SetDirectory(0);
282 }
0ffacf98 283}
284
ac940b58 285//_____________________________________________________________________
8ba97cc8 286AliTPCdataQA::AliTPCdataQA(const TMap *config) : /*FOLD00*/
ac940b58 287 TH1F("TPCRAW","TPCRAW",100,0,100),
288 fFirstTimeBin(60),
289 fLastTimeBin(1000),
909e332a 290 fAdcMin(3),
291 fAdcMax(1000),
292 fMinQMax(5.f),
293 fRequireNeighbouringPad(kTRUE),
ac940b58 294 fMapping(NULL),
295 fPedestal(0),
296 fNoise(0),
297 fNLocalMaxima(0),
298 fMaxCharge(0),
299 fMeanCharge(0),
300 fNoThreshold(0),
301 fNTimeBins(0),
302 fNPads(0),
303 fTimePosition(0),
304 fOverThreshold10(0),
305 fOverThreshold20(0),
306 fOverThreshold30(0),
23c9ab21 307 fHistQVsTimeSideA(0),
308 fHistQVsTimeSideC(0),
309 fHistQMaxVsTimeSideA(0),
310 fHistQMaxVsTimeSideC(0),
ce0175fa 311 fHistOccupancyVsEvent(0),
312 fHistNclustersVsEvent(0),
ac940b58 313 fEventCounter(0),
314 fIsAnalysed(kFALSE),
ce0175fa 315 fMaxEvents(500000),
316 fEventsPerBin(1000),
317 fSignalCounter(0),
318 fClusterCounter(0),
909e332a 319 fActiveChambers(72),
ac940b58 320 fAllBins(0),
321 fAllSigBins(0),
322 fAllNSigBins(0),
323 fRowsMax(0),
324 fPadsMax(0),
0ab2a4cc 325 fTimeBinsMax(0),
326 fIsDQM(kFALSE),
327 fHistOccVsSector(0x0),
92ae9768 328 fHistOcc2dVsSector(0x0),
0ab2a4cc 329 fHistQVsSector(0x0),
330 fHistQmaxVsSector(0x0),
331 fOccVec(0x0),
92ae9768 332 fOccMaxVec(0x0),
333 fOccVecFine(0x0),
334 fOccMaxVecFine(0x0)
ac940b58 335{
336 //
337 // default constructor
338 //
339 if (config->GetValue("FirstTimeBin")) fFirstTimeBin = ((TObjString*)config->GetValue("FirstTimeBin"))->GetString().Atoi();
340 if (config->GetValue("LastTimeBin")) fLastTimeBin = ((TObjString*)config->GetValue("LastTimeBin"))->GetString().Atoi();
341 if (config->GetValue("AdcMin")) fAdcMin = ((TObjString*)config->GetValue("AdcMin"))->GetString().Atoi();
342 if (config->GetValue("AdcMax")) fAdcMax = ((TObjString*)config->GetValue("AdcMax"))->GetString().Atoi();
909e332a 343 if (config->GetValue("MinQMax")) fMinQMax = ((TObjString*)config->GetValue("MinQMax"))->GetString().Atof();
ce0175fa 344 if (config->GetValue("MaxEvents")) fMaxEvents = ((TObjString*)config->GetValue("MaxEvents"))->GetString().Atoi();
1267cf3a 345 if (config->GetValue("EventsPerBin")) fEventsPerBin = ((TObjString*)config->GetValue("EventsPerBin"))->GetString().Atoi();
909e332a 346 if (config->GetValue("RequireNeighbouringPad")) fRequireNeighbouringPad = ((TObjString*)config->GetValue("RequireNeighbouringPad"))->GetString().Atoi();
347 for (Int_t i=0; i<72; ++i) {fActiveChambers.SetBitNumber(i,kTRUE);}
ac940b58 348}
0ffacf98 349
350//_____________________________________________________________________
351AliTPCdataQA& AliTPCdataQA::operator = (const AliTPCdataQA &source)
352{
353 //
354 // assignment operator
355 //
356 if (&source == this) return *this;
357 new (this) AliTPCdataQA(source);
358
359 return *this;
360}
361
362
363//_____________________________________________________________________
364AliTPCdataQA::~AliTPCdataQA() /*FOLD00*/
365{
366 //
367 // destructor
368 //
369
370 // do not delete fMapping, because we do not own it.
266f8637 371 // do not delete fMapping, because we do not own it.
372 // do not delete fNoise and fPedestal, because we do not own them.
373
374 delete fNLocalMaxima;
375 delete fMaxCharge;
376 delete fMeanCharge;
377 delete fNoThreshold;
378 delete fNTimeBins;
379 delete fNPads;
380 delete fTimePosition;
381 delete fOverThreshold10;
382 delete fOverThreshold20;
383 delete fOverThreshold30;
23c9ab21 384 delete fHistQVsTimeSideA;
385 delete fHistQVsTimeSideC;
386 delete fHistQMaxVsTimeSideA;
387 delete fHistQMaxVsTimeSideC;
ce0175fa 388 delete fHistOccupancyVsEvent;
389 delete fHistNclustersVsEvent;
266f8637 390
0ab2a4cc 391 // DQM
392 delete fHistOccVsSector;
92ae9768 393 delete fHistOcc2dVsSector;
0ab2a4cc 394 delete fHistQVsSector;
395 delete fHistQmaxVsSector;
396 delete fOccVec;
397 delete fOccMaxVec;
92ae9768 398 delete fOccVecFine;
399 delete fOccMaxVecFine;
0ab2a4cc 400
266f8637 401 for (Int_t iRow = 0; iRow < fRowsMax; iRow++) {
402 delete [] fAllBins[iRow];
403 delete [] fAllSigBins[iRow];
404 }
405 delete [] fAllBins;
406 delete [] fAllSigBins;
407 delete [] fAllNSigBins;
0ffacf98 408}
ce0175fa 409
410//_____________________________________________________________________
411TH1F* AliTPCdataQA::GetHistOccupancyVsEvent()
412{
413 //
414 // Create Occupancy vs event histogram
415 // (we create this histogram differently then the other histograms
416 // because this we want to be able to access and copy
417 // from AliTPCQAMakerRec before it normally would be created)
418 //
419 if(!fHistOccupancyVsEvent) {
420
421 Int_t nBins = fMaxEvents/fEventsPerBin;
422 fHistOccupancyVsEvent = new TH1F("hOccupancyVsEvent", "Occupancy vs event number (~time); Event number; Occupancy", nBins, 0, nBins*fEventsPerBin);
423 fHistOccupancyVsEvent->SetDirectory(0);
ce0175fa 424 }
425
426 return fHistOccupancyVsEvent;
427}
428
429//_____________________________________________________________________
430TH1F* AliTPCdataQA::GetHistNclustersVsEvent()
431{
432 //
433 // Create Nclusters vs event histogram
434 // (we create this histogram differently then the other histograms
435 // because this we want to be able to access and copy
436 // from AliTPCQAMakerRec before it normally would be created)
437 //
438 if(!fHistNclustersVsEvent) {
439
440 Int_t nBins = fMaxEvents/fEventsPerBin;
441 fHistNclustersVsEvent = new TH1F("hNclustersVsEvent", "Nclusters vs event number (~time); Event number; Nclusters per event", nBins, 0, nBins*fEventsPerBin);
442 fHistNclustersVsEvent->SetDirectory(0);
ce0175fa 443 }
444
445 return fHistNclustersVsEvent;
446}
447
448//_____________________________________________________________________
449void AliTPCdataQA::UpdateEventHistograms()
450{
451 // Update histograms that display occupancy and
452 // number of clusters as a function of number of
453 // events
454 if (!fHistOccupancyVsEvent)
455 GetHistOccupancyVsEvent();
456 if (!fHistNclustersVsEvent)
457 GetHistNclustersVsEvent();
458
1267cf3a 459 if(fEventCounter > fMaxEvents) {
460
461 // we have to expand the histogram to handle the larger number of
462 // events. The way it is done now is to double the range and the
463 // number of events per bin (so the number of histogram bins stays
464 // constant)
465 fEventsPerBin *= 2;
466 fMaxEvents *= 2;
467
468 // Change histogram limits
469 const Int_t nBins = fHistOccupancyVsEvent->GetXaxis()->GetNbins();
470 fHistOccupancyVsEvent->GetXaxis()->Set(nBins, fHistOccupancyVsEvent->GetXaxis()->GetNbins(), fMaxEvents);
471 fHistNclustersVsEvent->GetXaxis()->Set(nBins, fHistNclustersVsEvent->GetXaxis()->GetNbins(), fMaxEvents);
472
473 // Rebin the histogram
474 for(Int_t bin = 1; bin <= nBins; bin+=2) {
475
476 Int_t newBin = TMath::Nint(Float_t(bin+1)/2.0);
477 Float_t newContent = (fHistOccupancyVsEvent->GetBinContent(bin)+
478 fHistOccupancyVsEvent->GetBinContent(bin+1))/2.0;
479 fHistOccupancyVsEvent->SetBinContent(newBin, newContent);
480
481 newContent = (fHistNclustersVsEvent->GetBinContent(bin)+
482 fHistNclustersVsEvent->GetBinContent(bin+1))/2.0;
483 fHistNclustersVsEvent->SetBinContent(newBin, newContent);
484 }
485
486 // Set the remaining bins to 0
487 Int_t lastHalf = nBins/2 +1;
488 for(Int_t bin = lastHalf; bin <= nBins; bin++) {
489
490 fHistOccupancyVsEvent->SetBinContent(bin, 0);
491 fHistNclustersVsEvent->SetBinContent(bin, 0);
492 }
493
494 // In this case we should nut update but wait untill the new
495 // number of events per bin is reached!
496 return;
497 }
498
499 const Int_t bin = TMath::Nint(Float_t(fEventCounter)/fEventsPerBin);
500
ce0175fa 501 Float_t averageOccupancy =
502 Float_t(fSignalCounter)/fEventsPerBin/(fLastTimeBin - fFirstTimeBin +1.0)
1267cf3a 503 / 570132.0; // 570,132 is number of pads
504 fHistOccupancyVsEvent->SetBinContent(bin, averageOccupancy);
ce0175fa 505 fSignalCounter = 0;
506
507 Float_t averageNclusters =
508 Float_t(fClusterCounter)/fEventsPerBin;
1267cf3a 509 fHistNclustersVsEvent->SetBinContent(bin, averageNclusters);
ce0175fa 510 fClusterCounter = 0;
511}
512
513//_____________________________________________________________________
6a50ff96 514Bool_t AliTPCdataQA::ProcessEvent(AliTPCRawStreamV3 *const rawStreamV3)
0c25417d 515{
516 //
517 // Event Processing loop - AliTPCRawStreamV3
518 //
519 Bool_t withInput = kFALSE;
520 Int_t nSignals = 0;
521 Int_t lastSector = -1;
909e332a 522
523 Init();
0c25417d 524
525 while ( rawStreamV3->NextDDL() ){
1267cf3a 526
0c25417d 527 while ( rawStreamV3->NextChannel() ){
1267cf3a 528
0c25417d 529 Int_t iSector = rawStreamV3->GetSector(); // current sector
530 Int_t iRow = rawStreamV3->GetRow(); // current row
531 Int_t iPad = rawStreamV3->GetPad(); // current pad
92ae9768 532 Int_t iPatch = rawStreamV3->GetPatchIndex(); // current patch
533 Int_t iBranch = rawStreamV3->GetBranch(); // current branch
0c25417d 534 if (iRow<0 || iPad<0) continue;
535 // Call local maxima finder if the data is in a new sector
536 if(iSector != lastSector) {
537
538 if(nSignals>0)
539 FindLocalMaxima(lastSector);
540
541 CleanArrays();
542 lastSector = iSector;
543 nSignals = 0;
544 }
545
546 while ( rawStreamV3->NextBunch() ){
1267cf3a 547
0c25417d 548 Int_t startTbin = (Int_t)rawStreamV3->GetStartTimeBin();
549 Int_t bunchlength = (Int_t)rawStreamV3->GetBunchLength();
550 const UShort_t *sig = rawStreamV3->GetSignals();
551
552 for (Int_t iTimeBin = 0; iTimeBin<bunchlength; iTimeBin++){
553 Float_t signal=(Float_t)sig[iTimeBin];
92ae9768 554 nSignals += Update(iSector,iRow,iPad,startTbin--,signal, iPatch, iBranch);
0c25417d 555 withInput = kTRUE;
556 }
557 }
558 }
559 }
1267cf3a 560
561 if (lastSector>=0&&nSignals>0)
0c25417d 562 FindLocalMaxima(lastSector);
909e332a 563
564 CleanArrays();
0c25417d 565
566 return withInput;
567}
568
569//_____________________________________________________________________
6a50ff96 570Bool_t AliTPCdataQA::ProcessEvent(AliRawReader *const rawReader)
0c25417d 571{
572 //
573 // Event processing loop - AliRawReader
574 //
92ae9768 575 AliTPCRawStreamV3 rawStreamV3(rawReader,(AliAltroMapping**)fMapping);
c75ba816 576 Bool_t res=ProcessEvent(&rawStreamV3);
ce0175fa 577 if(res) {
0c25417d 578 fEventCounter++; // only increment event counter if there is TPC data
ce0175fa 579
1267cf3a 580 if(fEventCounter%fEventsPerBin==0)
ce0175fa 581 UpdateEventHistograms();
582 }
0c25417d 583 return res;
584}
0ffacf98 585
0ffacf98 586//_____________________________________________________________________
6a50ff96 587Bool_t AliTPCdataQA::ProcessEvent(eventHeaderStruct *const event)
0ffacf98 588{
589 //
590 // process date event
591 //
592
c75ba816 593 AliRawReaderDate rawReader((void*)event);
594 Bool_t result=ProcessEvent(&rawReader);
0ffacf98 595 return result;
596}
597
598
599
600//_____________________________________________________________________
601void AliTPCdataQA::DumpToFile(const Char_t *filename, const Char_t *dir, Bool_t append) /*FOLD00*/
602{
603 //
604 // Write class to file
605 //
606
607 TString sDir(dir);
608 TString option;
609
610 if ( append )
611 option = "update";
612 else
613 option = "recreate";
614
615 TDirectory *backup = gDirectory;
616 TFile f(filename,option.Data());
617 f.cd();
618 if ( !sDir.IsNull() ){
619 f.mkdir(sDir.Data());
620 f.cd(sDir);
621 }
622 this->Write();
623 f.Close();
624
625 if ( backup ) backup->cd();
626}
627
628
629//_____________________________________________________________________
266f8637 630Int_t AliTPCdataQA::Update(const Int_t iSector, /*FOLD00*/
631 const Int_t iRow,
632 const Int_t iPad,
633 const Int_t iTimeBin,
92ae9768 634 Float_t signal,
635 const Int_t iPatch,
636 const Int_t iBranch)
0ffacf98 637{
638 //
639 // Signal filling method
640 //
266f8637 641
909e332a 642 if (!fActiveChambers[iSector]) return 0;
266f8637 643 //
644 // TimeBin cut
645 //
646 if (iTimeBin<fFirstTimeBin) return 0;
647 if (iTimeBin>fLastTimeBin) return 0;
648
f11b3071 649 // if pedestal calibrations are loaded subtract pedestals
650 if(fPedestal) {
651
266f8637 652 Float_t ped = fPedestal->GetCalROC(iSector)->GetValue(iRow, iPad);
653 // Don't use data from pads where pedestals are abnormally small or large
654 if(ped<10 || ped>90)
f11b3071 655 return 0;
266f8637 656 signal -= ped;
f11b3071 657 }
266f8637 658
0ab2a4cc 659 if(fIsDQM) {
660
661 fOccVec->GetArray()[iSector] += 1.0;
92ae9768 662 // To change before committing
663 if(iPatch>=0 && iBranch>=0 && iPatch<=5 && iBranch <= 1)
664 fOccVecFine->GetArray()[(iSector%36)*12+iPatch*2+iBranch] += 1.0;
0ab2a4cc 665 } else {
666 // In fNoThreshold we fill all data to estimate the ZS volume
667 Float_t count = fNoThreshold->GetCalROC(iSector)->GetValue(iRow, iPad);
668 fNoThreshold->GetCalROC(iSector)->SetValue(iRow, iPad,count+1);
669 }
670
f11b3071 671 // Require at least 3 ADC channels
909e332a 672 if (signal < fAdcMin)
f11b3071 673 return 0;
674
675 // if noise calibrations are loaded require at least 3*sigmaNoise
676 if(fNoise) {
266f8637 677
678 Float_t noise = fNoise->GetCalROC(iSector)->GetValue(iRow, iPad);
679
680 if(signal < noise*3.0)
f11b3071 681 return 0;
682 }
266f8637 683
f11b3071 684 //
266f8637 685 // This signal is ok and we store it in the cluster map
0ffacf98 686 //
f11b3071 687
266f8637 688 SetExpandDigit(iRow, iPad, iTimeBin, signal);
ce0175fa 689
690 fSignalCounter++;
266f8637 691
692 return 1; // signal was accepted
f11b3071 693}
266f8637 694
f11b3071 695//_____________________________________________________________________
266f8637 696void AliTPCdataQA::FindLocalMaxima(const Int_t iSector)
f11b3071 697{
698 //
266f8637 699 // This method is called after the data from each sector has been
700 // exapanded into an array
701 // Loop over the signals and identify local maxima and fill the
702 // calibration objects with the information
f11b3071 703 //
266f8637 704
909e332a 705 if (!fActiveChambers[iSector]) return;
706
266f8637 707 Int_t nLocalMaxima = 0;
708 const Int_t maxTimeBin = fTimeBinsMax+4; // Used to step between neighboring pads
709 // Because we have tha pad-time data in a
710 // 1d array
711
712 for (Int_t iRow = 0; iRow < fRowsMax; iRow++) {
713
714 Float_t* allBins = fAllBins[iRow];
715 Int_t* sigBins = fAllSigBins[iRow];
716 const Int_t nSigBins = fAllNSigBins[iRow];
717
718 for (Int_t iSig = 0; iSig < nSigBins; iSig++) {
719
720 Int_t bin = sigBins[iSig];
721 Float_t *b = &allBins[bin];
722
723 //
724 // Now we check if this is a local maximum
725 //
726
727 Float_t qMax = b[0];
728
729 // First check that the charge is bigger than the threshold
909e332a 730 if (qMax<fMinQMax)
266f8637 731 continue;
732
733 // Require at least one neighboring pad with signal
909e332a 734 if (fRequireNeighbouringPad && (b[-maxTimeBin]+b[maxTimeBin]<=0) ) continue;
266f8637 735
736 // Require at least one neighboring time bin with signal
737 if (b[-1]+b[1]<=0) continue;
738
739 //
740 // Check that this is a local maximum
741 // Note that the checking is done so that if 2 charges has the same
742 // qMax then only 1 cluster is generated
743 // (that is why there is BOTH > and >=)
744 //
745 if (b[-maxTimeBin] >= qMax) continue;
746 if (b[-1 ] >= qMax) continue;
747 if (b[+maxTimeBin] > qMax) continue;
748 if (b[+1 ] > qMax) continue;
749 if (b[-maxTimeBin-1] >= qMax) continue;
750 if (b[+maxTimeBin-1] >= qMax) continue;
751 if (b[+maxTimeBin+1] > qMax) continue;
752 if (b[-maxTimeBin+1] >= qMax) continue;
753
754 //
755 // Now we accept the local maximum and fill the calibration/data objects
756 //
909e332a 757 ++nLocalMaxima;
266f8637 758
759 Int_t iPad, iTimeBin;
760 GetPadAndTimeBin(bin, iPad, iTimeBin);
761
0ab2a4cc 762 if(!fIsDQM) {
763 Float_t count = fNLocalMaxima->GetCalROC(iSector)->GetValue(iRow, iPad);
764 fNLocalMaxima->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
765
766 count = fTimePosition->GetCalROC(iSector)->GetValue(iRow, iPad);
767 fTimePosition->GetCalROC(iSector)->SetValue(iRow, iPad, count+iTimeBin);
266f8637 768
0ab2a4cc 769 Float_t charge = fMaxCharge->GetCalROC(iSector)->GetValue(iRow, iPad);
770 fMaxCharge->GetCalROC(iSector)->SetValue(iRow, iPad, charge + qMax);
771
772 if(qMax>=10) {
773 count = fOverThreshold10->GetCalROC(iSector)->GetValue(iRow, iPad);
774 fOverThreshold10->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
775 }
776 if(qMax>=20) {
777 count = fOverThreshold20->GetCalROC(iSector)->GetValue(iRow, iPad);
778 fOverThreshold20->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
779 }
780 if(qMax>=30) {
781 count = fOverThreshold30->GetCalROC(iSector)->GetValue(iRow, iPad);
782 fOverThreshold30->GetCalROC(iSector)->SetValue(iRow, iPad, count+1);
783 }
266f8637 784 }
785
786 //
787 // Calculate the total charge as the sum over the region:
788 //
789 // o o o o o
790 // o i i i o
791 // o i C i o
792 // o i i i o
793 // o o o o o
794 //
795 // with qmax at the center C.
796 //
797 // The inner charge (i) we always add, but we only add the outer
798 // charge (o) if the neighboring inner bin (i) has a signal.
799 //
800 Int_t minP = 0, maxP = 0, minT = 0, maxT = 0;
801 Float_t qTot = qMax;
802 for(Int_t i = -1; i<=1; i++) {
803 for(Int_t j = -1; j<=1; j++) {
804
805 if(i==0 && j==0)
806 continue;
807
77f88633 808 Float_t charge1 = GetQ(b, i, j, maxTimeBin, minT, maxT, minP, maxP);
809 qTot += charge1;
810 if(charge1>0) {
266f8637 811 // see if the next neighbor is also above threshold
812 if(i*j==0) {
813 qTot += GetQ(b, 2*i, 2*j, maxTimeBin, minT, maxT, minP, maxP);
814 } else {
815 // we are in a diagonal corner
816 qTot += GetQ(b, i, 2*j, maxTimeBin, minT, maxT, minP, maxP);
817 qTot += GetQ(b, 2*i, j, maxTimeBin, minT, maxT, minP, maxP);
818 qTot += GetQ(b, 2*i, 2*j, maxTimeBin, minT, maxT, minP, maxP);
819 }
820 }
821 }
822 }
823
0ab2a4cc 824 if(fIsDQM) {
825 fHistQVsSector->Fill(iSector, qTot);
826 fHistQmaxVsSector->Fill(iSector, qMax);
23c9ab21 827 } else {
0ab2a4cc 828 Float_t charge = fMeanCharge->GetCalROC(iSector)->GetValue(iRow, iPad);
829 fMeanCharge->GetCalROC(iSector)->SetValue(iRow, iPad, charge + qTot);
830
831 Float_t count = fNTimeBins->GetCalROC(iSector)->GetValue(iRow, iPad);
832 fNTimeBins->GetCalROC(iSector)->SetValue(iRow, iPad, count + maxT-minT+1);
833
834 count = fNPads->GetCalROC(iSector)->GetValue(iRow, iPad);
835 fNPads->GetCalROC(iSector)->SetValue(iRow, iPad, count + maxP-minP+1);
836
837 if((iSector%36)<18) { // A side
838 fHistQVsTimeSideA->Fill(iTimeBin, qTot);
839 fHistQMaxVsTimeSideA->Fill(iTimeBin, qMax);
840 } else {
841 fHistQVsTimeSideC->Fill(iTimeBin, qTot);
842 fHistQMaxVsTimeSideC->Fill(iTimeBin, qMax);
843 }
23c9ab21 844 }
266f8637 845 } // end loop over signals
846 } // end loop over rows
f11b3071 847
ce0175fa 848 fClusterCounter += nLocalMaxima;
0ffacf98 849}
11ccf1c1 850
f11b3071 851//_____________________________________________________________________
852void AliTPCdataQA::Analyse()
853{
11ccf1c1 854 //
f11b3071 855 // Calculate calibration constants
11ccf1c1 856 //
f11b3071 857
1267cf3a 858 AliInfo("Analyse called");
f11b3071 859
0ab2a4cc 860 if(fIsDQM == kTRUE) {
861
862 AliInfo("DQM flas is set -> No 2d information to analyze");
863 return;
864 }
865
266f8637 866 if(fIsAnalysed == kTRUE) {
867
1267cf3a 868 AliInfo("No new data since Analyse was called last time");
266f8637 869 return;
870 }
f11b3071 871
266f8637 872 if(fEventCounter==0) {
873
1267cf3a 874 AliInfo("EventCounter == 0, Cannot analyse");
f11b3071 875 return;
876 }
266f8637 877
f11b3071 878 Int_t nTimeBins = fLastTimeBin - fFirstTimeBin +1;
1267cf3a 879 AliInfo(Form("EventCounter: %d , TimeBins: %d", fEventCounter, nTimeBins));
f11b3071 880
f11b3071 881 Float_t normalization = 1.0 / Float_t(fEventCounter * nTimeBins);
266f8637 882 fNoThreshold->Multiply(normalization);
883
884 fMeanCharge->Divide(fNLocalMaxima);
885 fMaxCharge->Divide(fNLocalMaxima);
886 fNTimeBins->Divide(fNLocalMaxima);
887 fNPads->Divide(fNLocalMaxima);
888 fTimePosition->Divide(fNLocalMaxima);
889
890 fIsAnalysed = kTRUE;
11ccf1c1 891}
258cd111 892
893
266f8637 894//_____________________________________________________________________
6a50ff96 895void AliTPCdataQA::MakeTree(const char *fname) const {
258cd111 896 //
897 // Export result to the tree -located in the file
898 // This file can be analyzed using AliTPCCalibViewer
899 //
258cd111 900 AliTPCPreprocessorOnline preprocesor;
266f8637 901
902 if (fNLocalMaxima) preprocesor.AddComponent(fNLocalMaxima);
903 if (fMaxCharge) preprocesor.AddComponent(fMaxCharge);
904 if (fMeanCharge) preprocesor.AddComponent(fMeanCharge);
905 if (fNoThreshold) preprocesor.AddComponent(fNoThreshold);
906 if (fNTimeBins) preprocesor.AddComponent(fNTimeBins);
907 if (fNPads) preprocesor.AddComponent(fNPads);
908 if (fTimePosition) preprocesor.AddComponent(fTimePosition);
909 if (fOverThreshold10) preprocesor.AddComponent(fOverThreshold10);
910 if (fOverThreshold20) preprocesor.AddComponent(fOverThreshold20);
911 if (fOverThreshold30) preprocesor.AddComponent(fOverThreshold30);
912
258cd111 913 preprocesor.DumpToFile(fname);
914}
c322f08a 915
916
266f8637 917//_____________________________________________________________________
c322f08a 918void AliTPCdataQA::MakeArrays(){
919 //
266f8637 920 // The arrays for expanding the raw data are defined and
921 // som parameters are intialised
c322f08a 922 //
923 AliTPCROC * roc = AliTPCROC::Instance();
924 //
266f8637 925 // To make the array big enough for all sectors we take
926 // the dimensions from the outer row of an OROC (the last sector)
927 //
928 fRowsMax = roc->GetNRows(roc->GetNSector()-1);
929 fPadsMax = roc->GetNPads(roc->GetNSector()-1,fRowsMax-1);
930 fTimeBinsMax = fLastTimeBin - fFirstTimeBin +1;
931
932 //
933 // Since we have added 2 pads (TimeBins) before and after the real pads (TimeBins)
934 // to make sure that we can always query the exanded table even when the
935 // max is on the edge
936 //
937
c322f08a 938
266f8637 939 fAllBins = new Float_t*[fRowsMax];
940 fAllSigBins = new Int_t*[fRowsMax];
941 fAllNSigBins = new Int_t[fRowsMax];
942
943 for (Int_t iRow = 0; iRow < fRowsMax; iRow++) {
c322f08a 944 //
266f8637 945 Int_t maxBin = (fTimeBinsMax+4)*(fPadsMax+4);
c322f08a 946 fAllBins[iRow] = new Float_t[maxBin];
266f8637 947 memset(fAllBins[iRow],0,sizeof(Float_t)*maxBin); // set all values to 0
c322f08a 948 fAllSigBins[iRow] = new Int_t[maxBin];
266f8637 949 fAllNSigBins[iRow] = 0;
c322f08a 950 }
951}
952
953
266f8637 954//_____________________________________________________________________
c322f08a 955void AliTPCdataQA::CleanArrays(){
956 //
957 //
958 //
266f8637 959
960 for (Int_t iRow = 0; iRow < fRowsMax; iRow++) {
42919b08 961
962 // To speed up the performance by a factor 2 on cosmic data (and
963 // presumably pp data as well) where the ocupancy is low, the
964 // memset is only called if there is more than 1000 signals for a
965 // row (of the order 1% occupancy)
966 if(fAllNSigBins[iRow]<1000) {
967
968 Float_t* allBins = fAllBins[iRow];
969 Int_t* sigBins = fAllSigBins[iRow];
970 const Int_t nSignals = fAllNSigBins[iRow];
971 for(Int_t i = 0; i < nSignals; i++)
23c9ab21 972 allBins[sigBins[i]]=0;
42919b08 973 } else {
23c9ab21 974
42919b08 975 Int_t maxBin = (fTimeBinsMax+4)*(fPadsMax+4);
976 memset(fAllBins[iRow],0,sizeof(Float_t)*maxBin);
977 }
978
c322f08a 979 fAllNSigBins[iRow]=0;
980 }
981}
982
266f8637 983//_____________________________________________________________________
984void AliTPCdataQA::GetPadAndTimeBin(Int_t bin, Int_t& iPad, Int_t& iTimeBin){
985 //
986 // Return pad and timebin for a given bin
c322f08a 987 //
266f8637 988
989 // Int_t bin = iPad*(fTimeBinsMax+4)+iTimeBin;
990 iTimeBin = bin%(fTimeBinsMax+4);
991 iPad = (bin-iTimeBin)/(fTimeBinsMax+4);
992
993 iPad -= 2;
994 iTimeBin -= 2;
995 iTimeBin += fFirstTimeBin;
996
997 R__ASSERT(iPad>=0 && iPad<=fPadsMax);
998 R__ASSERT(iTimeBin>=fFirstTimeBin && iTimeBin<=fLastTimeBin);
999}
1000
1001//_____________________________________________________________________
1002void AliTPCdataQA::SetExpandDigit(const Int_t iRow, Int_t iPad,
1003 Int_t iTimeBin, const Float_t signal)
1004{
c322f08a 1005 //
266f8637 1006 //
c322f08a 1007 //
266f8637 1008 R__ASSERT(iRow>=0 && iRow<fRowsMax);
1009 R__ASSERT(iPad>=0 && iPad<=fPadsMax);
1010 R__ASSERT(iTimeBin>=fFirstTimeBin && iTimeBin<=fLastTimeBin);
1011
1012 iTimeBin -= fFirstTimeBin;
1013 iPad += 2;
1014 iTimeBin += 2;
c322f08a 1015
266f8637 1016 Int_t bin = iPad*(fTimeBinsMax+4)+iTimeBin;
1017 fAllBins[iRow][bin] = signal;
1018 fAllSigBins[iRow][fAllNSigBins[iRow]] = bin;
1019 fAllNSigBins[iRow]++;
1020}
1021
0ab2a4cc 1022//______________________________________________________________________________
266f8637 1023Float_t AliTPCdataQA::GetQ(const Float_t* adcArray, const Int_t time,
1024 const Int_t pad, const Int_t maxTimeBins,
1025 Int_t& timeMin, Int_t& timeMax,
6a50ff96 1026 Int_t& padMin, Int_t& padMax) const
266f8637 1027{
1028 //
1029 // This methods return the charge in the bin time+pad*maxTimeBins
1030 // If the charge is above 0 it also updates the padMin, padMax, timeMin
1031 // and timeMax if necessary
1032 //
1033 Float_t charge = adcArray[time + pad*maxTimeBins];
1034 if(charge > 0) {
1035 timeMin = TMath::Min(time, timeMin); timeMax = TMath::Max(time, timeMax);
1036 padMin = TMath::Min(pad, padMin); padMax = TMath::Max(pad, padMax);
1037 }
1038 return charge;
c322f08a 1039}
ce4b4255 1040
1041//______________________________________________________________________________
6a50ff96 1042void AliTPCdataQA::Streamer(TBuffer &xRuub)
ce4b4255 1043{
1044 // Automatic schema evolution was first used from revision 4
1045 // Code based on:
1046 // http://root.cern.ch/root/roottalk/roottalk02/3207.html
1047
6a50ff96 1048 UInt_t xRuus, xRuuc;
1049 if (xRuub.IsReading()) {
1050 Version_t xRuuv = xRuub.ReadVersion(&xRuus, &xRuuc);
ce4b4255 1051 //we use the automatic algorithm for class version > 3
6a50ff96 1052 if (xRuuv > 3) {
1053 AliTPCdataQA::Class()->ReadBuffer(xRuub, this, xRuuv, xRuus,
1054 xRuuc);
ce4b4255 1055 return;
1056 }
6a50ff96 1057 TH1F::Streamer(xRuub);
1058 xRuub >> fFirstTimeBin;
1059 xRuub >> fLastTimeBin;
1060 xRuub >> fAdcMin;
1061 xRuub >> fAdcMax;
1062 xRuub >> fNLocalMaxima;
1063 xRuub >> fMaxCharge;
1064 xRuub >> fMeanCharge;
1065 xRuub >> fNoThreshold;
1066 xRuub >> fNTimeBins;
1067 xRuub >> fNPads;
1068 xRuub >> fTimePosition;
1069 xRuub >> fEventCounter;
1070 xRuub >> fIsAnalysed;
1071 xRuub.CheckByteCount(xRuus, xRuuc, AliTPCdataQA::IsA());
ce4b4255 1072 } else {
6a50ff96 1073 AliTPCdataQA::Class()->WriteBuffer(xRuub,this);
ce4b4255 1074 }
1075}
0ab2a4cc 1076
1077//____________________________________________________________________________________________
1078void AliTPCdataQA::FillOccupancyProfile()
1079{
1080 // This has to be filled at the end of the loop over data
1081 if(!fIsDQM)
1082 AliInfo("Method only meaningful for DQM");
1083
1084 for(Int_t i = 0; i < 72; i++) {
1085
1086 fOccVec->GetArray()[i] /= fOccMaxVec->GetArray()[i];
1087 fHistOccVsSector->Fill(i, fOccVec->GetArray()[i]);
1088 }
92ae9768 1089
1090 const Int_t nBranches = 36*12;
1091 for(Int_t i = 0; i < nBranches; i++) {
1092
1093 fOccVecFine->GetArray()[i] /= fOccMaxVecFine->GetArray()[i];
1094
1095 const Int_t fullSector = Int_t(i/12);
1096
1097 Int_t branch = i - fullSector*12;
1098 const Int_t patch = Int_t(branch/2);
1099
1100 branch -= patch*2;
1101
1102 fHistOcc2dVsSector->Fill(fullSector+0.5*branch+0.1, patch+0.5, fOccVecFine->GetArray()[i]);
1103 }
0ab2a4cc 1104}
1105
1106//____________________________________________________________________________________________
1107void AliTPCdataQA::ResetProfiles()
1108{
1109 if(!fIsDQM)
1110 AliInfo("Method only meaningful for DQM");
1111
1112 if(fHistQVsSector)
1113 fHistQVsSector->Reset();
1114 if(fHistQmaxVsSector)
1115 fHistQmaxVsSector->Reset();
1116 if(fHistOccVsSector)
1117 fHistOccVsSector->Reset();
92ae9768 1118 if(fHistOcc2dVsSector)
1119 fHistOcc2dVsSector->Reset();
0ab2a4cc 1120
1121 if(fOccVec)
1122 for(Int_t i = 0; i < 72; i++)
1123 fOccVec->GetArray()[i] = 0.0;
92ae9768 1124 if(fOccVecFine)
1125 for(Int_t i = 0; i < 36*12; i++)
1126 fOccVecFine->GetArray()[i] = 0.0;
0ab2a4cc 1127}
909e332a 1128
1129//____________________________________________________________________________________________
1130void AliTPCdataQA::Init()
1131{
1132 //
1133 // Define the calibration objects the first time Update is called
1134 // NB! This has to be done first even if the data is rejected by the time
1135 // cut to make sure that the objects are available in Analyse
1136 //
1137 if(!fIsDQM) {
1138
1139 if (!fNLocalMaxima){
1140 TObjArray configArr(72);
1141 fNLocalMaxima = new AliTPCCalPad(ConfigArrRocs(&configArr,"NLocalMaxima"));
1142 fMaxCharge = new AliTPCCalPad(ConfigArrRocs(&configArr,"MaxCharge"));
1143 fMeanCharge = new AliTPCCalPad(ConfigArrRocs(&configArr,"MeanCharge"));
1144 fNoThreshold = new AliTPCCalPad(ConfigArrRocs(&configArr,"NoThreshold"));
1145 fNTimeBins = new AliTPCCalPad(ConfigArrRocs(&configArr,"NTimeBins"));
1146 fNPads = new AliTPCCalPad(ConfigArrRocs(&configArr,"NPads"));
1147 fTimePosition = new AliTPCCalPad(ConfigArrRocs(&configArr,"TimePosition"));
1148 fOverThreshold10 = new AliTPCCalPad(ConfigArrRocs(&configArr,"OverThreshold10"));
1149 fOverThreshold20 = new AliTPCCalPad(ConfigArrRocs(&configArr,"OverThreshold20"));
1150 fOverThreshold30 = new AliTPCCalPad(ConfigArrRocs(&configArr,"OverThreshold30"));
1151
1152 fHistQVsTimeSideA = new TProfile("hQVsTimeSideA", "Q vs time (side A); Time [Timebin]; Q [ADC ch]", 100, 0, 1000);
1153 fHistQVsTimeSideA->SetDirectory(0);
1154 fHistQVsTimeSideC = new TProfile("hQVsTimeSideC", "Q vs time (side C); Time [Timebin]; Q [ADC ch]", 100, 0, 1000);
1155 fHistQVsTimeSideC->SetDirectory(0);
1156 fHistQMaxVsTimeSideA = new TProfile("hQMaxVsTimeSideA", "Q_{MAX} vs time (side A); Time [Timebin]; Q_{MAX} [ADC ch]", 100, 0, 1000);
1157 fHistQMaxVsTimeSideA->SetDirectory(0);
1158 fHistQMaxVsTimeSideC = new TProfile("hQMaxVsTimeSideC", "Q_{MAX} vs time (side C); Time [Timebin]; Q_{MAX} [ADC ch]", 100, 0, 1000);
1159 fHistQMaxVsTimeSideC->SetDirectory(0);
1160 }
1161 } else { // DQM histograms and array
1162
1163 if (!fHistOccVsSector) {
1164 fHistOccVsSector = new TProfile("hOccVsSector", "Occupancy vs sector; Sector; Occupancy", 72, 0, 72);
1165 fHistOccVsSector->SetDirectory(0);
1166
1167 fHistOcc2dVsSector = new TProfile2D("hOcc2dVsSector", "Occupancy vs sector and patch; Sector; Patch", 72, 0, 36, 6, 0, 6);
1168 fHistOcc2dVsSector->SetDirectory(0);
1169
1170 fHistQVsSector = new TProfile("hQVsSector", "Q vs sector; Sector; Q [ADC ch]", 72, 0, 72);
1171 fHistQVsSector->SetDirectory(0);
1172
1173 fHistQmaxVsSector = new TProfile("hQmaxVsSector", "Qmax vs sector; Sector; Qmax [ADC ch]", 72, 0, 72);
1174 fHistQmaxVsSector->SetDirectory(0);
1175
1176 fOccVec = new TArrayD(72);
1177 for(Int_t i = 0; i < 72; i++)
1178 fOccVec->GetArray()[i] = 0;
1179
1180 fOccMaxVec = new TArrayD(72);
1181 const Double_t nTimeBins = fLastTimeBin - fFirstTimeBin +1;
1182 for(Int_t i = 0; i < 72; i++)
1183
1184 if(i<36) // IROCs (5504 pads)
1185 fOccMaxVec->GetArray()[i] = nTimeBins*5504;
1186 else // OROCs (9984 pads)
1187 fOccMaxVec->GetArray()[i] = nTimeBins*9984;
1188
1189 // 12 branches for each full sector
1190 const Int_t nBranches = 36*12;
1191 fOccVecFine = new TArrayD(nBranches);
1192 for(Int_t i = 0; i < nBranches; i++)
1193 fOccVecFine->GetArray()[i] = 0;
1194
1195 // Pads per patch same for all sectors
1196 Int_t nPads0[6] = {1152, 1536, 1152, 1280, 1280, 1280};
1197 Int_t nPads1[6] = {1152, 1664, 1152, 1280, 1280, 1280};
1198
1199 fOccMaxVecFine = new TArrayD(nBranches);
1200 for(Int_t i = 0; i < nBranches; i++) {
1201
1202 const Int_t fullSector = Int_t(i/12);
1203 Int_t branch = i - fullSector*12;
1204 R__ASSERT(branch>=0 && branch<12);
1205
1206 const Int_t patch = Int_t(branch/2);
1207 branch -= patch*2;
1208
1209 R__ASSERT(branch>=0 && branch<2);
1210 if(branch == 0)
1211 fOccMaxVecFine->GetArray()[i] = nTimeBins*nPads0[patch];
1212 else // OROCs (9984 pads)
1213 fOccMaxVecFine->GetArray()[i] = nTimeBins*nPads1[patch];
1214 }
1215 }
1216 }
1217 // Make the arrays for expanding the data
1218
1219 if (!fAllBins)
1220 MakeArrays();
1221
1222 //
1223 // If Analyse has been previously called we need now to denormalize the data
1224 // as more data is coming
1225 //
1226 if(fIsAnalysed == kTRUE && !fIsDQM) {
1227
1228 const Int_t nTimeBins = fLastTimeBin - fFirstTimeBin +1;
1229 const Float_t denormalization = Float_t(fEventCounter * nTimeBins);
1230 fNoThreshold->Multiply(denormalization);
1231
1232 fMeanCharge->Multiply(fNLocalMaxima);
1233 fMaxCharge->Multiply(fNLocalMaxima);
1234 fNTimeBins->Multiply(fNLocalMaxima);
1235 fNPads->Multiply(fNLocalMaxima);
1236 fTimePosition->Multiply(fNLocalMaxima);
1237 fIsAnalysed = kFALSE;
1238 }
1239}
1240
1241//____________________________________________________________________________________________
1242void AliTPCdataQA::ResetData()
1243{
1244 //
1245 // reset all data
1246 //
1247 if(!fIsDQM) {
1248
1249 if (fNLocalMaxima){
1250 fNoThreshold->Reset();
1251 fNLocalMaxima->Reset();
1252 fMeanCharge->Reset();
1253 fMaxCharge->Reset();
1254 fNTimeBins->Reset();
1255 fNPads->Reset();
1256 fTimePosition->Reset();
1257 fOverThreshold10->Reset();
1258 fOverThreshold20->Reset();
1259 fOverThreshold30->Reset();
1260
1261 fHistQVsTimeSideA->Reset();
1262 fHistQVsTimeSideC->Reset();
1263 fHistQMaxVsTimeSideA->Reset();
1264 fHistQMaxVsTimeSideC->Reset();
1265
1266 fIsAnalysed = kFALSE;
1267
1268 }
1269 }
1270
1271 fEventCounter=0;
1272 fClusterCounter=0;
1273}
1274
1275TObjArray *AliTPCdataQA::ConfigArrRocs(TObjArray *arr, const Text_t* name)
1276{
1277 //
1278 // GetArray with confiured ROCs
1279 //
1280
1281 arr->Clear();
1282 arr->SetName(name);
1283 for (Int_t i=0; i<72; ++i){
1284 if (fActiveChambers[i]) arr->AddAt(new AliTPCCalROC(i),i);
1285 }
1286 return arr;
1287}