fixed the tainted variables
[u/mrichter/AliRoot.git] / ITS / AliITSOnlineSPDphysAnalyzer.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 ////////////////////////////////////////////////////////////
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 ////////////////////////////////////////////////////////////
22
23 #include "AliITSOnlineSPDphysAnalyzer.h"
24 #include "AliITSOnlineSPDphys.h"
25 #include "AliITSOnlineCalibrationSPDhandler.h"
26 #include "AliITSRawStreamSPD.h"
27 #include "AliITSIntMap.h"
28 #include <TStyle.h>
29 #include <TMath.h>
30 #include <TF1.h>
31 #include <TGraph.h>
32 #include <TH2F.h>
33 #include <TError.h>
34 #include <iostream>
35 #include <fstream>
36
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)
45 {
46   // constructor  
47   Init(readFromGridFile);
48 }
49
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)
58 {
59   // alt constructor
60   fPhysObj = physObj;
61 }
62
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)
71 {
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;
81
82   Init();
83 }
84
85 AliITSOnlineSPDphysAnalyzer::~AliITSOnlineSPDphysAnalyzer() {
86   // destructor
87   if (fPhysObj!=NULL) delete fPhysObj;
88 }
89
90 AliITSOnlineSPDphysAnalyzer& AliITSOnlineSPDphysAnalyzer::operator=(const AliITSOnlineSPDphysAnalyzer& handle) {
91   // assignment operator, only copies the filename and params (not the processed data)
92   if (this!=&handle) {
93     if (fPhysObj!=NULL) delete fPhysObj;
94     
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;
103
104     fPhysObj = NULL;
105     fHandler = NULL;
106     fNrEnoughStatChips = 0;
107     fNrDeadChips = 0;
108     fNrInefficientChips = 0;
109     fNrEqHits = 0;
110     fbDeadProcessed = kFALSE;
111
112     Init();    
113   }
114   return *this;
115 }
116
117 void AliITSOnlineSPDphysAnalyzer::Init(Bool_t readFromGridFile) {
118   // initialize container obj
119   if (!readFromGridFile) {
120     FILE* fp0 = fopen(fFileName.Data(), "r");
121     if (fp0 == NULL) {
122       return;
123     }
124     else {
125       fclose(fp0);
126     }
127   }
128   fPhysObj = new AliITSOnlineSPDphys(fFileName.Data(), readFromGridFile);
129 }
130
131 void AliITSOnlineSPDphysAnalyzer::SetParam(const Char_t *pname, const Char_t *pval) {
132   // set a parameter
133   TString name = pname;
134   TString val = pval;
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);
139   }
140   else if (name.CompareTo("MistakeProbabilityDead")==0) {
141     Double_t mistakeProbabilityDead = val.Atof();
142     fThreshDead = mistakeProbabilityDead/(20*6*10*32*256);
143   }
144   else if (name.CompareTo("fMinEventsForNoisy")==0) {
145     fMinEventsForNoisy = val.Atoi();
146   }
147   else if (name.CompareTo("fMinEventsForDead")==0) {
148     fMinEventsForDead = val.Atoi();
149   }
150   else if (name.CompareTo("fDefinitelyNoisyRatio")==0) {
151     fDefinitelyNoisyRatio = val.Atof();
152   }
153   else if (name.CompareTo("fMinNrEqHitsForDeadChips")==0) {
154     fMinNrEqHitsForDeadChips = val.Atof();
155   }
156   else if (name.CompareTo("fRatioToMeanForInefficientChip")==0) {
157     fRatioToMeanForInefficientChip = val.Atof();
158   }
159   else {
160     Error("AliITSOnlineSPDphysAnalyzer::SetParam","Parameter %s in configuration file unknown.",name.Data());
161   }
162 }
163
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);
167   ifstream paramsFile;
168   paramsFile.open(paramsFileName, ifstream::in);
169   if (paramsFile.fail()) {
170     printf("No config file (%s) present. Using default tuning parameters.\n",paramsFileName.Data());
171   }
172   else {
173     while(1) {
174       Char_t paramN[50];
175       Char_t paramV[50];
176       paramsFile >> paramN;
177       if (paramsFile.eof()) break;
178       paramsFile >> paramV;
179       SetParam(paramN,paramV);
180       if (paramsFile.eof()) break;
181     }
182     paramsFile.close();
183   }
184 }
185
186
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!");
191     return 0;
192   }
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);
196     return 0;
197   }
198   // handler should be initialized
199   if (fHandler==NULL) {
200     Error("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","Calibration handler is not initialized!");
201     return 0;
202   }
203   
204   UInt_t nrEnoughStatChips = 0;
205
206   for (UInt_t hs=0; hs<6; hs++) {
207     for (UInt_t chip=0; chip<10; chip++) {
208
209       UInt_t nrPixels = 0;
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
217           nrPixels++;
218           if (nrHits>fDefinitelyNoisyRatio*GetNrEvents()) {
219             fHandler->SetNoisyPixel(GetEqNr(),hs,chip,col,row);
220             nrPixels--;
221             nrChipHits-=nrHits;
222           }
223           else {
224             if (nrMostHits<nrHits) nrMostHits=nrHits;
225           }
226         }
227       }
228
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) {
233
234           Double_t p = (Double_t)nrChipHits/nrPixels/n;
235
236           // Bin(n,k=0):
237           Double_t bin = pow((Double_t)(1-p),(Double_t)n);
238           // Bin(n,k)
239           UInt_t k=1;
240           while ((bin>fThreshNoisy || k<n*p) && k<=n) {
241             k++;
242             bin = bin*(n-k+1)/k*p/(1-p);
243           }
244           
245           // can we find noisy pixels...?
246           if (k<=n) {
247             //      printf("eq %d , hs %d , chip %d : Noisy level = %d\n",GetEqNr(),hs,chip,k);
248             nrEnoughStatChips++;
249             // add noisy pixels to handler
250             UInt_t noiseLimit=k;
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);
257                   }
258                 }
259               }
260             }
261           }
262         }
263
264       }
265
266     } // for chip
267   } // for hs
268
269   return nrEnoughStatChips;
270 }
271
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!");
276     return 0;
277   }
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);
281     return 0;
282   }
283   // handler should be initialized
284   if (fHandler==NULL) {
285     Error("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","Calibration handler is not initialized!");
286     return 0;
287   }
288   
289   UInt_t nrEnoughStatChips = 0;
290
291   for (UInt_t hs=0; hs<6; hs++) {
292     for (UInt_t chip=0; chip<10; chip++) {
293
294       UInt_t nrPixels = 0;
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
302           nrPixels++;
303           if (nrHits>fDefinitelyNoisyRatio*nrEvts) {
304             fHandler->SetNoisyPixel(eq,hs,chip,col,row);
305             nrPixels--;
306             nrChipHits-=nrHits;
307           }
308           else {
309             if (nrMostHits<nrHits) nrMostHits=nrHits;
310           }
311         }
312       }
313
314       if (nrChipHits>0) { // otherwise there are for sure no noisy
315         // Binomial with n events and probability p for pixel hit
316         UInt_t n = nrEvts;
317         if (nrPixels>0 && n>0) {
318
319           Double_t p = (Double_t)nrChipHits/nrPixels/n;
320
321           // Bin(n,k=0):
322           Double_t bin = pow((Double_t)(1-p),(Double_t)n);
323           // Bin(n,k)
324           UInt_t k=1;
325           while ((bin>fThreshNoisy || k<n*p) && k<=n) {
326             k++;
327             bin = bin*(n-k+1)/k*p/(1-p);
328           }
329           
330           // can we find noisy pixels...?
331           if (k<=n) {
332             //      printf("eq %d , hs %d , chip %d : Noisy level = %d\n",GetEqNr(),hs,chip,k);
333             nrEnoughStatChips++;
334             // add noisy pixels to handler
335             UInt_t noiseLimit=k;
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);
342                   }
343                 }
344               }
345             }
346           }
347         }
348
349       }
350
351     } // for chip
352   } // for hs
353
354   return nrEnoughStatChips;
355 }
356
357
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!");
362     return 0;
363   }
364
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);
368     return 0;
369   }
370   // handler should be initialized
371   if (fHandler==NULL) {
372     Error("AliITSOnlineSPDphysAnalyzer::ProcessDeadPixels","Calibration handler is not initialized!");
373     return 0;
374   }
375
376   AliITSIntMap* possiblyDead  = new AliITSIntMap();
377   AliITSIntMap* possiblyIneff = new AliITSIntMap();
378
379   fNrEnoughStatChips = 0;
380   fNrDeadChips = 0;
381   fNrInefficientChips = 0;
382   UInt_t nrPossiblyDeadChips = 0;
383   fNrEqHits = 0;
384
385
386   for (UInt_t hs=0; hs<6; hs++) {
387     if (!fHandler->IsActiveHS(GetEqNr(),hs)) {
388       fNrDeadChips+=10;
389     }
390     else {
391       for (UInt_t chip=0; chip<10; chip++) {
392         if (!fHandler->IsActiveChip(GetEqNr(),hs,chip)) {
393           fNrDeadChips++;
394         }
395         else {
396           // perform search for individual dead pixels...
397           Bool_t good=kFALSE;
398
399           UInt_t nrPossiblyDeadPixels = 0;
400           UInt_t nrPixels = 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
408                 nrPixels++;
409                 if (nrHits==0) {
410                   nrPossiblyDeadPixels++;
411                 }
412                 else {
413                   fHandler->UnSetDeadPixel(GetEqNr(),hs,chip,col,row); // unset (no action unless dead before)
414                 }
415               }
416               else {
417                 nrChipHits -= nrHits; // this is needed when running offline (online nrHits should be 0 already)
418               }
419             }
420           }
421           fNrEqHits+=nrChipHits;
422
423           if (nrChipHits>0) {
424             // make sure the chip is not flagged as dead
425             fHandler->SetDeadChip(GetEqNr(),hs,chip,kFALSE);
426           }
427
428           if (nrPossiblyDeadPixels==0) {
429             // no need to see if we have enough statistics...
430             fNrEnoughStatChips++;
431             good=kTRUE;
432             //  printf("%3d",good);
433             //  if (chip==9) printf("\n");
434             continue;
435           }
436
437           if (nrChipHits==0) {
438             nrPossiblyDeadChips++;
439             possiblyDead->Insert(hs,chip);
440             good=kFALSE;
441             //  printf("%3d",good);
442             //  if (chip==9) printf("\n");
443             continue;
444           }
445
446           // Binomial with n events and probability p for pixel hit
447           UInt_t n = GetNrEvents();
448           if (nrPixels>0 && n>0) {
449
450             Double_t p = (Double_t)nrChipHits/nrPixels/n;
451
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);
455
456             // can we find dead pixels...?
457             if (falselyDeadProb<fThreshDead) {
458               fNrEnoughStatChips++;
459               good=kTRUE;
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);
464                   if (nrHits==0) {
465                     if (!fHandler->IsPixelNoisy(GetEqNr(),hs,chip,col,row)) {
466                       // don't include noisy pixels
467                       fHandler->SetDeadPixel(GetEqNr(),hs,chip,col,row);
468                     }
469                   }
470                 }
471               }
472             }
473             if (!good) {
474               // this might be an inefficient chip
475               possiblyIneff->Insert(hs*10+chip,nrChipHits);
476             }
477
478           }
479           else {
480             if (n>0) {
481               // this is a completely noisy chip... put in category enough stat
482               fNrEnoughStatChips++;
483               good=kTRUE;
484             }
485           }
486
487           //      printf("%3d",good);
488           //      if (chip==9) printf("\n");
489
490         }
491       } // for chip
492     }
493   } // for hs
494  
495
496   Int_t key,val;
497
498   // dead chips?
499   if (fNrEqHits>fMinNrEqHitsForDeadChips) {
500     while (possiblyDead->Pop(key,val)) {
501       fHandler->SetDeadChip(GetEqNr(),key,val,kFALSE);
502     }
503     fNrDeadChips+=nrPossiblyDeadChips;
504   }
505   delete possiblyDead;
506
507   // inefficient chips?
508   while (possiblyIneff->Pop(key,val)) {
509     if (val<fNrEqHits/60*fRatioToMeanForInefficientChip) {
510       fNrInefficientChips++;
511     }
512   }
513   delete possiblyIneff;
514
515
516   fbDeadProcessed = kTRUE;
517
518   return fNrEnoughStatChips;
519 }
520
521
522 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrEnoughStatChips() {
523   // returns nr of enough stat chips
524   if (!fbDeadProcessed) ProcessDeadPixels();
525   return fNrEnoughStatChips;
526 }
527 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrDeadChips() {
528   // returns nr of dead chips
529   if (!fbDeadProcessed) ProcessDeadPixels();
530   return fNrDeadChips;
531 }
532 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrInefficientChips() {
533   // returns nr of inefficient chips
534   if (!fbDeadProcessed) ProcessDeadPixels();
535   return fNrInefficientChips;
536 }
537 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrNeedsMoreStatChips() {
538   // returns nr of needs more stat chips
539   if (!fbDeadProcessed) ProcessDeadPixels();
540   return 60-fNrEnoughStatChips-fNrDeadChips-fNrInefficientChips;
541 }
542
543 UInt_t AliITSOnlineSPDphysAnalyzer::GetEqNr() const {
544   // returns the eq nr of phys obj
545   if (fPhysObj!=NULL) return fPhysObj->GetEqNr(); 
546   else return 999;
547 }
548
549 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrEvents() const {
550   // returns the nr of events of phys obj
551   if (fPhysObj!=NULL) return fPhysObj->GetNrEvents(); 
552   else return 0;
553 }
554
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)
557   while (val>10) {
558     val/=10;
559     valExp++;
560   }
561   while (val<1) {
562     val*=10;
563     valExp--;
564   }
565 }
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.
570
571   if (fPhysObj==NULL) {
572     Error("AliITSOnlineSPDphysAnalyzer::GetPhysicalHitMapTot","No data!");
573     return NULL;
574   }
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));
592         }
593       }
594     }
595   }
596   return hPhysicalHitMapTot;
597 }
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!");
604     return NULL;
605   }
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));
619         }
620       }
621     }
622   }
623   return fHitMapTot;
624 }
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!");
630     return NULL;
631   }
632
633   TString histoName;
634   TString histoTitle;
635   histoName = Form("fChipHisto_%d_%d_%d", GetEqNr(), hs, chip);
636   histoTitle = Form("Eq ID %d, Half Stave %d, Chip %d", GetEqNr(), hs, chip);
637
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));
644     }
645   }
646
647   return returnHisto;
648 }
649