1 /**************************************************************************
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 ////////////////////////////////////////////////////////////
17 // Author: Henrik Tydesjo //
18 // This class is used in the detector algorithm framework //
19 // to process the data stored in special container files //
20 // (see AliITSOnlineSPDphys). //
21 ////////////////////////////////////////////////////////////
23 #include "AliITSOnlineSPDphysAnalyzer.h"
24 #include "AliITSOnlineSPDphys.h"
25 #include "AliITSOnlineCalibrationSPDhandler.h"
26 #include "AliITSRawStreamSPD.h"
27 #include "AliITSIntMap.h"
37 AliITSOnlineSPDphysAnalyzer::AliITSOnlineSPDphysAnalyzer(const Char_t *fileName, AliITSOnlineCalibrationSPDhandler* handler, Bool_t readFromGridFile) :
38 fFileName(fileName),fPhysObj(NULL),fHandler(handler),
39 fNrEnoughStatChips(0),fNrDeadChips(0),fNrInefficientChips(0),
40 fNrEqHits(0),fbDeadProcessed(kFALSE),
41 fThreshNoisy(1e-9),fThreshDead(1e-9),
42 fMinEventsForNoisy(10000),fMinEventsForDead(10000),
43 fDefinitelyNoisyRatio(0.3),
44 fMinNrEqHitsForDeadChips(60000),fRatioToMeanForInefficientChip(0.1)
47 Init(readFromGridFile);
50 AliITSOnlineSPDphysAnalyzer::AliITSOnlineSPDphysAnalyzer(AliITSOnlineSPDphys* physObj, AliITSOnlineCalibrationSPDhandler* handler) :
51 fFileName("test.root"),fPhysObj(NULL),fHandler(handler),
52 fNrEnoughStatChips(0),fNrDeadChips(0),fNrInefficientChips(0),
53 fNrEqHits(0),fbDeadProcessed(kFALSE),
54 fThreshNoisy(1e-9),fThreshDead(1e-9),
55 fMinEventsForNoisy(10000),fMinEventsForDead(10000),
56 fDefinitelyNoisyRatio(0.3),
57 fMinNrEqHitsForDeadChips(60000),fRatioToMeanForInefficientChip(0.1)
63 AliITSOnlineSPDphysAnalyzer::AliITSOnlineSPDphysAnalyzer(const AliITSOnlineSPDphysAnalyzer& handle) :
64 fFileName("test.root"),fPhysObj(NULL),fHandler(NULL),
65 fNrEnoughStatChips(0),fNrDeadChips(0),fNrInefficientChips(0),
66 fNrEqHits(0),fbDeadProcessed(kFALSE),
67 fThreshNoisy(1e-9),fThreshDead(1e-9),
68 fMinEventsForNoisy(10000),fMinEventsForDead(10000),
69 fDefinitelyNoisyRatio(0.3),
70 fMinNrEqHitsForDeadChips(60000),fRatioToMeanForInefficientChip(0.1)
72 // copy constructor, only copies the filename and params (not the processed data)
73 fFileName=handle.fFileName;
74 fThreshNoisy = handle.fThreshNoisy;
75 fThreshDead = handle.fThreshDead;
76 fMinEventsForNoisy = handle.fMinEventsForNoisy;
77 fMinEventsForDead = handle.fMinEventsForDead;
78 fDefinitelyNoisyRatio = handle.fDefinitelyNoisyRatio;
79 fMinNrEqHitsForDeadChips = handle.fMinNrEqHitsForDeadChips;
80 fRatioToMeanForInefficientChip = handle.fRatioToMeanForInefficientChip;
85 AliITSOnlineSPDphysAnalyzer::~AliITSOnlineSPDphysAnalyzer() {
87 if (fPhysObj!=NULL) delete fPhysObj;
90 AliITSOnlineSPDphysAnalyzer& AliITSOnlineSPDphysAnalyzer::operator=(const AliITSOnlineSPDphysAnalyzer& handle) {
91 // assignment operator, only copies the filename and params (not the processed data)
93 if (fPhysObj!=NULL) delete fPhysObj;
95 fFileName=handle.fFileName;
96 fThreshNoisy = handle.fThreshNoisy;
97 fThreshDead = handle.fThreshDead;
98 fMinEventsForNoisy = handle.fMinEventsForNoisy;
99 fMinEventsForDead = handle.fMinEventsForDead;
100 fDefinitelyNoisyRatio = handle.fDefinitelyNoisyRatio;
101 fMinNrEqHitsForDeadChips = handle.fMinNrEqHitsForDeadChips;
102 fRatioToMeanForInefficientChip = handle.fRatioToMeanForInefficientChip;
106 fNrEnoughStatChips = 0;
108 fNrInefficientChips = 0;
110 fbDeadProcessed = kFALSE;
117 void AliITSOnlineSPDphysAnalyzer::Init(Bool_t readFromGridFile) {
118 // initialize container obj
119 if (!readFromGridFile) {
120 FILE* fp0 = fopen(fFileName.Data(), "r");
128 fPhysObj = new AliITSOnlineSPDphys(fFileName.Data(), readFromGridFile);
131 void AliITSOnlineSPDphysAnalyzer::SetParam(const Char_t *pname, const Char_t *pval) {
133 TString name = pname;
135 // printf("Setting Param %s to %s\n",name.Data(),val.Data());
136 if (name.CompareTo("MistakeProbabilityNoisy")==0) {
137 Double_t mistakeProbabilityNoisy = val.Atof();
138 fThreshNoisy = mistakeProbabilityNoisy/(20*6*10*32*256);
140 else if (name.CompareTo("MistakeProbabilityDead")==0) {
141 Double_t mistakeProbabilityDead = val.Atof();
142 fThreshDead = mistakeProbabilityDead/(20*6*10*32*256);
144 else if (name.CompareTo("fMinEventsForNoisy")==0) {
145 fMinEventsForNoisy = val.Atoi();
147 else if (name.CompareTo("fMinEventsForDead")==0) {
148 fMinEventsForDead = val.Atoi();
150 else if (name.CompareTo("fDefinitelyNoisyRatio")==0) {
151 fDefinitelyNoisyRatio = val.Atof();
153 else if (name.CompareTo("fMinNrEqHitsForDeadChips")==0) {
154 fMinNrEqHitsForDeadChips = val.Atof();
156 else if (name.CompareTo("fRatioToMeanForInefficientChip")==0) {
157 fRatioToMeanForInefficientChip = val.Atof();
160 Error("AliITSOnlineSPDphysAnalyzer::SetParam","Parameter %s in configuration file unknown.",name.Data());
164 void AliITSOnlineSPDphysAnalyzer::ReadParamsFromLocation(const Char_t *dirName) {
165 // opens file (default name) in dir dirName and reads parameters from it
166 TString paramsFileName = Form("%s/physics_params.txt",dirName);
168 paramsFile.open(paramsFileName, ifstream::in);
169 if (paramsFile.fail()) {
170 printf("No config file (%s) present. Using default tuning parameters.\n",paramsFileName.Data());
176 paramsFile >> paramN;
177 if (paramsFile.eof()) break;
178 paramsFile >> paramV;
179 SetParam(paramN,paramV);
180 if (paramsFile.eof()) break;
187 UInt_t AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels() {
188 // process noisy pixel data , returns number of chips with enough statistics
189 if (fPhysObj==NULL) {
190 Warning("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","No data!");
193 // do we have enough events to even try the algorithm?
194 if (GetNrEvents() < fMinEventsForNoisy) {
195 Warning("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","Nr events (%d) < fMinEventsForNoisy (%d)!",GetNrEvents(),fMinEventsForNoisy);
198 // handler should be initialized
199 if (fHandler==NULL) {
200 Error("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","Calibration handler is not initialized!");
204 UInt_t nrEnoughStatChips = 0;
206 for (UInt_t hs=0; hs<6; hs++) {
207 for (UInt_t chip=0; chip<10; chip++) {
210 UInt_t nrChipHits = 0;
211 UInt_t nrMostHits = 0;
212 for (UInt_t col=0; col<32; col++) {
213 for (UInt_t row=0; row<256; row++) {
214 UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
215 nrChipHits += nrHits;
216 // if (nrHits>0) nrPixels++; // don't include pixels that might be dead
218 if (nrHits>fDefinitelyNoisyRatio*GetNrEvents()) {
219 fHandler->SetNoisyPixel(GetEqNr(),hs,chip,col,row);
224 if (nrMostHits<nrHits) nrMostHits=nrHits;
229 if (nrChipHits>0) { // otherwise there are for sure no noisy
230 // Binomial with n events and probability p for pixel hit
231 UInt_t n = GetNrEvents();
232 if (nrPixels>0 && n>0) {
234 Double_t p = (Double_t)nrChipHits/nrPixels/n;
237 Double_t bin = pow((Double_t)(1-p),(Double_t)n);
240 while ((bin>fThreshNoisy || k<n*p) && k<=n) {
242 bin = bin*(n-k+1)/k*p/(1-p);
245 // can we find noisy pixels...?
247 // printf("eq %d , hs %d , chip %d : Noisy level = %d\n",GetEqNr(),hs,chip,k);
249 // add noisy pixels to handler
251 if (nrMostHits>=noiseLimit) {
252 for (UInt_t col=0; col<32; col++) {
253 for (UInt_t row=0; row<256; row++) {
254 UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
255 if (nrHits >= noiseLimit) {
256 fHandler->SetNoisyPixel(GetEqNr(),hs,chip,col,row);
269 return nrEnoughStatChips;
272 UInt_t AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels(UInt_t eq, UInt_t nrEvts) {
273 // process noisy pixel data , returns number of chips with enough statistics
274 if (fPhysObj==NULL) {
275 Warning("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","No data!");
278 // do we have enough events to even try the algorithm?
279 if (nrEvts < fMinEventsForNoisy) {
280 Warning("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","Nr events (%d) < fMinEventsForNoisy (%d)!",nrEvts,fMinEventsForNoisy);
283 // handler should be initialized
284 if (fHandler==NULL) {
285 Error("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","Calibration handler is not initialized!");
289 UInt_t nrEnoughStatChips = 0;
291 for (UInt_t hs=0; hs<6; hs++) {
292 for (UInt_t chip=0; chip<10; chip++) {
295 UInt_t nrChipHits = 0;
296 UInt_t nrMostHits = 0;
297 for (UInt_t col=0; col<32; col++) {
298 for (UInt_t row=0; row<256; row++) {
299 UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
300 nrChipHits += nrHits;
301 // if (nrHits>0) nrPixels++; // don't include pixels that might be dead
303 if (nrHits>fDefinitelyNoisyRatio*nrEvts) {
304 fHandler->SetNoisyPixel(eq,hs,chip,col,row);
309 if (nrMostHits<nrHits) nrMostHits=nrHits;
314 if (nrChipHits>0) { // otherwise there are for sure no noisy
315 // Binomial with n events and probability p for pixel hit
317 if (nrPixels>0 && n>0) {
319 Double_t p = (Double_t)nrChipHits/nrPixels/n;
322 Double_t bin = pow((Double_t)(1-p),(Double_t)n);
325 while ((bin>fThreshNoisy || k<n*p) && k<=n) {
327 bin = bin*(n-k+1)/k*p/(1-p);
330 // can we find noisy pixels...?
332 // printf("eq %d , hs %d , chip %d : Noisy level = %d\n",GetEqNr(),hs,chip,k);
334 // add noisy pixels to handler
336 if (nrMostHits>=noiseLimit) {
337 for (UInt_t col=0; col<32; col++) {
338 for (UInt_t row=0; row<256; row++) {
339 UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
340 if (nrHits >= noiseLimit) {
341 fHandler->SetNoisyPixel(eq,hs,chip,col,row);
354 return nrEnoughStatChips;
358 UInt_t AliITSOnlineSPDphysAnalyzer::ProcessDeadPixels() {
359 // process dead pixel data , returns number of chips with enough statistics
360 if (fPhysObj==NULL) {
361 Warning("AliITSOnlineSPDphysAnalyzer::ProcessDeadPixels","No data!");
365 // do we have enough events to even try the algorithm?
366 if (GetNrEvents() < fMinEventsForDead) {
367 Warning("AliITSOnlineSPDphysAnalyzer::ProcessDeadPixels","Nr events (%d) < fMinEventsForDead (%d)!",GetNrEvents(),fMinEventsForDead);
370 // handler should be initialized
371 if (fHandler==NULL) {
372 Error("AliITSOnlineSPDphysAnalyzer::ProcessDeadPixels","Calibration handler is not initialized!");
376 AliITSIntMap* possiblyDead = new AliITSIntMap();
377 AliITSIntMap* possiblyIneff = new AliITSIntMap();
379 fNrEnoughStatChips = 0;
381 fNrInefficientChips = 0;
382 UInt_t nrPossiblyDeadChips = 0;
386 for (UInt_t hs=0; hs<6; hs++) {
387 if (!fHandler->IsActiveHS(GetEqNr(),hs)) {
391 for (UInt_t chip=0; chip<10; chip++) {
392 if (!fHandler->IsActiveChip(GetEqNr(),hs,chip)) {
396 // perform search for individual dead pixels...
399 UInt_t nrPossiblyDeadPixels = 0;
401 UInt_t nrChipHits = 0;
402 for (UInt_t col=0; col<32; col++) {
403 for (UInt_t row=0; row<256; row++) {
404 UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
405 nrChipHits += nrHits;
406 if (!fHandler->IsPixelNoisy(GetEqNr(),hs,chip,col,row)) {
407 // don't include noisy pixels
410 nrPossiblyDeadPixels++;
413 fHandler->UnSetDeadPixel(GetEqNr(),hs,chip,col,row); // unset (no action unless dead before)
417 nrChipHits -= nrHits; // this is needed when running offline (online nrHits should be 0 already)
421 fNrEqHits+=nrChipHits;
424 // make sure the chip is not flagged as dead
425 fHandler->SetDeadChip(GetEqNr(),hs,chip,kFALSE);
428 if (nrPossiblyDeadPixels==0) {
429 // no need to see if we have enough statistics...
430 fNrEnoughStatChips++;
432 // printf("%3d",good);
433 // if (chip==9) printf("\n");
438 nrPossiblyDeadChips++;
439 possiblyDead->Insert(hs,chip);
441 // printf("%3d",good);
442 // if (chip==9) printf("\n");
446 // Binomial with n events and probability p for pixel hit
447 UInt_t n = GetNrEvents();
448 if (nrPixels>0 && n>0) {
450 Double_t p = (Double_t)nrChipHits/nrPixels/n;
452 // probability of falsely assigning a dead pixel
453 Double_t falselyDeadProb = pow((Double_t)(1-p),(Double_t)n);
454 // printf("falselyprob=%e\n",falselyDeadProb);
456 // can we find dead pixels...?
457 if (falselyDeadProb<fThreshDead) {
458 fNrEnoughStatChips++;
460 // add dead pixels to handler
461 for (UInt_t col=0; col<32; col++) {
462 for (UInt_t row=0; row<256; row++) {
463 UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
465 if (!fHandler->IsPixelNoisy(GetEqNr(),hs,chip,col,row)) {
466 // don't include noisy pixels
467 fHandler->SetDeadPixel(GetEqNr(),hs,chip,col,row);
474 // this might be an inefficient chip
475 possiblyIneff->Insert(hs*10+chip,nrChipHits);
481 // this is a completely noisy chip... put in category enough stat
482 fNrEnoughStatChips++;
487 // printf("%3d",good);
488 // if (chip==9) printf("\n");
499 if (fNrEqHits>fMinNrEqHitsForDeadChips) {
500 while (possiblyDead->Pop(key,val)) {
501 fHandler->SetDeadChip(GetEqNr(),key,val,kFALSE);
503 fNrDeadChips+=nrPossiblyDeadChips;
507 // inefficient chips?
508 while (possiblyIneff->Pop(key,val)) {
509 if (val<fNrEqHits/60*fRatioToMeanForInefficientChip) {
510 fNrInefficientChips++;
513 delete possiblyIneff;
516 fbDeadProcessed = kTRUE;
518 return fNrEnoughStatChips;
522 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrEnoughStatChips() {
523 // returns nr of enough stat chips
524 if (!fbDeadProcessed) ProcessDeadPixels();
525 return fNrEnoughStatChips;
527 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrDeadChips() {
528 // returns nr of dead chips
529 if (!fbDeadProcessed) ProcessDeadPixels();
532 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrInefficientChips() {
533 // returns nr of inefficient chips
534 if (!fbDeadProcessed) ProcessDeadPixels();
535 return fNrInefficientChips;
537 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrNeedsMoreStatChips() {
538 // returns nr of needs more stat chips
539 if (!fbDeadProcessed) ProcessDeadPixels();
540 return 60-fNrEnoughStatChips-fNrDeadChips-fNrInefficientChips;
543 UInt_t AliITSOnlineSPDphysAnalyzer::GetEqNr() const {
544 // returns the eq nr of phys obj
545 if (fPhysObj!=NULL) return fPhysObj->GetEqNr();
549 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrEvents() const {
550 // returns the nr of events of phys obj
551 if (fPhysObj!=NULL) return fPhysObj->GetNrEvents();
555 void AliITSOnlineSPDphysAnalyzer::Exponent(Double_t &val, Int_t &valExp) const {
556 // put double in format with val and exp so that 1<val<10 - The actual value is val*10e(valExp)
566 //____________________________________________________________________________________________________
567 TH2F* AliITSOnlineSPDphysAnalyzer::GetPhysicalHitMapTot() {
568 // creates and returns a pointer to a hitmap histo (equipment opened up)
569 // physical representation of the half stave hitmap.
571 if (fPhysObj==NULL) {
572 Error("AliITSOnlineSPDphysAnalyzer::GetPhysicalHitMapTot","No data!");
575 TString histoname = Form("Eq %d",GetEqNr());
576 TH2F* hPhysicalHitMapTot = new TH2F(histoname.Data(),histoname.Data(),32*10,-0.5,32*10-0.5,256*6,-0.5,256*6-0.5);
577 hPhysicalHitMapTot->SetNdivisions(-10,"X");
578 hPhysicalHitMapTot->SetNdivisions(-006,"Y");
579 hPhysicalHitMapTot->SetTickLength(0,"X");
580 hPhysicalHitMapTot->SetTickLength(0,"Y");
581 hPhysicalHitMapTot->GetXaxis()->SetLabelColor(gStyle->GetCanvasColor());
582 hPhysicalHitMapTot->GetYaxis()->SetLabelColor(gStyle->GetCanvasColor());
583 Int_t correctChip=-1;
584 for (UInt_t hs=0; hs<6; hs++) {
585 for (UInt_t chipNr=0; chipNr<10; chipNr++) {
586 if(GetEqNr()<10) correctChip=9-chipNr;
587 else correctChip=chipNr;
588 for (UInt_t col=0; col<32; col++) {
589 for (UInt_t row=0; row<256; row++) {
590 if(hs>1) hPhysicalHitMapTot->Fill(correctChip*32+(31-col),(5-hs)*256+row,fPhysObj->GetHits(hs,chipNr,col,row));
591 else hPhysicalHitMapTot->Fill(correctChip*32+col,(5-hs)*256+row,fPhysObj->GetHits(hs,chipNr,col,row));
596 return hPhysicalHitMapTot;
598 //_____________________________________________________________________________________________________
599 TH2F* AliITSOnlineSPDphysAnalyzer::GetHitMapTot() {
600 // creates and returns a pointer to a hitmap histo (half sector style a la spdmood)
601 // This histogram shown the read out numbering pattern, it is not the physical one.
602 if (fPhysObj==NULL) {
603 Error("AliITSOnlineSPDphysAnalyzer::GetHitMapTot","No data!");
606 TString histoname = Form("Eq %d",GetEqNr());
607 TH2F* fHitMapTot = new TH2F(histoname.Data(),histoname.Data(),32*10,-0.5,32*10-0.5,256*6,-0.5,256*6-0.5);
608 fHitMapTot->SetNdivisions(-10,"X");
609 fHitMapTot->SetNdivisions(-006,"Y");
610 fHitMapTot->SetTickLength(0,"X");
611 fHitMapTot->SetTickLength(0,"Y");
612 fHitMapTot->GetXaxis()->SetLabelColor(gStyle->GetCanvasColor());
613 fHitMapTot->GetYaxis()->SetLabelColor(gStyle->GetCanvasColor());
614 for (UInt_t hs=0; hs<6; hs++) {
615 for (UInt_t chipNr=0; chipNr<10; chipNr++) {
616 for (UInt_t col=0; col<32; col++) {
617 for (UInt_t row=0; row<256; row++) {
618 fHitMapTot->Fill(chipNr*32+col,(5-hs)*256+row,fPhysObj->GetHits(hs,chipNr,col,row));
625 //________________________________________________________________________________________________________
626 TH2F* AliITSOnlineSPDphysAnalyzer::GetHitMapChip(UInt_t hs, UInt_t chip) {
627 // creates and returns a pointer to a hitmap histo (chip style a la spdmood)
628 if (fPhysObj==NULL) {
629 Error("AliITSOnlineSPDphysAnalyzer::GetHitMapChip","No data!");
635 histoName = Form("fChipHisto_%d_%d_%d", GetEqNr(), hs, chip);
636 histoTitle = Form("Eq ID %d, Half Stave %d, Chip %d", GetEqNr(), hs, chip);
638 TH2F *returnHisto = new TH2F(histoName.Data(), histoTitle.Data(), 32, -0.5, 31.5, 256, -0.5, 255.5);
639 returnHisto->SetMinimum(0);
640 for (UInt_t col=0; col<32; col++) {
641 for (UInt_t row=0; row<256; row++) {
642 if(hs<2) returnHisto->Fill(31-col,row,fPhysObj->GetHits(hs,chip,col,row));
643 else returnHisto->Fill(col,row,fPhysObj->GetHits(hs,chip,col,row));