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