Another histos for lumi
[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 using std::ifstream;
38
39 AliITSOnlineSPDphysAnalyzer::AliITSOnlineSPDphysAnalyzer(const Char_t *fileName, AliITSOnlineCalibrationSPDhandler* handler, Bool_t readFromGridFile) :
40   fFileName(fileName),fPhysObj(NULL),fHandler(handler),
41   fNrEnoughStatChips(0),fNrDeadChips(0),fNrInefficientChips(0),
42   fNrEqHits(0),fbDeadProcessed(kFALSE),
43   fThreshNoisy(1e-9),fThreshDead(1e-9),
44   fMinEventsForNoisy(10000),fMinEventsForDead(10000),
45   fDefinitelyNoisyRatio(0.3),
46   fMinNrEqHitsForDeadChips(60000),fRatioToMeanForInefficientChip(0.1)
47 {
48   // constructor  
49   Init(readFromGridFile);
50 }
51
52 AliITSOnlineSPDphysAnalyzer::AliITSOnlineSPDphysAnalyzer(AliITSOnlineSPDphys* physObj, AliITSOnlineCalibrationSPDhandler* handler) :
53   fFileName("test.root"),fPhysObj(NULL),fHandler(handler),
54   fNrEnoughStatChips(0),fNrDeadChips(0),fNrInefficientChips(0),
55   fNrEqHits(0),fbDeadProcessed(kFALSE),
56   fThreshNoisy(1e-9),fThreshDead(1e-9),
57   fMinEventsForNoisy(10000),fMinEventsForDead(10000),
58   fDefinitelyNoisyRatio(0.3),
59   fMinNrEqHitsForDeadChips(60000),fRatioToMeanForInefficientChip(0.1)
60 {
61   // alt constructor
62   fPhysObj = physObj;
63 }
64
65 AliITSOnlineSPDphysAnalyzer::AliITSOnlineSPDphysAnalyzer(const AliITSOnlineSPDphysAnalyzer& handle) :
66   fFileName("test.root"),fPhysObj(NULL),fHandler(NULL),
67   fNrEnoughStatChips(0),fNrDeadChips(0),fNrInefficientChips(0),
68   fNrEqHits(0),fbDeadProcessed(kFALSE),
69   fThreshNoisy(1e-9),fThreshDead(1e-9),
70   fMinEventsForNoisy(10000),fMinEventsForDead(10000),
71   fDefinitelyNoisyRatio(0.3),
72   fMinNrEqHitsForDeadChips(60000),fRatioToMeanForInefficientChip(0.1)
73 {
74   // copy constructor, only copies the filename and params (not the processed data)
75   fFileName=handle.fFileName;
76   fThreshNoisy = handle.fThreshNoisy;
77   fThreshDead = handle.fThreshDead;
78   fMinEventsForNoisy = handle.fMinEventsForNoisy;
79   fMinEventsForDead = handle.fMinEventsForDead;
80   fDefinitelyNoisyRatio = handle.fDefinitelyNoisyRatio;
81   fMinNrEqHitsForDeadChips = handle.fMinNrEqHitsForDeadChips;
82   fRatioToMeanForInefficientChip = handle.fRatioToMeanForInefficientChip;
83
84   Init();
85 }
86
87 AliITSOnlineSPDphysAnalyzer::~AliITSOnlineSPDphysAnalyzer() {
88   // destructor
89   if (fPhysObj!=NULL) delete fPhysObj;
90 }
91
92 AliITSOnlineSPDphysAnalyzer& AliITSOnlineSPDphysAnalyzer::operator=(const AliITSOnlineSPDphysAnalyzer& handle) {
93   // assignment operator, only copies the filename and params (not the processed data)
94   if (this!=&handle) {
95     if (fPhysObj!=NULL) delete fPhysObj;
96     
97     fFileName=handle.fFileName;
98     fThreshNoisy = handle.fThreshNoisy;
99     fThreshDead = handle.fThreshDead;
100     fMinEventsForNoisy = handle.fMinEventsForNoisy;
101     fMinEventsForDead = handle.fMinEventsForDead;
102     fDefinitelyNoisyRatio = handle.fDefinitelyNoisyRatio;
103     fMinNrEqHitsForDeadChips = handle.fMinNrEqHitsForDeadChips;
104     fRatioToMeanForInefficientChip = handle.fRatioToMeanForInefficientChip;
105
106     fPhysObj = NULL;
107     fHandler = NULL;
108     fNrEnoughStatChips = 0;
109     fNrDeadChips = 0;
110     fNrInefficientChips = 0;
111     fNrEqHits = 0;
112     fbDeadProcessed = kFALSE;
113
114     Init();    
115   }
116   return *this;
117 }
118
119 void AliITSOnlineSPDphysAnalyzer::Init(Bool_t readFromGridFile) {
120   // initialize container obj
121   if (!readFromGridFile) {
122     FILE* fp0 = fopen(fFileName.Data(), "r");
123     if (fp0 == NULL) {
124       return;
125     }
126     else {
127       fclose(fp0);
128     }
129   }
130   fPhysObj = new AliITSOnlineSPDphys(fFileName.Data(), readFromGridFile);
131 }
132
133 void AliITSOnlineSPDphysAnalyzer::SetParam(const Char_t *pname, const Char_t *pval) {
134   // set a parameter
135   TString name = pname;
136   TString val = pval;
137   //  printf("Setting Param %s  to %s\n",name.Data(),val.Data());
138   if (name.CompareTo("MistakeProbabilityNoisy")==0) {
139     Double_t mistakeProbabilityNoisy = val.Atof();
140     fThreshNoisy = mistakeProbabilityNoisy/(20*6*10*32*256);
141   }
142   else if (name.CompareTo("MistakeProbabilityDead")==0) {
143     Double_t mistakeProbabilityDead = val.Atof();
144     fThreshDead = mistakeProbabilityDead/(20*6*10*32*256);
145   }
146   else if (name.CompareTo("fMinEventsForNoisy")==0) {
147     fMinEventsForNoisy = val.Atoi();
148   }
149   else if (name.CompareTo("fMinEventsForDead")==0) {
150     fMinEventsForDead = val.Atoi();
151   }
152   else if (name.CompareTo("fDefinitelyNoisyRatio")==0) {
153     fDefinitelyNoisyRatio = val.Atof();
154   }
155   else if (name.CompareTo("fMinNrEqHitsForDeadChips")==0) {
156     fMinNrEqHitsForDeadChips = val.Atof();
157   }
158   else if (name.CompareTo("fRatioToMeanForInefficientChip")==0) {
159     fRatioToMeanForInefficientChip = val.Atof();
160   }
161   else {
162     Error("AliITSOnlineSPDphysAnalyzer::SetParam","Parameter %s in configuration file unknown.",name.Data());
163   }
164 }
165
166 void AliITSOnlineSPDphysAnalyzer::ReadParamsFromLocation(const Char_t *dirName) {
167   // opens file (default name) in dir dirName and reads parameters from it
168   TString paramsFileName = Form("%s/physics_params.txt",dirName);
169   ifstream paramsFile;
170   paramsFile.open(paramsFileName, ifstream::in);
171   if (paramsFile.fail()) {
172     printf("No config file (%s) present. Using default tuning parameters.\n",paramsFileName.Data());
173   }
174   else {
175     while(1) {
176       Char_t paramN[50];
177       Char_t paramV[50];
178       paramsFile >> paramN;
179       if (paramsFile.eof()) break;
180       paramsFile >> paramV;
181       SetParam(paramN,paramV);
182       if (paramsFile.eof()) break;
183     }
184     paramsFile.close();
185   }
186 }
187
188
189 UInt_t AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels() {
190   // process noisy pixel data , returns number of chips with enough statistics
191   if (fPhysObj==NULL) {
192     Warning("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","No data!");
193     return 0;
194   }
195   // do we have enough events to even try the algorithm?
196   if (GetNrEvents() < fMinEventsForNoisy) {
197     Warning("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","Nr events (%d) < fMinEventsForNoisy (%d)!",GetNrEvents(),fMinEventsForNoisy);
198     return 0;
199   }
200   // handler should be initialized
201   if (fHandler==NULL) {
202     Error("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","Calibration handler is not initialized!");
203     return 0;
204   }
205   
206   UInt_t nrEnoughStatChips = 0;
207
208   for (UInt_t hs=0; hs<6; hs++) {
209     for (UInt_t chip=0; chip<10; chip++) {
210
211       UInt_t nrPixels = 0;
212       UInt_t nrChipHits = 0;
213       UInt_t nrMostHits = 0;
214       for (UInt_t col=0; col<32; col++) {
215         for (UInt_t row=0; row<256; row++) {
216           UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
217           nrChipHits += nrHits;
218           //      if (nrHits>0) nrPixels++; // don't include pixels that might be dead
219           nrPixels++;
220           if (nrHits>fDefinitelyNoisyRatio*GetNrEvents()) {
221             fHandler->SetNoisyPixel(GetEqNr(),hs,chip,col,row);
222             nrPixels--;
223             nrChipHits-=nrHits;
224           }
225           else {
226             if (nrMostHits<nrHits) nrMostHits=nrHits;
227           }
228         }
229       }
230
231       if (nrChipHits>0) { // otherwise there are for sure no noisy
232         // Binomial with n events and probability p for pixel hit
233         UInt_t n = GetNrEvents();
234         if (nrPixels>0 && n>0) {
235
236           Double_t p = (Double_t)nrChipHits/nrPixels/n;
237
238           // Bin(n,k=0):
239           Double_t bin = pow((Double_t)(1-p),(Double_t)n);
240           // Bin(n,k)
241           UInt_t k=1;
242           while ((bin>fThreshNoisy || k<n*p) && k<=n) {
243             k++;
244             bin = bin*(n-k+1)/k*p/(1-p);
245           }
246           
247           // can we find noisy pixels...?
248           if (k<=n) {
249             //      printf("eq %d , hs %d , chip %d : Noisy level = %d\n",GetEqNr(),hs,chip,k);
250             nrEnoughStatChips++;
251             // add noisy pixels to handler
252             UInt_t noiseLimit=k;
253             if (nrMostHits>=noiseLimit) {
254               for (UInt_t col=0; col<32; col++) {
255                 for (UInt_t row=0; row<256; row++) {
256                   UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
257                   if (nrHits >= noiseLimit) {
258                     fHandler->SetNoisyPixel(GetEqNr(),hs,chip,col,row);
259                   }
260                 }
261               }
262             }
263           }
264         }
265
266       }
267
268     } // for chip
269   } // for hs
270
271   return nrEnoughStatChips;
272 }
273
274 UInt_t AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels(UInt_t eq, UInt_t nrEvts) {
275   // process noisy pixel data , returns number of chips with enough statistics
276   if (fPhysObj==NULL) {
277     Warning("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","No data!");
278     return 0;
279   }
280   // do we have enough events to even try the algorithm?
281   if (nrEvts < fMinEventsForNoisy) {
282     Warning("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","Nr events (%d) < fMinEventsForNoisy (%d)!",nrEvts,fMinEventsForNoisy);
283     return 0;
284   }
285   // handler should be initialized
286   if (fHandler==NULL) {
287     Error("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","Calibration handler is not initialized!");
288     return 0;
289   }
290   
291   UInt_t nrEnoughStatChips = 0;
292
293   for (UInt_t hs=0; hs<6; hs++) {
294     for (UInt_t chip=0; chip<10; chip++) {
295
296       UInt_t nrPixels = 0;
297       UInt_t nrChipHits = 0;
298       UInt_t nrMostHits = 0;
299       for (UInt_t col=0; col<32; col++) {
300         for (UInt_t row=0; row<256; row++) {
301           UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
302           nrChipHits += nrHits;
303           //      if (nrHits>0) nrPixels++; // don't include pixels that might be dead
304           nrPixels++;
305           if (nrHits>fDefinitelyNoisyRatio*nrEvts) {
306             fHandler->SetNoisyPixel(eq,hs,chip,col,row);
307             nrPixels--;
308             nrChipHits-=nrHits;
309           }
310           else {
311             if (nrMostHits<nrHits) nrMostHits=nrHits;
312           }
313         }
314       }
315
316       if (nrChipHits>0) { // otherwise there are for sure no noisy
317         // Binomial with n events and probability p for pixel hit
318         UInt_t n = nrEvts;
319         if (nrPixels>0 && n>0) {
320
321           Double_t p = (Double_t)nrChipHits/nrPixels/n;
322
323           // Bin(n,k=0):
324           Double_t bin = pow((Double_t)(1-p),(Double_t)n);
325           // Bin(n,k)
326           UInt_t k=1;
327           while ((bin>fThreshNoisy || k<n*p) && k<=n) {
328             k++;
329             bin = bin*(n-k+1)/k*p/(1-p);
330           }
331           
332           // can we find noisy pixels...?
333           if (k<=n) {
334             //      printf("eq %d , hs %d , chip %d : Noisy level = %d\n",GetEqNr(),hs,chip,k);
335             nrEnoughStatChips++;
336             // add noisy pixels to handler
337             UInt_t noiseLimit=k;
338             if (nrMostHits>=noiseLimit) {
339               for (UInt_t col=0; col<32; col++) {
340                 for (UInt_t row=0; row<256; row++) {
341                   UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
342                   if (nrHits >= noiseLimit) {
343                     fHandler->SetNoisyPixel(eq,hs,chip,col,row);
344                   }
345                 }
346               }
347             }
348           }
349         }
350
351       }
352
353     } // for chip
354   } // for hs
355
356   return nrEnoughStatChips;
357 }
358
359
360 UInt_t AliITSOnlineSPDphysAnalyzer::ProcessDeadPixels() {
361   // process dead pixel data , returns number of chips with enough statistics
362   if (fPhysObj==NULL) {
363     Warning("AliITSOnlineSPDphysAnalyzer::ProcessDeadPixels","No data!");
364     return 0;
365   }
366
367   // do we have enough events to even try the algorithm?
368   if (GetNrEvents() < fMinEventsForDead) {
369     Warning("AliITSOnlineSPDphysAnalyzer::ProcessDeadPixels","Nr events (%d) < fMinEventsForDead (%d)!",GetNrEvents(),fMinEventsForDead);
370     return 0;
371   }
372   // handler should be initialized
373   if (fHandler==NULL) {
374     Error("AliITSOnlineSPDphysAnalyzer::ProcessDeadPixels","Calibration handler is not initialized!");
375     return 0;
376   }
377
378   AliITSIntMap* possiblyDead  = new AliITSIntMap();
379   AliITSIntMap* possiblyIneff = new AliITSIntMap();
380
381   fNrEnoughStatChips = 0;
382   fNrDeadChips = 0;
383   fNrInefficientChips = 0;
384   UInt_t nrPossiblyDeadChips = 0;
385   fNrEqHits = 0;
386
387
388   for (UInt_t hs=0; hs<6; hs++) {
389     if (!fHandler->IsActiveHS(GetEqNr(),hs)) {
390       fNrDeadChips+=10;
391     }
392     else {
393       for (UInt_t chip=0; chip<10; chip++) {
394         if (!fHandler->IsActiveChip(GetEqNr(),hs,chip)) {
395           fNrDeadChips++;
396         }
397         else {
398           // perform search for individual dead pixels...
399           Bool_t good=kFALSE;
400
401           UInt_t nrPossiblyDeadPixels = 0;
402           UInt_t nrPixels = 0;
403           UInt_t nrChipHits = 0;
404           for (UInt_t col=0; col<32; col++) {
405             for (UInt_t row=0; row<256; row++) {
406               UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
407               nrChipHits += nrHits;
408               if (!fHandler->IsPixelNoisy(GetEqNr(),hs,chip,col,row)) {
409                 // don't include noisy pixels
410                 nrPixels++;
411                 if (nrHits==0) {
412                   nrPossiblyDeadPixels++;
413                 }
414                 else {
415                   fHandler->UnSetDeadPixel(GetEqNr(),hs,chip,col,row); // unset (no action unless dead before)
416                 }
417               }
418               else {
419                 nrChipHits -= nrHits; // this is needed when running offline (online nrHits should be 0 already)
420               }
421             }
422           }
423           fNrEqHits+=nrChipHits;
424
425           if (nrChipHits>0) {
426             // make sure the chip is not flagged as dead
427             fHandler->SetDeadChip(GetEqNr(),hs,chip,kFALSE);
428           }
429
430           if (nrPossiblyDeadPixels==0) {
431             // no need to see if we have enough statistics...
432             fNrEnoughStatChips++;
433             good=kTRUE;
434             //  printf("%3d",good);
435             //  if (chip==9) printf("\n");
436             continue;
437           }
438
439           if (nrChipHits==0) {
440             nrPossiblyDeadChips++;
441             possiblyDead->Insert(hs,chip);
442             good=kFALSE;
443             //  printf("%3d",good);
444             //  if (chip==9) printf("\n");
445             continue;
446           }
447
448           // Binomial with n events and probability p for pixel hit
449           UInt_t n = GetNrEvents();
450           if (nrPixels>0 && n>0) {
451
452             Double_t p = (Double_t)nrChipHits/nrPixels/n;
453
454             // probability of falsely assigning a dead pixel
455             Double_t falselyDeadProb = pow((Double_t)(1-p),(Double_t)n);
456             //      printf("falselyprob=%e\n",falselyDeadProb);
457
458             // can we find dead pixels...?
459             if (falselyDeadProb<fThreshDead) {
460               fNrEnoughStatChips++;
461               good=kTRUE;
462               // add dead pixels to handler
463               for (UInt_t col=0; col<32; col++) {
464                 for (UInt_t row=0; row<256; row++) {
465                   UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
466                   if (nrHits==0) {
467                     if (!fHandler->IsPixelNoisy(GetEqNr(),hs,chip,col,row)) {
468                       // don't include noisy pixels
469                       fHandler->SetDeadPixel(GetEqNr(),hs,chip,col,row);
470                     }
471                   }
472                 }
473               }
474             }
475             if (!good) {
476               // this might be an inefficient chip
477               possiblyIneff->Insert(hs*10+chip,nrChipHits);
478             }
479
480           }
481           else {
482             if (n>0) {
483               // this is a completely noisy chip... put in category enough stat
484               fNrEnoughStatChips++;
485               good=kTRUE;
486             }
487           }
488
489           //      printf("%3d",good);
490           //      if (chip==9) printf("\n");
491
492         }
493       } // for chip
494     }
495   } // for hs
496  
497
498   Int_t key,val;
499
500   // dead chips?
501   if (fNrEqHits>fMinNrEqHitsForDeadChips) {
502     while (possiblyDead->Pop(key,val)) {
503       fHandler->SetDeadChip(GetEqNr(),key,val,kFALSE);
504     }
505     fNrDeadChips+=nrPossiblyDeadChips;
506   }
507   delete possiblyDead;
508
509   // inefficient chips?
510   while (possiblyIneff->Pop(key,val)) {
511     if (val<fNrEqHits/60*fRatioToMeanForInefficientChip) {
512       fNrInefficientChips++;
513     }
514   }
515   delete possiblyIneff;
516
517
518   fbDeadProcessed = kTRUE;
519
520   return fNrEnoughStatChips;
521 }
522
523
524 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrEnoughStatChips() {
525   // returns nr of enough stat chips
526   if (!fbDeadProcessed) ProcessDeadPixels();
527   return fNrEnoughStatChips;
528 }
529 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrDeadChips() {
530   // returns nr of dead chips
531   if (!fbDeadProcessed) ProcessDeadPixels();
532   return fNrDeadChips;
533 }
534 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrInefficientChips() {
535   // returns nr of inefficient chips
536   if (!fbDeadProcessed) ProcessDeadPixels();
537   return fNrInefficientChips;
538 }
539 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrNeedsMoreStatChips() {
540   // returns nr of needs more stat chips
541   if (!fbDeadProcessed) ProcessDeadPixels();
542   return 60-fNrEnoughStatChips-fNrDeadChips-fNrInefficientChips;
543 }
544
545 UInt_t AliITSOnlineSPDphysAnalyzer::GetEqNr() const {
546   // returns the eq nr of phys obj
547   if (fPhysObj!=NULL) return fPhysObj->GetEqNr(); 
548   else return 999;
549 }
550
551 UInt_t AliITSOnlineSPDphysAnalyzer::GetNrEvents() const {
552   // returns the nr of events of phys obj
553   if (fPhysObj!=NULL) return fPhysObj->GetNrEvents(); 
554   else return 0;
555 }
556
557 void AliITSOnlineSPDphysAnalyzer::Exponent(Double_t &val, Int_t &valExp) const {
558   // put double in format with val and exp so that 1<val<10 - The actual value is val*10e(valExp)
559   while (val>10) {
560     val/=10;
561     valExp++;
562   }
563   while (val<1) {
564     val*=10;
565     valExp--;
566   }
567 }
568 //____________________________________________________________________________________________________
569 TH2F* AliITSOnlineSPDphysAnalyzer::GetPhysicalHitMapTot() {
570   // creates and returns a pointer to a hitmap histo (equipment opened up)
571   // physical representation of the half stave hitmap.
572
573   if (fPhysObj==NULL) {
574     Error("AliITSOnlineSPDphysAnalyzer::GetPhysicalHitMapTot","No data!");
575     return NULL;
576   }
577   TString histoname = Form("Eq %d",GetEqNr());
578   TH2F* hPhysicalHitMapTot = new TH2F(histoname.Data(),histoname.Data(),32*10,-0.5,32*10-0.5,256*6,-0.5,256*6-0.5);
579   hPhysicalHitMapTot->SetNdivisions(-10,"X");
580   hPhysicalHitMapTot->SetNdivisions(-006,"Y");
581   hPhysicalHitMapTot->SetTickLength(0,"X");
582   hPhysicalHitMapTot->SetTickLength(0,"Y");
583   hPhysicalHitMapTot->GetXaxis()->SetLabelColor(gStyle->GetCanvasColor());
584   hPhysicalHitMapTot->GetYaxis()->SetLabelColor(gStyle->GetCanvasColor());
585   Int_t correctChip=-1;
586   for (UInt_t hs=0; hs<6; hs++) {
587     for (UInt_t chipNr=0; chipNr<10; chipNr++) {
588       if(GetEqNr()<10) correctChip=9-chipNr;
589       else correctChip=chipNr;
590       for (UInt_t col=0; col<32; col++) {
591         for (UInt_t row=0; row<256; row++) {
592           if(hs>1) hPhysicalHitMapTot->Fill(correctChip*32+(31-col),(5-hs)*256+row,fPhysObj->GetHits(hs,chipNr,col,row));
593           else hPhysicalHitMapTot->Fill(correctChip*32+col,(5-hs)*256+row,fPhysObj->GetHits(hs,chipNr,col,row));
594         }
595       }
596     }
597   }
598   return hPhysicalHitMapTot;
599 }
600 //_____________________________________________________________________________________________________
601 TH2F* AliITSOnlineSPDphysAnalyzer::GetHitMapTot() {
602   // creates and returns a pointer to a hitmap histo (half sector style a la spdmood)
603   // This histogram  shown the read out numbering pattern, it is not the physical one.
604   if (fPhysObj==NULL) {
605     Error("AliITSOnlineSPDphysAnalyzer::GetHitMapTot","No data!");
606     return NULL;
607   }
608   TString histoname = Form("Eq %d",GetEqNr());
609   TH2F* fHitMapTot = new TH2F(histoname.Data(),histoname.Data(),32*10,-0.5,32*10-0.5,256*6,-0.5,256*6-0.5);
610   fHitMapTot->SetNdivisions(-10,"X");
611   fHitMapTot->SetNdivisions(-006,"Y");
612   fHitMapTot->SetTickLength(0,"X");
613   fHitMapTot->SetTickLength(0,"Y");
614   fHitMapTot->GetXaxis()->SetLabelColor(gStyle->GetCanvasColor());
615   fHitMapTot->GetYaxis()->SetLabelColor(gStyle->GetCanvasColor());
616   for (UInt_t hs=0; hs<6; hs++) {
617     for (UInt_t chipNr=0; chipNr<10; chipNr++) {
618       for (UInt_t col=0; col<32; col++) {
619         for (UInt_t row=0; row<256; row++) {
620           fHitMapTot->Fill(chipNr*32+col,(5-hs)*256+row,fPhysObj->GetHits(hs,chipNr,col,row));
621         }
622       }
623     }
624   }
625   return fHitMapTot;
626 }
627 //________________________________________________________________________________________________________
628 TH2F* AliITSOnlineSPDphysAnalyzer::GetHitMapChip(UInt_t hs, UInt_t chip) {
629   // creates and returns a pointer to a hitmap histo (chip style a la spdmood)
630   if (fPhysObj==NULL) {
631     Error("AliITSOnlineSPDphysAnalyzer::GetHitMapChip","No data!");
632     return NULL;
633   }
634
635   TString histoName;
636   TString histoTitle;
637   histoName = Form("fChipHisto_%d_%d_%d", GetEqNr(), hs, chip);
638   histoTitle = Form("Eq ID %d, Half Stave %d, Chip %d", GetEqNr(), hs, chip);
639
640   TH2F *returnHisto = new TH2F(histoName.Data(), histoTitle.Data(), 32, -0.5, 31.5, 256, -0.5, 255.5);
641   returnHisto->SetMinimum(0);
642   for (UInt_t col=0; col<32; col++) {
643     for (UInt_t row=0; row<256; row++) {
644       if(hs<2) returnHisto->Fill(31-col,row,fPhysObj->GetHits(hs,chip,col,row));
645       else returnHisto->Fill(col,row,fPhysObj->GetHits(hs,chip,col,row));
646     }
647   }
648
649   return returnHisto;
650 }
651