]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSOnlineSPDscanAnalyzer.cxx
ITSSPDPHYSda: New detector algorithm for finding dead and noisy pixels.
[u/mrichter/AliRoot.git] / ITS / AliITSOnlineSPDscanAnalyzer.cxx
1 /**************************************************************************
2  * Copyright(c) 2007-2009, 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 /* $Id$ */
17
18 ////////////////////////////////////////////////////////////
19 // Author: Henrik Tydesjo                                 //
20 // This class is used in the detector algorithm framework //
21 // to process the data stored in special container files  //
22 // (see AliITSOnlineSPDscan). For instance, minimum       //
23 // threshold values can be extracted.                     //
24 ////////////////////////////////////////////////////////////
25
26 #include "AliITSOnlineSPDscanAnalyzer.h"
27 #include "AliITSOnlineSPDscan.h"
28 #include "AliITSOnlineSPDscanSingle.h"
29 #include "AliITSOnlineSPDscanMultiple.h"
30 #include "AliITSOnlineSPDscanMeanTh.h"
31 #include "AliITSOnlineCalibrationSPDhandler.h"
32 #include "AliITSRawStreamSPD.h"
33 #include <TStyle.h>
34 #include <TMath.h>
35 #include <TF1.h>
36 #include <TGraph.h>
37 #include <TH2F.h>
38 #include <TError.h>
39 #include <iostream>
40 #include <fstream>
41
42 Double_t itsSpdErrorf(Double_t *x, Double_t *par){
43   if (par[2]<0) par[2]=0;
44   Double_t val = par[2]+(0.12*256*32-par[2])*(0.5+0.5*TMath::Erf((x[0]-par[0])/par[1]/sqrt(2.)));
45   return val;
46 }
47 //Double_t itsSpdErrorfOrig(Double_t *x, Double_t *par){
48 //  return 0.5+0.5*TMath::Erf((x[0]-par[0])/par[1]/sqrt(2.));
49 //}
50
51
52 AliITSOnlineSPDscanAnalyzer::AliITSOnlineSPDscanAnalyzer(const Char_t *fileName, AliITSOnlineCalibrationSPDhandler *handler) :
53   fType(99),fDacId(99),fFileName(fileName),fScanObj(NULL),fHandler(handler),fTriggers(NULL),
54   fOverWrite(kFALSE),fNoiseThreshold(0.01),fNoiseMinimumEvents(100),
55   fMinNrStepsBeforeIncrease(5),fMinIncreaseFromBaseLine(2),fStepDownDacSafe(5),fMaxBaseLineLevel(10)
56 {
57   // constructor
58   for (UInt_t chipNr=0; chipNr<11; chipNr++) {
59     for (UInt_t hs=0; hs<6; hs++) {
60       fMeanMultiplicity[hs][chipNr]=NULL;
61       fHitEventEfficiency[hs][chipNr]=NULL;
62     }
63   }
64   for (UInt_t mod=0; mod<240; mod++) {
65     fbModuleScanned[mod]=kFALSE;
66   }
67
68   Init();
69 }
70
71 AliITSOnlineSPDscanAnalyzer::AliITSOnlineSPDscanAnalyzer(const AliITSOnlineSPDscanAnalyzer& handle) :
72   fType(99),fDacId(99),fFileName("."),fScanObj(NULL),fHandler(NULL),fTriggers(NULL),
73   fOverWrite(kFALSE),fNoiseThreshold(0.01),fNoiseMinimumEvents(100),
74   fMinNrStepsBeforeIncrease(5),fMinIncreaseFromBaseLine(2),fStepDownDacSafe(5),fMaxBaseLineLevel(10)
75 {
76   // copy constructor, only copies the filename and params (not the processed data)
77   fFileName=handle.fFileName;
78   fOverWrite=handle.fOverWrite;
79   fNoiseThreshold=handle.fNoiseThreshold;
80   fNoiseMinimumEvents=handle.fNoiseMinimumEvents;
81   fMinNrStepsBeforeIncrease=handle.fMinNrStepsBeforeIncrease;
82   fMinIncreaseFromBaseLine=handle.fMinIncreaseFromBaseLine;
83   fStepDownDacSafe=handle.fStepDownDacSafe;
84   fMaxBaseLineLevel=handle.fMaxBaseLineLevel;
85
86   for (UInt_t chipNr=0; chipNr<11; chipNr++) {
87     for (UInt_t hs=0; hs<6; hs++) {
88       fMeanMultiplicity[hs][chipNr]=NULL;
89       fHitEventEfficiency[hs][chipNr]=NULL;
90     }
91   }
92   for (UInt_t mod=0; mod<240; mod++) {
93     fbModuleScanned[mod]=kFALSE;
94   }
95
96   Init();
97 }
98
99 AliITSOnlineSPDscanAnalyzer::~AliITSOnlineSPDscanAnalyzer() {
100   // destructor
101   for (UInt_t hs=0; hs<6; hs++) {
102     for (UInt_t chipNr=0; chipNr<11; chipNr++) {
103       if (fMeanMultiplicity[hs][chipNr]!=NULL) {
104         delete fMeanMultiplicity[hs][chipNr];
105       }
106       if (fHitEventEfficiency[hs][chipNr]!=NULL) {
107         delete fHitEventEfficiency[hs][chipNr];
108       }
109     }
110   }
111   if (fTriggers!=NULL) delete fTriggers;
112   if (fScanObj!=NULL) delete fScanObj;
113 }
114
115 AliITSOnlineSPDscanAnalyzer& AliITSOnlineSPDscanAnalyzer::operator=(const AliITSOnlineSPDscanAnalyzer& handle) {
116   // assignment operator, only copies the filename and params (not the processed data)
117   if (this!=&handle) {
118     for (UInt_t hs=0; hs<6; hs++) {
119       for (UInt_t chipNr=0; chipNr<11; chipNr++) {
120         if (fMeanMultiplicity[hs][chipNr]!=NULL) {
121           delete fMeanMultiplicity[hs][chipNr];
122         }
123         if (fHitEventEfficiency[hs][chipNr]!=NULL) {
124           delete fHitEventEfficiency[hs][chipNr];
125         }
126       }
127     }
128     if (fTriggers!=NULL) delete fTriggers;
129     if (fScanObj!=NULL) delete fScanObj;
130    
131     fFileName=handle.fFileName;
132     fOverWrite=handle.fOverWrite;
133     fNoiseThreshold=handle.fNoiseThreshold;
134     fNoiseMinimumEvents=handle.fNoiseMinimumEvents;
135     fMinNrStepsBeforeIncrease=handle.fMinNrStepsBeforeIncrease;
136     fMinIncreaseFromBaseLine=handle.fMinIncreaseFromBaseLine;
137     fStepDownDacSafe=handle.fStepDownDacSafe;
138     fMaxBaseLineLevel=handle.fMaxBaseLineLevel;
139
140     for (UInt_t chipNr=0; chipNr<11; chipNr++) {
141       for (UInt_t hs=0; hs<6; hs++) {
142         fMeanMultiplicity[hs][chipNr]=NULL;
143         fHitEventEfficiency[hs][chipNr]=NULL;
144       }
145     }
146     for (UInt_t mod=0; mod<240; mod++) {
147       fbModuleScanned[mod]=kFALSE;
148     }
149     fTriggers=NULL;
150     fHandler=NULL;
151     
152     fScanObj=NULL;
153     fType=99;
154     fDacId=99;
155
156     Init();    
157   }
158   return *this;
159 }
160
161 void AliITSOnlineSPDscanAnalyzer::Init() {
162   // first checks type of container and then initializes container obj
163   FILE* fp0 = fopen(fFileName.Data(), "r");
164   if (fp0 == NULL) {
165     return;
166   }
167   else {
168     fclose(fp0);
169   }
170   fScanObj = new AliITSOnlineSPDscan(fFileName.Data());
171   fType = fScanObj->GetType();
172   delete fScanObj;
173
174   // init container
175   switch(fType) {
176   case kUNIMA:
177   case kNOISE:
178     fScanObj = new AliITSOnlineSPDscanSingle(fFileName.Data());
179     break;
180   case kMINTH:
181   case kDAC:
182   case kDELAY:
183     fScanObj = new AliITSOnlineSPDscanMultiple(fFileName.Data());
184     fDacId = ((AliITSOnlineSPDscanMultiple*)fScanObj)->GetDacId();
185     break;
186   case kMEANTH:
187     fScanObj = new AliITSOnlineSPDscanMeanTh(fFileName.Data());
188     fDacId = ((AliITSOnlineSPDscanMeanTh*)fScanObj)->GetDacId();
189     break;
190   default:
191     Error("AliITSOnlineSPDscanAnalyzer::Init","Type %d not defined!",fType);
192     fScanObj=NULL;
193     return;
194     break;
195   }
196
197 }
198
199 void AliITSOnlineSPDscanAnalyzer::SetParam(const Char_t *pname, const Char_t *pval) {
200   // set a parameter
201   TString name = pname;
202   TString val = pval;
203   if (name.CompareTo("fOverWrite")==0) {
204     if (val.CompareTo("YES")==0 || val.CompareTo("1")==0) {
205       fOverWrite = kTRUE;
206     }
207     else fOverWrite = kFALSE;
208   }
209   else if (name.CompareTo("fNoiseThreshold")==0) {
210     fNoiseThreshold = val.Atof();
211   }
212   else if (name.CompareTo("fNoiseMinimumEvents")==0) {
213     fNoiseMinimumEvents = val.Atoi();
214   }
215   else if (name.CompareTo("fMinNrStepsBeforeIncrease")==0) {
216     fMinNrStepsBeforeIncrease = val.Atoi();
217   }
218   else if (name.CompareTo("fMinIncreaseFromBaseLine")==0) {
219     fMinIncreaseFromBaseLine = val.Atof();
220   }
221   else if (name.CompareTo("fStepDownDacSafe")==0) {
222     fStepDownDacSafe = val.Atoi();
223   }
224   else if (name.CompareTo("fMaxBaseLineLevel")==0) {
225     fMaxBaseLineLevel = val.Atof();
226   }
227   else {
228     Error("AliITSOnlineSPDscanAnalyzer::SetParam","Parameter %s in configuration file unknown.",name.Data());
229   }
230 }
231
232 void AliITSOnlineSPDscanAnalyzer::ReadParamsFromLocation(const Char_t *dirName) {
233   // opens file (default name) in dir dirName and reads parameters from it
234   TString paramsFileName = Form("%s/standal_params.txt",dirName);
235   ifstream paramsFile;
236   paramsFile.open(paramsFileName, ifstream::in);
237   if (paramsFile.fail()) {
238     printf("No config file (%s) present. Using default tuning parameters.\n",paramsFileName.Data());
239   }
240   else {
241     while(1) {
242       Char_t paramN[50];
243       Char_t paramV[50];
244       paramsFile >> paramN;
245       if (paramsFile.eof()) break;
246       paramsFile >> paramV;
247       SetParam(paramN,paramV);
248       if (paramsFile.eof()) break;
249     }
250     paramsFile.close();
251   }
252 }
253
254 Bool_t AliITSOnlineSPDscanAnalyzer::IsModuleScanned(UInt_t module) const {
255   // is this module scanned?
256   if (module<240) {
257     return fbModuleScanned[module];
258   }
259   return kFALSE;
260 }
261
262 Bool_t AliITSOnlineSPDscanAnalyzer::ProcessDeadPixels(/*Char_t *oldcalibDir*/) {
263   // process dead pixel data, for uniformity scan, 
264   // NB: This will not be the general way of finding dead pixels.
265   if (fScanObj==NULL) {
266     Warning("AliITSOnlineSPDscanAnalyzer::ProcessDeadPixels","No data!");
267     return kFALSE;
268   }
269   // should be type kUNIMA
270   if (fType!=kUNIMA) {
271     Warning("AliITSOnlineSPDscanAnalyzer::ProcessDeadPixels","Dead pixels only for scan type %d.",kUNIMA);
272     return kFALSE;
273   }
274   // handler should be initialized
275   if (fHandler==NULL) {
276     Error("AliITSOnlineSPDscanAnalyzer::ProcessDeadPixels","Calibration handler is not initialized!");
277     return kFALSE;
278   }
279
280   UInt_t routerNr = fScanObj->GetRouterNr();
281   UInt_t rowStart = fScanObj->GetRowStart();
282   UInt_t rowEnd   = fScanObj->GetRowEnd();
283   for (UInt_t hs=0; hs<6; hs++) {
284     for (UInt_t chipNr=0; chipNr<10; chipNr++) {
285       if (fScanObj->GetChipPresent(hs,chipNr) && fScanObj->GetAverageMultiplicity(0,hs,chipNr)>0) { // check the status of the chippresent parameter in the mood header!!!!!!!!!!!!!!!!!!!!!!!!!!!!
286         UInt_t module = AliITSRawStreamSPD::GetModuleNumber(routerNr,hs,chipNr);
287         if (!fbModuleScanned[module]) {
288           fbModuleScanned[module]=kTRUE;
289           //      fHandler[module]->SetFileLocation(oldcalibDir);
290           //      fHandler[module]->ReadFromFile(module);
291           if (fOverWrite) {fHandler->ResetDeadForChip(routerNr,hs,chipNr);}
292         }
293         for (UInt_t col=0; col<32; col++) {
294           for (UInt_t row=rowStart; row<=rowEnd; row++) {
295             if (col!=1 && col!=9 && col!=17 && col!=25) { //exclude test columns!!!
296               if (fScanObj->GetHits(0,hs,chipNr,col,row)==0) {
297                 fHandler->SetDeadPixel(routerNr,hs,chipNr,col,row);
298               }
299             }
300           }
301         }
302       }
303     }
304   }
305   return kTRUE;
306 }
307
308
309
310 Bool_t AliITSOnlineSPDscanAnalyzer::ProcessNoisyPixels(/*Char_t *oldcalibDir*/) {
311   // process noisy pixel data
312   if (fScanObj==NULL) {
313     Warning("AliITSOnlineSPDscanAnalyzer::ProcessNoisyPixels","No data!");
314     return kFALSE;
315   }
316   // should be type kNOISE
317   if (fType != kNOISE) {
318     Warning("AliITSOnlineSPDscanAnalyzer::ProcessNoisyPixels","Noisy pixels only for scan type %d.",kNOISE);
319     return kFALSE;
320   }
321   // handler should be initialized
322   if (fHandler==NULL) {
323     Error("AliITSOnlineSPDscanAnalyzer::ProcessNoisyPixels","Calibration handler is not initialized!");
324     return kFALSE;
325   }
326   // check if enough statistics
327   if (fScanObj->GetTriggers(0)<fNoiseMinimumEvents) {
328     Warning("AliITSOnlineSPDscanAnalyzer::ProcessNoisyPixels","Process noisy: Too few events.");
329     return kFALSE;
330   }
331
332   UInt_t routerNr = fScanObj->GetRouterNr();
333   for (UInt_t hs=0; hs<6; hs++) {
334     for (UInt_t chipNr=0; chipNr<10; chipNr++) {
335       if (fScanObj->GetChipPresent(hs,chipNr)) { // check the status of the chippresent parameter in the mood header!!!!!!!!!!!!!!!!!!!!!!!!!!!!
336         UInt_t module = AliITSRawStreamSPD::GetModuleNumber(routerNr,hs,chipNr);
337         if (!fbModuleScanned[module]) {
338           fbModuleScanned[module]=kTRUE;
339           if (fOverWrite) {fHandler->ResetNoisyForChip(routerNr,hs,chipNr);}
340         }
341         for (UInt_t col=0; col<32; col++) {
342           for (UInt_t row=0; row<256; row++) {
343             if (fScanObj->GetHitsEfficiency(0,hs,chipNr,col,row)>fNoiseThreshold) {
344               fHandler->SetNoisyPixel(routerNr,hs,chipNr,col,row);
345             }
346           }
347         }
348       }
349     }
350   }
351   return kTRUE;
352 }
353
354 Int_t AliITSOnlineSPDscanAnalyzer::GetDelay(UInt_t hs, UInt_t chipNr) {
355   // get delay
356   if (hs>=6 || chipNr>10) return -1;
357   if (fScanObj==NULL) {
358     Warning("AliITSOnlineSPDscanAnalyzer::GetDelay","No data!");
359     return -1;
360   }
361   // should be type kDELAY or kDAC with id 42 (delay_ctrl)
362   if (fType!=kDELAY && (fType!=kDAC || fDacId!=42)) {
363     Warning("AliITSOnlineSPDscanAnalyzer::GetDelay","Delay only for scan type %d or %d and dac_id 42.",kDELAY,kDAC);
364     return -1;
365   }
366   if (fMeanMultiplicity[hs][chipNr]==NULL) {
367     if (!ProcessMeanMultiplicity()) {
368       return -1;
369     }
370   }
371
372   UInt_t maxStep=0;
373   Float_t maxVal=0;
374   for (UInt_t step=0; step<fScanObj->GetNSteps(); step++) {
375     Double_t thisDac;
376     Double_t thisMult;
377     fMeanMultiplicity[hs][chipNr]->GetPoint(step,thisDac,thisMult);
378     if (thisMult > maxVal) {
379       maxVal = thisMult;
380       maxStep = step;
381     }
382   }
383
384   if (maxVal>0) {
385     return ((AliITSOnlineSPDscanMultiple*)fScanObj)->GetDacValue(maxStep);
386   }
387   else {
388     return -1;
389   }
390
391 }
392
393
394 Int_t AliITSOnlineSPDscanAnalyzer::GetNrNoisyUnima(UInt_t hs, UInt_t chipNr) {
395   // in case of a uniformity scan, returns the nr of noisy pixels, (here > 200 hits)
396   if (hs>=6 || chipNr>10) return -1;
397   if (fScanObj==NULL) {
398     Error("AliITSOnlineSPDscanAnalyzer::GetNrNoisyUnima","No data!");
399     return kFALSE;
400   }
401   // should be type kUNIMA
402   if (fType != kUNIMA) {
403     Error("AliITSOnlineSPDscanAnalyzer::GetNrNoisyUnima","Noisy pixels Unima only for scan type %d.",kUNIMA);
404     return kFALSE;
405   }
406   if (fScanObj->GetTriggers(0)!=25600) {
407     Error("AliITSOnlineSPDscanAnalyzer::GetNrNoisyUnima","Process noisy unima: Incorrect number of events (!=25600.");
408     return kFALSE;
409   }
410
411   Int_t nrNoisy=0;
412   if (fScanObj->GetChipPresent(hs,chipNr)) { // check the status of the chippresent parameter in the mood header!!!!!!!!!!!!!!!!!!!!!!!!!!!!
413     for (UInt_t col=0; col<32; col++) {
414       for (UInt_t row=0; row<256; row++) {
415         if (fScanObj->GetHits(0,hs,chipNr,col,row)>200) {
416           nrNoisy++;
417         }
418       }
419     }
420   }
421   else {
422     return -1;
423   }
424   return nrNoisy;
425 }
426
427 Int_t AliITSOnlineSPDscanAnalyzer::FindLastMinThDac(UInt_t hs, UInt_t chipNr) {
428   // returns dac value where fMinIncreaseFromBaseLine reached
429   if (hs>=6 || chipNr>10) return -1;
430   if (fMeanMultiplicity[hs][chipNr]==NULL) {
431     if (!ProcessMeanMultiplicity()) {
432       return -1;
433     }
434   }
435   Double_t firstVal, dummy1;
436   fMeanMultiplicity[hs][chipNr]->GetPoint(0,dummy1,firstVal);
437   UInt_t step=0;
438   while (step<fScanObj->GetNSteps()-1) {
439     Double_t graphVal, dummy2;
440     fMeanMultiplicity[hs][chipNr]->GetPoint(step+1,dummy2,graphVal);
441     if (graphVal>firstVal+fMinIncreaseFromBaseLine) break;
442     step++;
443   }
444   if (step==fScanObj->GetNSteps()-1) return -1;
445   return ((AliITSOnlineSPDscanMultiple*)fScanObj)->GetDacValue(step);
446 }
447
448 Int_t AliITSOnlineSPDscanAnalyzer::FindClosestLowerStep(Float_t dacValueInput) {
449   // returns step closest (lower) to a dacvalue 
450   UInt_t step=0;
451   while (step<fScanObj->GetNSteps()-1) {
452     Int_t dacVal = ((AliITSOnlineSPDscanMultiple*)fScanObj)->GetDacValue(step+1);
453     if (dacVal>=dacValueInput) break;
454     step++;
455   }
456   return step;
457 }
458
459 Float_t AliITSOnlineSPDscanAnalyzer::GetCompareLine(UInt_t step, UInt_t hs, UInt_t chipNr, Float_t basePar2) {
460   // returns value to compare mean mult with (when finding min th)
461   if (hs>=6 || chipNr>10) return -1;
462   if (step<fMinNrStepsBeforeIncrease) return -1;
463   Float_t baseLine = basePar2;
464   if (baseLine<0) baseLine=0;
465   Float_t baseAdd;
466   Double_t baseM=0;
467   Double_t baseS=0;
468   Double_t d,m;
469   for (UInt_t st=1;st<2*step/3;st++) { // skip first point...
470     fMeanMultiplicity[hs][chipNr]->GetPoint(st,d,m);
471     baseM+=m-baseLine;
472     baseS+=(m-baseLine)*(m-baseLine);
473   }
474   baseAdd=2*sqrt( baseS/(2*step/3-1) - (baseM/(2*step/3-1))*(baseM/(2*step/3-1)) );
475   baseAdd+=0.03; // magic number
476   if (baseAdd>fMinIncreaseFromBaseLine) baseAdd=fMinIncreaseFromBaseLine;
477   return baseLine + baseAdd;
478 }
479
480 Int_t AliITSOnlineSPDscanAnalyzer::GetMinTh(UInt_t hs, UInt_t chipNr) {
481   // calculates and returns the minimum threshold
482   if (hs>=6 || chipNr>10) return -1;
483   if (fScanObj==NULL) {
484     Error("AliITSOnlineSPDscanAnalyzer::GetMinTh","No data!");
485     return -1;
486   }
487   // should be type  kMINTH  or  kDAC with id 39 (pre_vth)
488   if (fType!=kMINTH && (fType!=kDAC || fDacId!=39)) {
489     Error("AliITSOnlineSPDscanAnalyzer::GetMinTh","MinTh only for scan type %d OR %d with dac_id 39.",kMINTH,kDAC);
490     return -1;
491   }
492   if (fMeanMultiplicity[hs][chipNr]==NULL) {
493     if (!ProcessMeanMultiplicity()) {
494       return -1;
495     }
496   }
497
498   Int_t lastDac = FindLastMinThDac(hs,chipNr);
499   if (lastDac==-1) {
500     Warning("AliITSOnlineSPDscanAnalyzer::GetMinTh","HS%d, Chip%d: Increase of Mean Multiplicity by %1.2f never reached.",hs,chipNr,fMinIncreaseFromBaseLine);
501     return -1;
502   }
503
504   Int_t minDac = ((AliITSOnlineSPDscanMultiple*)fScanObj)->GetDacValue(0);
505   TString funcName = Form("Fit minth func HS%d CHIP%d",hs,chipNr);
506   TF1 *minThFunc = new TF1(funcName.Data(),itsSpdErrorf,100,500,3);
507   minThFunc->SetParameter(0,lastDac+10);
508   minThFunc->SetParameter(1,2);
509   minThFunc->SetParameter(2,0);
510   minThFunc->SetParName(0,"Mean");
511   minThFunc->SetParName(1,"Sigma");
512   minThFunc->SetParName(2,"BaseLine");
513   minThFunc->SetLineWidth(1);
514   if (fMeanMultiplicity[hs][chipNr]==NULL) {
515     if (!ProcessMeanMultiplicity()) {
516       return -1;
517     }
518   }
519   fMeanMultiplicity[hs][chipNr]->Fit(funcName,"Q0","",minDac,lastDac);
520
521   //  Double_t mean = fMinThFunc[hs][chipNr]->GetParameter(0);
522   //  Double_t sigma = fMinThFunc[hs][chipNr]->GetParameter(1);
523   Double_t baseLine = minThFunc->GetParameter(2);
524   delete minThFunc;
525
526   if (baseLine>fMaxBaseLineLevel) {
527     Warning("AliITSOnlineSPDscanAnalyzer::GetMinTh","HS%d, Chip%d: BaseLine too large (%1.2f>%1.2f).",hs,chipNr,baseLine,fMaxBaseLineLevel);
528     return -1;
529   }
530   UInt_t step=FindClosestLowerStep(lastDac);
531   Float_t compareLine = GetCompareLine(step,hs,chipNr,baseLine);
532   if (compareLine==-1) {
533     Warning("AliITSOnlineSPDscanAnalyzer::GetMinTh","HS%d, Chip%d: Not enough steps (%d<%d) before increase to get a compare line.",hs,chipNr,step,fMinNrStepsBeforeIncrease);
534     return -1;
535   }
536
537   Double_t mult, dummy;
538   mult=1000;
539   while (mult > compareLine && step>0) {
540     fMeanMultiplicity[hs][chipNr]->GetPoint(step,dummy,mult);
541     step--;
542   }
543   Int_t minth = ((AliITSOnlineSPDscanMultiple*)fScanObj)->GetDacValue(step+1)-fStepDownDacSafe;
544
545   if (step>0) {
546     return minth;
547   }
548   else {
549     Warning("AliITSOnlineSPDscanAnalyzer::GetMinTh","HS%d, Chip%d: Did not find a point below the compare line (%f).",hs,chipNr,compareLine);
550     return -1;
551   }
552 }
553
554
555
556 Bool_t AliITSOnlineSPDscanAnalyzer::ProcessMeanMultiplicity() {
557   // process mean multiplicity data
558   if (fScanObj==NULL) {
559     Error("AliITSOnlineSPDscanAnalyzer::ProcessMeanMultiplicity","No data!");
560     return kFALSE;
561   }
562   for (UInt_t step=0; step<fScanObj->GetNSteps(); step++) {
563     for (UInt_t hs=0; hs<6; hs++) {
564       for (UInt_t chipNr=0; chipNr<11; chipNr++) {
565         //      if (fScanObj->GetChipPresent(hs,chipNr)) { // check the status of the chippresent parameter in the mood header!!!!!!!!!!!!!!!!!!!!!!!!!!!!
566         if (step==0) {
567           if (fMeanMultiplicity[hs][chipNr]!=NULL) {
568             delete fMeanMultiplicity[hs][chipNr];
569           }
570           fMeanMultiplicity[hs][chipNr] = new TGraph();
571         }
572         Float_t multiplMean=fScanObj->GetAverageMultiplicity(step,hs,chipNr);
573         if (fType==kMINTH || fType==kMEANTH || fType==kDAC || fType==kDELAY) {
574           fMeanMultiplicity[hs][chipNr]->SetPoint(step,((AliITSOnlineSPDscanMultiple*)fScanObj)->GetDacValue(step),multiplMean);
575         }
576         else {
577           fMeanMultiplicity[hs][chipNr]->SetPoint(step,0,multiplMean);
578         }
579       }
580       //      }
581     }
582   }
583   return kTRUE;
584 }
585
586 TGraph* AliITSOnlineSPDscanAnalyzer::GetMeanMultiplicityG(UInt_t hs, UInt_t chipNr) {
587   // returns mean multiplicity graph
588   if (hs>=6 || chipNr>10) return NULL;
589   if (fMeanMultiplicity[hs][chipNr]==NULL) {
590     if (!ProcessMeanMultiplicity()) {
591       return NULL;
592     }
593   }
594   return fMeanMultiplicity[hs][chipNr];
595 }
596
597 Bool_t AliITSOnlineSPDscanAnalyzer::ProcessHitEventEfficiency() {
598   // process hit event efficiency
599   if (fScanObj==NULL) {
600     Error("AliITSOnlineSPDscanAnalyzer::ProcessHitEventEfficiency","No data!");
601     return kFALSE;
602   }
603   for (UInt_t step=0; step<fScanObj->GetNSteps(); step++) {
604     for (UInt_t hs=0; hs<6; hs++) {
605       for (UInt_t chipNr=0; chipNr<11; chipNr++) {
606         //      if (fScanObj->GetChipPresent(hs,chipNr)) { // check the status of the chippresent parameter in the mood header!!!!!!!!!!!!!!!!!!!!!!!!!!!!
607         if (step==0) {
608           if (fHitEventEfficiency[hs][chipNr]!=NULL) {
609             delete fHitEventEfficiency[hs][chipNr];
610           }
611           fHitEventEfficiency[hs][chipNr] = new TGraph();
612         }
613         Float_t efficiency=fScanObj->GetHitEventsEfficiency(step,hs,chipNr);
614         if (fType==kMINTH || fType==kMEANTH || fType==kDAC || fType==kDELAY) {
615           fHitEventEfficiency[hs][chipNr]->SetPoint(step,((AliITSOnlineSPDscanMultiple*)fScanObj)->GetDacValue(step),efficiency);
616         }
617         else {
618           fHitEventEfficiency[hs][chipNr]->SetPoint(step,0,efficiency);
619         }
620       }
621       //      }
622     }
623   }
624   return kTRUE;
625 }
626
627 TGraph* AliITSOnlineSPDscanAnalyzer::GetHitEventEfficiencyG(UInt_t hs, UInt_t chipNr) {
628   // returns hit event efficiency graph
629   if (hs>=6 || chipNr>10) return NULL;
630   if (fHitEventEfficiency[hs][chipNr]==NULL) {
631     if (!ProcessHitEventEfficiency()) {
632       return NULL;
633     }
634   }
635   return fHitEventEfficiency[hs][chipNr];
636 }
637
638
639 Bool_t AliITSOnlineSPDscanAnalyzer::ProcessNrTriggers() {
640   // process nr of triggers data
641   if (fScanObj==NULL) {
642     Error("AliITSOnlineSPDscanAnalyzer::ProcessNrTriggers","No data!");
643     return kFALSE;
644   }
645   for (UInt_t step=0; step<fScanObj->GetNSteps(); step++) {
646     if (step==0) {
647       if (fTriggers!=NULL) {
648         delete fTriggers;
649       }
650       fTriggers = new TGraph();
651     }
652     if (fType==kMINTH || fType==kMEANTH || fType==kDAC || fType==kDELAY) {
653       fTriggers->SetPoint(step,((AliITSOnlineSPDscanMultiple*)fScanObj)->GetDacValue(step),fScanObj->GetTriggers(step));
654     }
655     else {
656       fTriggers->SetPoint(step,0,fScanObj->GetTriggers(step));
657     }
658   }
659   return kTRUE;
660 }
661
662 TGraph* AliITSOnlineSPDscanAnalyzer::GetNrTriggersG() {
663   // returns nr of triggers graph
664   if (fTriggers==NULL) {
665     if (!ProcessNrTriggers()) {
666       return NULL;
667     }
668   }
669   return fTriggers;
670 }
671
672 Bool_t AliITSOnlineSPDscanAnalyzer::GetHalfStavePresent(UInt_t hs) {
673   // returns half stave present info
674   if (hs<6 && fScanObj!=NULL) {
675     Int_t chipstatus=0;
676     for (Int_t chip=0; chip<10; chip++) {
677       chipstatus+=fScanObj->GetChipPresent(hs,chip);
678     }
679     if (chipstatus>0) return kTRUE;
680   }
681   return kFALSE;
682 }
683
684 UInt_t AliITSOnlineSPDscanAnalyzer::GetRouterNr() {
685   // returns the router nr of scan obj
686   if (fScanObj!=NULL) return fScanObj->GetRouterNr(); 
687   else return 99;
688 }
689
690 TH2F* AliITSOnlineSPDscanAnalyzer::GetHitMapTot(UInt_t step) {
691   // creates and returns a pointer to a hitmap histo (half sector style a la spdmood)
692   if (fScanObj==NULL) {
693     Error("AliITSOnlineSPDscanAnalyzer::GetHitMapTot","No data!");
694     return NULL;
695   }
696   TString histoname;
697   if (fType==kMINTH || fType==kMEANTH || fType==kDAC) {
698     histoname = Form("Router %d , DAC %d",GetRouterNr(),((AliITSOnlineSPDscanMultiple*)fScanObj)->GetDacValue(step));
699   }
700   else {
701     histoname = Form("Router %d ",GetRouterNr());
702   }
703   TH2F* fHitMapTot = new TH2F(histoname.Data(),histoname.Data(),32*10,-0.5,32*10-0.5,256*6,-0.5,256*6-0.5);
704   fHitMapTot->SetNdivisions(-10,"X");
705   fHitMapTot->SetNdivisions(-006,"Y");
706   fHitMapTot->SetTickLength(0,"X");
707   fHitMapTot->SetTickLength(0,"Y");
708   fHitMapTot->GetXaxis()->SetLabelColor(gStyle->GetCanvasColor());
709   fHitMapTot->GetYaxis()->SetLabelColor(gStyle->GetCanvasColor());
710   for (UInt_t hs=0; hs<6; hs++) {
711     for (UInt_t chipNr=0; chipNr<10; chipNr++) {
712       for (UInt_t col=0; col<32; col++) {
713         for (UInt_t row=0; row<256; row++) {
714           fHitMapTot->Fill(chipNr*32+col,(5-hs)*256+row,fScanObj->GetHits(step,hs,chipNr,col,row));
715         }
716       }
717     }
718   }
719   return fHitMapTot;
720 }
721
722 TH2F* AliITSOnlineSPDscanAnalyzer::GetHitMapChip(UInt_t step, UInt_t hs, UInt_t chip) {
723   // creates and returns a pointer to a hitmap histo (chip style a la spdmood)
724   if (fScanObj==NULL) {
725     Error("AliITSOnlineSPDscanAnalyzer::GetHitMapChip","No data!");
726     return NULL;
727   }
728
729   TString histoName;
730   TString histoTitle;
731   histoName = Form("fChipHisto_%d_%d_%d", GetRouterNr(), hs, chip);
732   histoTitle = Form("Eq ID %d, Half Stave %d, Chip %d", GetRouterNr(), hs, chip);
733
734   TH2F *returnHisto = new TH2F(histoName.Data(), histoTitle.Data(), 32, -0.5, 31.5, 256, -0.5, 255.5);
735   returnHisto->SetMinimum(0);
736   for (UInt_t col=0; col<32; col++) {
737     for (UInt_t row=0; row<256; row++) {
738       returnHisto->Fill(col,row,fScanObj->GetHits(step,hs,chip,col,row));
739     }
740   }
741
742   return returnHisto;
743 }