]> git.uio.no Git - u/mrichter/AliRoot.git/blame - ITS/AliITSOnlineSPDphysAnalyzer.cxx
Mainly changes related to the added treatment of inactive detector parts in
[u/mrichter/AliRoot.git] / ITS / AliITSOnlineSPDphysAnalyzer.cxx
CommitLineData
6727e2db 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
37AliITSOnlineSPDphysAnalyzer::AliITSOnlineSPDphysAnalyzer(const Char_t *fileName, AliITSOnlineCalibrationSPDhandler* handler) :
38 fFileName(fileName),fPhysObj(NULL),fHandler(handler),
39 fNrEnoughStatChips(0),fNrDeadChips(0),fNrInefficientChips(0),
40 fNrEqHits(0),fbDeadProcessed(kFALSE),
41 fThreshNoisy(1),fThreshNoisyExp(-12),fThreshDead(1),fThreshDeadExp(-12),
42 fMinEventsForNoisy(10000),fMinEventsForDead(10000),
43 fDefinitelyNoisyRatio(0.1),
44 fMinNrEqHitsForDeadChips(60000),fRatioToMeanForInefficientChip(0.1)//!!!
45{
46 // constructor
47 Init();
48}
49
50AliITSOnlineSPDphysAnalyzer::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(1),fThreshNoisyExp(-12),fThreshDead(1),fThreshDeadExp(-12),
55 fMinEventsForNoisy(10000),fMinEventsForDead(10000),
56 fDefinitelyNoisyRatio(0.1),
57 fMinNrEqHitsForDeadChips(60000),fRatioToMeanForInefficientChip(0.1)//!!!
58{
59 // alt constructor
60 fPhysObj = physObj;
61}
62
63AliITSOnlineSPDphysAnalyzer::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(1),fThreshNoisyExp(-12),fThreshDead(1),fThreshDeadExp(-12),
68 fMinEventsForNoisy(10000),fMinEventsForDead(10000),
69 fDefinitelyNoisyRatio(0.1),
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 fThreshNoisyExp = handle.fThreshNoisyExp;
76 fThreshDead = handle.fThreshDead;
77 fThreshDeadExp = handle.fThreshDeadExp;
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
87AliITSOnlineSPDphysAnalyzer::~AliITSOnlineSPDphysAnalyzer() {
88 // destructor
89 if (fPhysObj!=NULL) delete fPhysObj;
90}
91
92AliITSOnlineSPDphysAnalyzer& 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 fThreshNoisyExp = handle.fThreshNoisyExp;
100 fThreshDead = handle.fThreshDead;
101 fThreshDeadExp = handle.fThreshDeadExp;
102 fMinEventsForNoisy = handle.fMinEventsForNoisy;
103 fMinEventsForDead = handle.fMinEventsForDead;
104 fDefinitelyNoisyRatio = handle.fDefinitelyNoisyRatio;
105 fMinNrEqHitsForDeadChips = handle.fMinNrEqHitsForDeadChips;
106 fRatioToMeanForInefficientChip = handle.fRatioToMeanForInefficientChip;
107
108 fPhysObj = NULL;
109 fHandler = NULL;
110 fNrEnoughStatChips = 0;
111 fNrDeadChips = 0;
112 fNrInefficientChips = 0;
113 fNrEqHits = 0;
114 fbDeadProcessed = kFALSE;
115
116 Init();
117 }
118 return *this;
119}
120
121void AliITSOnlineSPDphysAnalyzer::Init() {
122 // initialize container obj
123 FILE* fp0 = fopen(fFileName.Data(), "r");
124 if (fp0 == NULL) {
125 return;
126 }
127 else {
128 fclose(fp0);
129 }
130 fPhysObj = new AliITSOnlineSPDphys(fFileName.Data());
131}
132
133void 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;
141 fThreshNoisyExp = 0;
142 Exponent(fThreshNoisy,fThreshNoisyExp);
143 fThreshNoisy/=(20*6*10*32*256);
144 Exponent(fThreshNoisy,fThreshNoisyExp);
145 }
146 else if (name.CompareTo("MistakeProbabilityDead")==0) {
147 Double_t mistakeProbabilityDead = val.Atof();
148 fThreshDead = mistakeProbabilityDead;
149 fThreshDeadExp = 0;
150 Exponent(fThreshDead,fThreshDeadExp);
151 fThreshDead/=(20*6*10*32*256);
152 Exponent(fThreshDead,fThreshDeadExp);
153 }
154 else if (name.CompareTo("fMinEventsForNoisy")==0) {
155 fMinEventsForNoisy = val.Atoi();
156 }
157 else if (name.CompareTo("fMinEventsForDead")==0) {
158 fMinEventsForDead = val.Atoi();
159 }
160 else if (name.CompareTo("fDefinitelyNoisyRatio")==0) {
161 fDefinitelyNoisyRatio = val.Atof();
162 }
163 else if (name.CompareTo("fMinNrEqHitsForDeadChips")==0) {
164 fMinNrEqHitsForDeadChips = val.Atof();
165 }
166 else if (name.CompareTo("fRatioToMeanForInefficientChip")==0) {
167 fRatioToMeanForInefficientChip = val.Atof();
168 }
169 else {
170 Error("AliITSOnlineSPDphysAnalyzer::SetParam","Parameter %s in configuration file unknown.",name.Data());
171 }
172}
173
174void AliITSOnlineSPDphysAnalyzer::ReadParamsFromLocation(const Char_t *dirName) {
175 // opens file (default name) in dir dirName and reads parameters from it
176 TString paramsFileName = Form("%s/physics_params.txt",dirName);
177 ifstream paramsFile;
178 paramsFile.open(paramsFileName, ifstream::in);
179 if (paramsFile.fail()) {
180 printf("No config file (%s) present. Using default tuning parameters.\n",paramsFileName.Data());
181 }
182 else {
183 while(1) {
184 Char_t paramN[50];
185 Char_t paramV[50];
186 paramsFile >> paramN;
187 if (paramsFile.eof()) break;
188 paramsFile >> paramV;
189 SetParam(paramN,paramV);
190 if (paramsFile.eof()) break;
191 }
192 paramsFile.close();
193 }
194}
195
196
197UInt_t AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels() {
198 // process noisy pixel data , returns number of chips with enough statistics
199 if (fPhysObj==NULL) {
200 Warning("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","No data!");
201 return 0;
202 }
203 // do we have enough events to even try the algorithm?
204 if (GetNrEvents() < fMinEventsForNoisy) {
205 Warning("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","Nr events (%d) < fMinEventsForNoisy (%d)!",GetNrEvents(),fMinEventsForNoisy);
206 return 0;
207 }
208 // handler should be initialized
209 if (fHandler==NULL) {
210 Error("AliITSOnlineSPDphysAnalyzer::ProcessNoisyPixels","Calibration handler is not initialized!");
211 return 0;
212 }
213
214 UInt_t nrEnoughStatChips = 0;
215
216 for (UInt_t hs=0; hs<6; hs++) {
217 for (UInt_t chip=0; chip<10; chip++) {
218
219 UInt_t nrPixels = 0;
220 UInt_t nrChipHits = 0;
221 UInt_t nrMostHits = 0;
222 for (UInt_t col=0; col<32; col++) {
223 for (UInt_t row=0; row<256; row++) {
224 UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
225 nrChipHits += nrHits;
226 // if (nrHits>0) nrPixels++; // don't include pixels that might be dead
227 nrPixels++;
228 if (nrHits>fDefinitelyNoisyRatio*GetNrEvents()) {
229 fHandler->SetNoisyPixel(GetEqNr(),hs,chip,col,row);
230 nrPixels--;
231 nrChipHits-=nrHits;
232 }
233 else {
234 if (nrMostHits<nrHits) nrMostHits=nrHits;
235 }
236 }
237 }
238
239 if (nrChipHits>0) { // otherwise there are for sure no noisy
240 // Binomial with n events and probability p for pixel hit
241 UInt_t n = GetNrEvents();
242 if (nrPixels>0 && n>0) {
243
244 Double_t p = (Double_t)nrChipHits/nrPixels/n;
245
246 Double_t bin = 1;
247 Int_t binExp = 0;
248 // Bin(n,k=0):
249 for (UInt_t i=0; i<n; i++) {
250 bin*=(1-p);
251 Exponent(bin,binExp);
252 }
253 // Bin(n,k)
254 UInt_t k=1;
255 while (((binExp>fThreshNoisyExp || (binExp==fThreshNoisyExp && bin>fThreshNoisy)) || k<n*p) && k<=n) {
256 k++;
257 bin = bin*(n-k+1)/k*p/(1-p);
258 Exponent(bin,binExp);
259 }
260
261 // can we find noisy pixels...?
262 if (k<=n) {
263 // printf("eq %d , hs %d , chip %d : Noisy level = %d\n",GetEqNr(),hs,chip,k);
264 nrEnoughStatChips++;
265 // add noisy pixels to handler
266 UInt_t noiseLimit=k;
267 if (nrMostHits>=noiseLimit) {
268 for (UInt_t col=0; col<32; col++) {
269 for (UInt_t row=0; row<256; row++) {
270 UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
271 if (nrHits >= noiseLimit) {
272 fHandler->SetNoisyPixel(GetEqNr(),hs,chip,col,row);
273 }
274 }
275 }
276 }
277 }
278 }
279
280 }
281
282 } // for chip
283 } // for hs
284
285 return nrEnoughStatChips;
286}
287
288
289UInt_t AliITSOnlineSPDphysAnalyzer::ProcessDeadPixels() {
290 // process dead pixel data , returns number of chips with enough statistics
291 if (fPhysObj==NULL) {
292 Warning("AliITSOnlineSPDphysAnalyzer::ProcessDeadPixels","No data!");
293 return 0;
294 }
295 // do we have enough events to even try the algorithm?
296 if (GetNrEvents() < fMinEventsForDead) {
297 Warning("AliITSOnlineSPDphysAnalyzer::ProcessDeadPixels","Nr events (%d) < fMinEventsForDead (%d)!",GetNrEvents(),fMinEventsForDead);
298 return 0;
299 }
300 // handler should be initialized
301 if (fHandler==NULL) {
302 Error("AliITSOnlineSPDphysAnalyzer::ProcessDeadPixels","Calibration handler is not initialized!");
303 return 0;
304 }
305
b696414b 306 AliITSIntMap* possiblyDead = new AliITSIntMap();
6727e2db 307 AliITSIntMap* possiblyIneff = new AliITSIntMap();
308
309 fNrEnoughStatChips = 0;
310 fNrDeadChips = 0;
311 fNrInefficientChips = 0;
312 UInt_t nrPossiblyDeadChips = 0;
313 fNrEqHits = 0;
314
6727e2db 315
b696414b 316 AliITSOnlineCalibrationSPDhandler *deadPixelHandler = new AliITSOnlineCalibrationSPDhandler();
6727e2db 317
b696414b 318 for (UInt_t hs=0; hs<6; hs++) {
319 if (!(fHandler->IsActiveHS(GetEqNr(),hs))) {
320 fNrDeadChips+=10;
321 }
322 else {
323 for (UInt_t chip=0; chip<10; chip++) {
324 if (!(fHandler->IsActiveChip(GetEqNr(),hs,chip))) {
325 fNrDeadChips++;
326 }
327 else {
328 // perform search for individual dead pixels...
329 deadPixelHandler->ResetDead();
330 Bool_t good=kFALSE;
331
332 UInt_t nrPossiblyDeadPixels = 0;
333 UInt_t nrPixels = 0;
334 UInt_t nrChipHits = 0;
335 for (UInt_t col=0; col<32; col++) {
336 for (UInt_t row=0; row<256; row++) {
337 UInt_t nrHits = fPhysObj->GetHits(hs,chip,col,row);
338 nrChipHits += nrHits;
339 if (!fHandler->IsPixelNoisy(GetEqNr(),hs,chip,col,row)) {
340 // don't include noisy pixels
341 nrPixels++;
342 if (nrHits==0) {
343 nrPossiblyDeadPixels++;
344 deadPixelHandler->SetDeadPixel(GetEqNr(),hs,chip,col,row);
345 }
346 }
347 else {
348 nrChipHits -= nrHits; // this is needed when running offline (online nrHits should be 0 already)
349 }
6727e2db 350 }
351 }
b696414b 352 fNrEqHits+=nrChipHits;
353
354 // check all pixels that were declared dead from before...
355 UInt_t nrDeadBefore = fHandler->GetNrDeadC(GetEqNr(),hs,chip);
356 AliITSOnlineCalibrationSPDhandler *tmpHand = new AliITSOnlineCalibrationSPDhandler();
357 for (UInt_t index=0; index<nrDeadBefore; index++) {
358 UInt_t col = fHandler->GetDeadColAtC(GetEqNr(),hs,chip,index);
359 UInt_t row = fHandler->GetDeadRowAtC(GetEqNr(),hs,chip,index);
360 if (fPhysObj->GetHits(hs,chip,col,row)>0) {
361 // fHandler->UnSetDeadPixel(GetEqNr(),hs,chip,col,row); // This was a bug - cannot delete while moving through indices, use tmpHand instead
362 tmpHand->SetDeadPixel(GetEqNr(),hs,chip,col,row);
363 }
6727e2db 364 }
b696414b 365 UInt_t nrToRemove = tmpHand->GetNrDead();
366 for (UInt_t index=0; index<nrToRemove; index++) {
367 fHandler->UnSetDeadPixel(GetEqNr(),hs,chip,tmpHand->GetDeadColAtC(GetEqNr(),hs,chip,index),tmpHand->GetDeadRowAtC(GetEqNr(),hs,chip,index));
6727e2db 368 }
b696414b 369 delete tmpHand;
6727e2db 370
371
372
b696414b 373 if (nrPossiblyDeadPixels==0) {
374 // no need to see if we have enough statistics...
375 fNrEnoughStatChips++;
376 good=kTRUE;
377 // printf("%3d",good);
378 // if (chip==9) printf("\n");
379 continue;
380 }
6727e2db 381
b696414b 382 if (nrChipHits==0) {
383 nrPossiblyDeadChips++;
384 //!!! deadChipHandler->SetDeadChip(GetEqNr(),hs,chip);
385 possiblyDead->Insert(hs,chip);
386 good=kFALSE;
387 // printf("%3d",good);
388 // if (chip==9) printf("\n");
389 continue;
390 }
6727e2db 391
b696414b 392 // Binomial with n events and probability p for pixel hit
393 UInt_t n = GetNrEvents();
394 if (nrPixels>0 && n>0) {
395
396 Double_t p = (Double_t)nrChipHits/nrPixels/n;
397
398 // probability of falsely assigning a dead pixel
399 Double_t falselyDeadProb = 1;
400 Int_t falselyDeadProbExp = 0;
401 for (UInt_t i=0; i<n; i++) {
402 falselyDeadProb*=(1-p);
403 Exponent(falselyDeadProb,falselyDeadProbExp);
404 // can we find dead pixels...?
405 if (falselyDeadProbExp<fThreshDeadExp || (falselyDeadProbExp==fThreshDeadExp && falselyDeadProb<fThreshDead)) {
406 fNrEnoughStatChips++;
407 good=kTRUE;
408 // add dead pixels to handler
409 fHandler->AddDeadFrom(deadPixelHandler);
410 break;
411 }
412 }
413 if (!good) {
414 // this might be an inefficient chip
415 possiblyIneff->Insert(hs*10+chip,nrChipHits);
416 }
6727e2db 417
b696414b 418 }
419 else {
420 if (n>0) {
421 // this is a completely noisy chip... put in category enough stat
422 fNrEnoughStatChips++;
423 good=kTRUE;
424 }
425 }
6727e2db 426
b696414b 427 // printf("%3d",good);
428 // if (chip==9) printf("\n");
6727e2db 429
6727e2db 430 }
b696414b 431 } // for chip
432 }
6727e2db 433 } // for hs
b696414b 434
435 delete deadPixelHandler;
6727e2db 436
b696414b 437 Int_t key,val;
6727e2db 438 // dead chips?
439 if (fNrEqHits>fMinNrEqHitsForDeadChips) {
b696414b 440 while (possiblyDead->Pop(key,val)) {
441 fHandler->ActivateChip(GetEqNr(),key,val,kFALSE);
442 }
443 fNrDeadChips+=nrPossiblyDeadChips;
6727e2db 444 }
b696414b 445 delete possiblyDead;
6727e2db 446
447 // inefficient chips?
6727e2db 448 while (possiblyIneff->Pop(key,val)) {
449 if (val<fNrEqHits/60*fRatioToMeanForInefficientChip) {
450 fNrInefficientChips++;
451 }
452 }
453 delete possiblyIneff;
454
455
456 fbDeadProcessed = kTRUE;
457
458 return fNrEnoughStatChips;
459}
460
461
462UInt_t AliITSOnlineSPDphysAnalyzer::GetNrEnoughStatChips() {
463 // returns nr of enough stat chips
464 if (!fbDeadProcessed) ProcessDeadPixels();
465 return fNrEnoughStatChips;
466}
467UInt_t AliITSOnlineSPDphysAnalyzer::GetNrDeadChips() {
468 // returns nr of dead chips
469 if (!fbDeadProcessed) ProcessDeadPixels();
470 return fNrDeadChips;
471}
472UInt_t AliITSOnlineSPDphysAnalyzer::GetNrInefficientChips() {
473 // returns nr of inefficient chips
474 if (!fbDeadProcessed) ProcessDeadPixels();
475 return fNrInefficientChips;
476}
477UInt_t AliITSOnlineSPDphysAnalyzer::GetNrNeedsMoreStatChips() {
478 // returns nr of needs more stat chips
479 if (!fbDeadProcessed) ProcessDeadPixels();
480 return 60-fNrEnoughStatChips-fNrDeadChips-fNrInefficientChips;
481}
482
483UInt_t AliITSOnlineSPDphysAnalyzer::GetEqNr() const {
484 // returns the eq nr of phys obj
485 if (fPhysObj!=NULL) return fPhysObj->GetEqNr();
486 else return 999;
487}
488
489UInt_t AliITSOnlineSPDphysAnalyzer::GetNrEvents() const {
490 // returns the nr of events of phys obj
491 if (fPhysObj!=NULL) return fPhysObj->GetNrEvents();
492 else return 0;
493}
494
495void AliITSOnlineSPDphysAnalyzer::Exponent(Double_t &val, Int_t &valExp) const {
496 // put double in format with val and exp so that 1<val<10 - The actual value is val*10e(valExp)
497 while (val>10) {
498 val/=10;
499 valExp++;
500 }
501 while (val<1) {
502 val*=10;
503 valExp--;
504 }
505}
506
507
508
509TH2F* AliITSOnlineSPDphysAnalyzer::GetHitMapTot() {
510 // creates and returns a pointer to a hitmap histo (half sector style a la spdmood)
511 if (fPhysObj==NULL) {
512 Error("AliITSOnlineSPDphysAnalyzer::GetHitMapTot","No data!");
513 return NULL;
514 }
515 TString histoname = Form("Eq %d",GetEqNr());
516 TH2F* fHitMapTot = new TH2F(histoname.Data(),histoname.Data(),32*10,-0.5,32*10-0.5,256*6,-0.5,256*6-0.5);
517 fHitMapTot->SetNdivisions(-10,"X");
518 fHitMapTot->SetNdivisions(-006,"Y");
519 fHitMapTot->SetTickLength(0,"X");
520 fHitMapTot->SetTickLength(0,"Y");
521 fHitMapTot->GetXaxis()->SetLabelColor(gStyle->GetCanvasColor());
522 fHitMapTot->GetYaxis()->SetLabelColor(gStyle->GetCanvasColor());
523 for (UInt_t hs=0; hs<6; hs++) {
524 for (UInt_t chipNr=0; chipNr<10; chipNr++) {
525 for (UInt_t col=0; col<32; col++) {
526 for (UInt_t row=0; row<256; row++) {
527 fHitMapTot->Fill(chipNr*32+col,(5-hs)*256+row,fPhysObj->GetHits(hs,chipNr,col,row));
528 }
529 }
530 }
531 }
532 return fHitMapTot;
533}
534
535TH2F* AliITSOnlineSPDphysAnalyzer::GetHitMapChip(UInt_t hs, UInt_t chip) {
536 // creates and returns a pointer to a hitmap histo (chip style a la spdmood)
537 if (fPhysObj==NULL) {
538 Error("AliITSOnlineSPDphysAnalyzer::GetHitMapChip","No data!");
539 return NULL;
540 }
541
542 TString histoName;
543 TString histoTitle;
544 histoName = Form("fChipHisto_%d_%d_%d", GetEqNr(), hs, chip);
545 histoTitle = Form("Eq ID %d, Half Stave %d, Chip %d", GetEqNr(), hs, chip);
546
547 TH2F *returnHisto = new TH2F(histoName.Data(), histoTitle.Data(), 32, -0.5, 31.5, 256, -0.5, 255.5);
548 returnHisto->SetMinimum(0);
549 for (UInt_t col=0; col<32; col++) {
550 for (UInt_t row=0; row<256; row++) {
551 returnHisto->Fill(col,row,fPhysObj->GetHits(hs,chip,col,row));
552 }
553 }
554
555 return returnHisto;
556}