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