]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSOnlineSDDInjectors.cxx
- fixing warnings/coverity
[u/mrichter/AliRoot.git] / ITS / AliITSOnlineSDDInjectors.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 #include <TFile.h>
16 #include "AliITSOnlineSDDInjectors.h"
17 #include "AliLog.h"
18 #include <TH2F.h>
19 #include <TF1.h>
20 #include <TGraphErrors.h>
21 #include <TMath.h>
22 #include <TString.h>
23
24 /* $Id$ */
25
26 ///////////////////////////////////////////////////////////////////
27 //                                                               //
28 // Implementation of the class used for SDD injector analysis    //
29 // Origin: F.Prino, Torino, prino@to.infn.it                     //
30 //                                                               //
31 ///////////////////////////////////////////////////////////////////
32
33 ClassImp(AliITSOnlineSDDInjectors)
34
35 const Float_t AliITSOnlineSDDInjectors::fgkSaturation = 1008.;
36 const Float_t AliITSOnlineSDDInjectors::fgkDefaultLThreshold = 5.;
37 const Float_t AliITSOnlineSDDInjectors::fgkDefaultHThreshold = 25.;
38 const Float_t AliITSOnlineSDDInjectors::fgkDefaultMinSpeed = 5.5;
39 const Float_t AliITSOnlineSDDInjectors::fgkDefaultMaxSpeed = 9.0;
40 const Float_t AliITSOnlineSDDInjectors::fgkDefaultMaxErr = 1.5;
41 const Int_t   AliITSOnlineSDDInjectors::fgkDefaultPolDegree = 3;
42 const Float_t AliITSOnlineSDDInjectors::fgkDefaultTimeStep = 50.;
43 const UShort_t AliITSOnlineSDDInjectors::fgkDefaultTbMin[kInjLines] = {10,50,100};
44 const UShort_t AliITSOnlineSDDInjectors::fgkDefaultTbMax[kInjLines] = {20,70,120};
45
46 //______________________________________________________________________
47 AliITSOnlineSDDInjectors::AliITSOnlineSDDInjectors():AliITSOnlineSDD(),fHisto(),fTbZero(0.),fRMSTbZero(0.),fNEvents(0),fParam(),fPolDegree(0),fActualPolDegree(0),fMinDriftSpeed(0.),fMaxDriftSpeed(0.),fMaxDriftSpeedErr(0.),fLowThreshold(0.),fHighThreshold(0.),fFirstPadForFit(0),fLastPadForFit(0),fPadStatusCutForFit(0),fTimeStep(0.),fUseTimeZeroSignal(kFALSE)
48 {
49   // default constructor
50   SetPositions();
51   SetDefaults();
52   SetTimeStep(fgkDefaultTimeStep);
53   for(Int_t i=0;i<kInjPads;i++){ 
54     fSumDriftSpeed[i]=0.;
55     fSumSqDriftSpeed[i]=0.;
56     fSumPadStatus[i]=0;
57     fSumPadStatusCut[i]=0;
58     fNEventsInPad[i]=0;
59   }
60   Reset();
61 }
62 //______________________________________________________________________
63 AliITSOnlineSDDInjectors::AliITSOnlineSDDInjectors(Int_t nddl, Int_t ncarlos, Int_t sid):AliITSOnlineSDD(nddl,ncarlos,sid),fHisto(),fTbZero(0.),fRMSTbZero(0.),fNEvents(0),fParam(),fPolDegree(0),fActualPolDegree(0),fMinDriftSpeed(0.),fMaxDriftSpeed(0.),fMaxDriftSpeedErr(0.),fLowThreshold(0.),fHighThreshold(0.),fFirstPadForFit(0),fLastPadForFit(0),fPadStatusCutForFit(0),fTimeStep(0.),fUseTimeZeroSignal(kFALSE)
64
65 // standard constructor
66   SetPositions();
67   SetDefaults();
68   SetTimeStep(fgkDefaultTimeStep);
69   for(Int_t i=0;i<kInjPads;i++){ 
70     fSumDriftSpeed[i]=0.;
71     fSumSqDriftSpeed[i]=0.;
72     fSumPadStatus[i]=0;
73     fSumPadStatusCut[i]=0;
74     fNEventsInPad[i]=0;
75   }
76   Reset();
77 }
78 //______________________________________________________________________
79 AliITSOnlineSDDInjectors::~AliITSOnlineSDDInjectors(){
80   // Destructor
81   // fHisto should not be deleted here because it points to an histo created 
82   // by the external code which calls the method AnalyzeEvent
83   // if(fHisto) delete fHisto;  
84   if(fParam) delete [] fParam;
85 }
86 //______________________________________________________________________
87 void AliITSOnlineSDDInjectors::SetDefaults(){
88   for(Int_t i=0;i<kInjLines;i++) {
89     SetInjLineRange(i,fgkDefaultTbMin[i],fgkDefaultTbMax[i]);
90     SetUseLine(i,kTRUE);
91   }
92   SetThresholds(fgkDefaultLThreshold,fgkDefaultHThreshold);
93   SetPolDegree(fgkDefaultPolDegree);
94   SetMinDriftSpeed(fgkDefaultMinSpeed);
95   SetMaxDriftSpeed(fgkDefaultMaxSpeed);
96   SetMaxDriftSpeedErr(fgkDefaultMaxErr);
97   SetFitLimits(1,kInjPads-2); // exclude first and last pad
98   SetPadStatusCutForFit();
99 }
100 //______________________________________________________________________
101 void AliITSOnlineSDDInjectors::SetPositions(){
102   // 
103   Double_t xLinFromCenterUm[kInjLines]={31860.,17460.,660.};
104   Double_t xAnodeFromCenterUm=35085;
105   for(Int_t i=0;i<kInjLines;i++){
106     fPosition[i]=xAnodeFromCenterUm-xLinFromCenterUm[i];
107     fPosition[i]/=10000.; // from microns to cm
108   }
109 }
110 //______________________________________________________________________
111 void AliITSOnlineSDDInjectors::Reset(){
112   //
113   for(Int_t i=0;i<kInjPads;i++){ 
114     fDriftSpeed[i]=0.;
115     fDriftSpeedErr[i]=0.;
116   }
117   for(Int_t i=0;i<kInjPads;i++){
118     for(Int_t j=0;j<kInjLines;j++){
119       fGoodInj[i][j]=0;
120       fCentroid[i][j]=0.;
121       fRMSCentroid[i][j]=0.;
122     }
123   }
124 }
125 //______________________________________________________________________
126 void AliITSOnlineSDDInjectors::AnalyzeEvent(TH2F* his){
127   //
128   AddEvent(his);
129   FitDriftSpeedVsAnode();
130 }
131 //______________________________________________________________________
132 void AliITSOnlineSDDInjectors::AddEvent(TH2F* his){
133   // Add the drift speed from current event to the average value
134   if(fNEvents==0){
135     for(Int_t i=0;i<kInjPads;i++){ 
136       fSumDriftSpeed[i]=0.;
137       fSumSqDriftSpeed[i]=0.;
138       fSumPadStatus[i]=0;
139       fSumPadStatusCut[i]=0;
140       fNEventsInPad[i]=0;
141     }
142   }
143   Reset();
144   fHisto=his;
145   FindGoodInjectors();
146   FindCentroids();
147   CalcTimeBinZero();
148   for(Int_t j=0;j<kInjPads;j++){ 
149     CalcDriftSpeed(j);
150     Int_t padStatus=GetInjPadStatus(j);
151     fSumPadStatus[j]+=padStatus;
152     if(padStatus>fPadStatusCutForFit){
153       fSumDriftSpeed[j]+=fDriftSpeed[j];
154       fSumSqDriftSpeed[j]+=fDriftSpeed[j]*fDriftSpeed[j];
155       fSumPadStatusCut[j]+=padStatus;
156       fNEventsInPad[j]++;
157     }
158   }
159   ++fNEvents;
160 }
161 //______________________________________________________________________
162 Double_t AliITSOnlineSDDInjectors::GetRMSDriftSpeed(Int_t ipad) const {
163   // 
164   if(fNEventsInPad[ipad]<=1) return 0.;
165   Double_t mean=fSumDriftSpeed[ipad]/(Double_t)fNEventsInPad[ipad];
166   Double_t diff=fSumSqDriftSpeed[ipad]/(Double_t)fNEventsInPad[ipad]-mean*mean;
167   if(diff<0.) diff=0.;
168   return TMath::Sqrt(diff);
169 }
170
171 //______________________________________________________________________
172 void AliITSOnlineSDDInjectors::FitMeanDriftSpeedVsAnode(){
173   // Calculates
174   if(fNEvents==0) return;
175   for(Int_t i=0;i<kInjPads;i++){ 
176     fDriftSpeed[i]=GetMeanDriftSpeed(i);
177     Int_t padStatusCut=(Int_t)(GetMeanPadStatusCut(i)+0.5);
178     for(Int_t ilin=0; ilin<kInjLines ; ilin++) fGoodInj[i][ilin]=(padStatusCut&1<<ilin)>>ilin;
179     if(fNEventsInPad[i]>1){
180       Double_t rms=GetRMSDriftSpeed(i);
181       if(rms>0.) fDriftSpeedErr[i]=rms/TMath::Sqrt(fNEventsInPad[i]);
182     }else{
183       for(Int_t ilin=0; ilin<kInjLines ; ilin++) fGoodInj[i][ilin]=0;
184     }
185   }
186   FitDriftSpeedVsAnode();
187   for(Int_t i=0;i<kInjPads;i++){ 
188     Int_t padStatus=(Int_t)(GetMeanPadStatusCut(i)+0.5);
189     for(Int_t ilin=0; ilin<kInjLines ; ilin++) fGoodInj[i][ilin]=(padStatus&1<<ilin)>>ilin;
190   }
191 }
192 //______________________________________________________________________
193 TGraphErrors* AliITSOnlineSDDInjectors::GetTimeVsDistGraph(Int_t jpad) const{
194   // 
195   const Int_t kPts=kInjLines+1;
196   Float_t x[kPts],y[kPts],ex[kPts],ey[kPts];
197   x[0]=0.;
198   ex[0]=0.;
199   y[0]=fTbZero;
200   ey[0]=0.;
201   for(Int_t i=0;i<kInjLines;i++){
202     x[i+1]=fPosition[i];
203     ex[i+1]=0.;
204     y[i+1]=fCentroid[jpad][i];
205     ey[i+1]=fRMSCentroid[jpad][i];
206   }
207   TGraphErrors *g=new TGraphErrors(4,x,y,ex,ey);
208   return g;
209 }
210
211 //______________________________________________________________________
212 TGraphErrors* AliITSOnlineSDDInjectors::GetDriftSpeedGraph() const{
213   // 
214   Int_t ipt=0;
215   TGraphErrors *g=new TGraphErrors(0);
216   for(Int_t i=0;i<kInjPads;i++){
217     if(fDriftSpeed[i]>0){ 
218       g->SetPoint(ipt,GetAnodeNumber(i),fDriftSpeed[i]);
219       g->SetPointError(ipt,0,fDriftSpeedErr[i]);
220       ipt++;
221     }
222   }
223   return g;
224 }
225 //______________________________________________________________________
226 TGraphErrors* AliITSOnlineSDDInjectors::GetSelectedDriftSpeedGraph(Int_t minAcceptStatus) const{
227   // TGraphErrors with only pads with status of injector >= minAcceptStatus
228   Int_t ipt=0;
229   TGraphErrors *g=new TGraphErrors(0);
230   for(Int_t i=0;i<kInjPads;i++){
231     Int_t padStatus = GetInjPadStatus(i);
232     if(fDriftSpeed[i]>0 && padStatus >= minAcceptStatus ){
233       g->SetPoint(ipt,GetAnodeNumber(i),fDriftSpeed[i]);
234       g->SetPointError(ipt,0,fDriftSpeedErr[i]);
235       ipt++;
236     }
237   }
238   return g;
239 }
240 //______________________________________________________________________
241 void AliITSOnlineSDDInjectors::CalcTimeBinZero(){
242   // Get time zero from trigger signal
243   Double_t tzero=0.,intCont=0.,rmsPeak=0.;
244   Bool_t isTbUsed[256];
245   Int_t nTbUsed=0;
246   for(Int_t i=0;i<256;i++) isTbUsed[i]=0;
247   for(Int_t ian=0;ian<fgkNAnodes;ian++){
248     for(Int_t itb=1;itb<fTbMin[0];itb++){
249       Double_t cont=fHisto->GetBinContent(itb,ian+1);
250       Double_t contm1=fHisto->GetBinContent(itb+1,ian+1);
251       Double_t contp1=fHisto->GetBinContent(itb-1,ian+1);
252       if(cont>fLowThreshold){
253         if(contm1>fHighThreshold || cont>fHighThreshold || contp1>fHighThreshold){
254           tzero+=cont*float(itb);
255           rmsPeak+=cont*float(itb)*float(itb);
256           intCont+=cont;
257           if(!isTbUsed[itb]){
258             isTbUsed[itb]=1;
259             ++nTbUsed;
260           }
261         }
262       }
263     }
264   }
265   if(intCont>0){ 
266     fTbZero=tzero/intCont;
267     fRMSTbZero=TMath::Sqrt(rmsPeak/intCont-fTbZero*fTbZero);
268   }
269   if(nTbUsed==1) fRMSTbZero=0.5; 
270 }
271
272 //______________________________________________________________________
273 void AliITSOnlineSDDInjectors::FitDriftSpeedVsAnode(){
274   // fits the anode dependence of drift speed
275
276   Float_t rangeForMax[2]={78.,178.};
277   PolyFit(fPolDegree);
278   fActualPolDegree=fPolDegree;
279   if(fPolDegree==3){
280     Double_t deltasq=fParam[2]*fParam[2]-3*fParam[1]*fParam[3];
281     Double_t zero1=-999.;
282     Double_t zero2=-999.;
283     if(deltasq>=0. && TMath::Abs(fParam[3])>0.){
284       Double_t delta=TMath::Sqrt(deltasq);
285       zero1=(-fParam[2]+delta)/3./fParam[3];
286       zero2=(-fParam[2]-delta)/3./fParam[3];
287     }
288     Bool_t twoZeroes=kFALSE;
289     Bool_t oneZero=kFALSE;
290     if(zero1>0. && zero1<256. && zero2>0. && zero2<256.) twoZeroes=kTRUE;
291     if(zero1>rangeForMax[0] && zero1<rangeForMax[1]) oneZero=kTRUE;
292     if(zero2>rangeForMax[0] && zero2<rangeForMax[1]) oneZero=kTRUE;
293     if(!oneZero || twoZeroes){
294       PolyFit(2);
295       Double_t xmax=-999.;
296       if(fParam[2]<0.) xmax=-fParam[1]/2./fParam[2];
297       if(xmax>rangeForMax[0] && xmax<rangeForMax[1]){
298         fActualPolDegree=2;
299       }else{
300         Double_t averSpeed=0.;
301         Double_t sumWei=0.;
302         Int_t nUsedPts=0;
303         for(Int_t jpad=fFirstPadForFit; jpad<=fLastPadForFit; jpad++){
304           if(fDriftSpeed[jpad]>0 && GetInjPadStatus(jpad)>fPadStatusCutForFit){
305             Double_t wei=1./fDriftSpeedErr[jpad]/fDriftSpeedErr[jpad];
306             averSpeed+=wei*fDriftSpeed[jpad];
307             sumWei+=wei;
308             nUsedPts++;
309           }
310         }
311         if(sumWei>0.) averSpeed/=sumWei;
312         if(nUsedPts<fPolDegree+1) averSpeed=0;
313         fParam[0]=averSpeed;
314         for(Int_t i=1; i < fPolDegree+1; i++) fParam[i]=0.;
315         fActualPolDegree=0;
316       }
317     }
318   }
319 }
320 //______________________________________________________________________
321 void AliITSOnlineSDDInjectors::PolyFit(Int_t degree){
322   // fits the anode dependence of drift speed with a polynomial function
323   const Int_t kNn=degree+1;
324   const Int_t kDimens=fPolDegree+1;
325
326   Double_t **mat = new Double_t*[kNn];
327   for(Int_t i=0; i < kNn; i++) mat[i] = new Double_t[kNn];
328   Double_t *vect = new Double_t[kNn];
329
330   for(Int_t k1=0;k1<kNn;k1++){
331     vect[k1]=0;
332     for(Int_t k2=0;k2<kNn;k2++){
333       mat[k1][k2]=0;
334     }
335   }
336   Int_t npts = 0;
337   for(Int_t k1=0;k1<kNn;k1++){
338     for(Int_t jpad=fFirstPadForFit; jpad<=fLastPadForFit; jpad++){
339       Double_t x=(Double_t)GetAnodeNumber(jpad);
340       if(fDriftSpeed[jpad]>0 && GetInjPadStatus(jpad)>fPadStatusCutForFit){
341         vect[k1]+=fDriftSpeed[jpad]*TMath::Power(x,k1)/TMath::Power(fDriftSpeedErr[jpad],2);    
342         if(k1==0) npts++;
343         for(Int_t k2=0;k2<kNn;k2++){
344           mat[k1][k2]+=TMath::Power(x,k1+k2)/TMath::Power(fDriftSpeedErr[jpad],2);
345         }
346       }
347     }
348   }
349   if(npts<fPolDegree+1){ 
350     if(fParam) delete [] fParam;
351     fParam=new Double_t[kDimens];
352     for(Int_t i=0; i<kDimens;i++)fParam[i]=0;
353   }else{
354     Int_t *iPivot = new Int_t[kNn];
355     Int_t *indxR = new Int_t[kNn];
356     Int_t *indxC = new Int_t[kNn];
357     for(Int_t i=0;i<kNn;i++) iPivot[i]=0;
358     Int_t iCol=-1,iRow=-1;
359     for(Int_t i=0;i<kNn;i++){
360       Double_t big=0.;
361       for(Int_t j=0;j<kNn;j++){
362         if(iPivot[j]!=1){
363           for(Int_t k=0;k<kNn;k++){
364             if(iPivot[k]==0){
365               if(TMath::Abs(mat[j][k])>=big){
366                 big=TMath::Abs(mat[j][k]);
367                 iRow=j;
368                 iCol=k;
369               }
370             }
371           }
372         }
373       }
374       iPivot[iCol]++;
375       Double_t aux;
376       if(iRow!=iCol){
377         for(Int_t l=0;l<kNn;l++){
378           aux=mat[iRow][l];
379           mat[iRow][l]=mat[iCol][l];
380           mat[iCol][l]=aux;
381         }
382         aux=vect[iRow];
383         vect[iRow]=vect[iCol];
384         vect[iCol]=aux;
385       }
386       indxR[i]=iRow;
387       indxC[i]=iCol;
388       if(mat[iCol][iCol]==0) break;
389       Double_t pivinv=1./mat[iCol][iCol];
390       mat[iCol][iCol]=1;
391       for(Int_t l=0;l<kNn;l++) mat[iCol][l]*=pivinv;
392       vect[iCol]*=pivinv;
393       for(Int_t m=0;m<kNn;m++){
394         if(m!=iCol){
395           aux=mat[m][iCol];
396           mat[m][iCol]=0;
397           for(Int_t n=0;n<kNn;n++) mat[m][n]-=mat[iCol][n]*aux;
398           vect[m]-=vect[iCol]*aux;
399         }
400       }    
401     }
402     delete [] iPivot;
403     delete [] indxR;
404     delete [] indxC;
405     
406   
407     if(fParam) delete [] fParam;
408     fParam=new Double_t[kDimens];
409     for(Int_t i=0; i<kNn;i++)fParam[i]=vect[i];
410     if(degree<fPolDegree) for(Int_t i=kNn; i<kDimens;i++)fParam[i]=0.;
411   }
412
413   for(Int_t i=0; i < kNn; i++) delete [] mat[i];
414   delete [] mat;
415   delete [] vect;
416 }
417 //______________________________________________________________________
418 void AliITSOnlineSDDInjectors::CalcDriftSpeed(Int_t jpad){
419   // 
420   Double_t sumY=0,sumX=0,sumXX=0,sumYY=0.,sumXY=0,sumWEI=0.;
421   Int_t npt=0;
422   Double_t y[kInjLines],ey[kInjLines];
423   Double_t tzero=0,erry=0;
424   for(Int_t i=0;i<kInjLines;i++){ 
425     y[i]=fCentroid[jpad][i];
426     ey[i]=fRMSCentroid[jpad][i];
427   }
428   for(Int_t i=0;i<kInjLines;i++){
429     if(!fUseLine[i]) continue;
430     if(fGoodInj[jpad][i] && ey[i]!=0){
431       sumY+=y[i]/ey[i]/ey[i];
432       sumX+=fPosition[i]/ey[i]/ey[i];
433       sumXX+=fPosition[i]*fPosition[i]/ey[i]/ey[i];
434       sumYY+=y[i]*y[i]/ey[i]/ey[i];
435       sumXY+=fPosition[i]*y[i]/ey[i]/ey[i];
436       sumWEI+=1./ey[i]/ey[i];
437       tzero=fTbZero/ey[i]/ey[i];
438       erry=ey[i]/ey[i]/ey[i];
439       npt++;
440     }
441   }
442   Double_t slope=0.,eslope=0.;
443   if(npt==1){
444     slope=(sumY-tzero)/sumX;
445     eslope=erry/sumX;
446   }
447   if(npt>1){ 
448     if(fUseTimeZeroSignal){
449       sumY+=fTbZero/fRMSTbZero/fRMSTbZero;
450       sumX+=0.;
451       sumXX+=0.;
452       sumYY+=fTbZero*fTbZero/fRMSTbZero/fRMSTbZero;
453       sumXY+=0.;
454       sumWEI+=1./fRMSTbZero/fRMSTbZero;
455     }
456     slope=(sumWEI*sumXY-sumY*sumX)/(sumWEI*sumXX-sumX*sumX);
457     eslope=TMath::Sqrt(sumWEI/(sumWEI*sumXX-sumX*sumX));
458   }
459
460   Double_t vel=0,evel=0;
461   if(slope!=0. && fTimeStep>0.){
462     vel=1./slope*10000./fTimeStep;// micron/ns
463     evel=eslope/slope/slope*10000./fTimeStep;// micron/ns
464   }
465   if(vel>fMaxDriftSpeed||vel<fMinDriftSpeed || evel>fMaxDriftSpeedErr){ 
466     vel=0.;
467     evel=0.;
468   }
469   fDriftSpeed[jpad]=vel;
470   fDriftSpeedErr[jpad]=evel;
471 }
472 //______________________________________________________________________
473 Int_t AliITSOnlineSDDInjectors::GetAnodeNumber(Int_t iInjPad) const{
474   // Injectors location along anodes:
475   // Side left  (UP)   - channel 0: injectors on anodes 0,7,15,...,247,255 
476   // Side right (DOWN) - channel 1: injectors on anodes 0,8,16,...,248,255 
477   Int_t ian=-1;
478   if(iInjPad>=kInjPads) return ian;
479   if(fSide==1){  // right side
480     ian=iInjPad*8;
481     if(iInjPad==32) ian--;
482   }else{         // left side
483     ian=iInjPad*8-1;
484     if(iInjPad==0) ian=0;
485   }
486   return ian;
487 }
488 //______________________________________________________________________
489 Int_t AliITSOnlineSDDInjectors::GetInjPadNumberFromAnode(Int_t nAnode) const{
490   //
491   Int_t iInjPad=-1;
492   if(fSide==1){  // right side
493     if(nAnode%8==0) iInjPad=nAnode/8;
494     if(nAnode==255) iInjPad=32;
495   }else{         // left side
496     if(nAnode%8==7) iInjPad=1+nAnode/8;
497     if(nAnode==0) iInjPad=0;
498   }
499   if(nAnode>=256) iInjPad=-1;
500   return iInjPad;
501 }
502 //______________________________________________________________________
503 Int_t AliITSOnlineSDDInjectors::GetInjPadStatus(Int_t jpad) const{
504   // returns an integer value with status of injector lines for given pad/anode
505   // status=7  -->  111  all injector are good
506   // status=6  -->  110  1st line (close to anodes) is bad, other two are good
507   // ....
508   // status=1  -->  001  only 1st line (close to anodes) good
509   // status=0  -->  000  all lines are bad
510   Int_t istatus=0;
511   if(jpad>=0 && jpad<kInjPads){
512     for(Int_t jlin=0;jlin<kInjLines;jlin++) istatus+=fGoodInj[jpad][jlin]<<jlin;
513   }
514   return istatus;
515 }
516 //______________________________________________________________________
517 void AliITSOnlineSDDInjectors::FindGoodInjectors(){
518   // 
519   for(Int_t jpad=0;jpad<kInjPads;jpad++){
520     Int_t ian=GetAnodeNumber(jpad);
521     for(Int_t jlin=0;jlin<kInjLines;jlin++){
522       for(Int_t jjj=fTbMin[jlin];jjj<fTbMax[jlin];jjj++){
523         Float_t c1=fHisto->GetBinContent(jjj,ian+1);
524         Float_t c2=fHisto->GetBinContent(jjj+1,ian+1);
525         //      Float_t c3=fHisto->GetBinContent(jjj+2,ian+1);
526         if(c1>fLowThreshold && c2>fLowThreshold){ 
527           if(c1>fHighThreshold || c2>fHighThreshold){
528             fGoodInj[jpad][jlin]=1;
529             break;
530           }
531         }
532       }
533     }
534   }
535 }
536 //______________________________________________________________________
537 void AliITSOnlineSDDInjectors::FindCentroids(){
538   // 
539   for(Int_t jpad=0;jpad<kInjPads;jpad++){
540     Int_t ian=GetAnodeNumber(jpad);
541     for(Int_t jlin=0;jlin<kInjLines;jlin++){
542       if(!fGoodInj[jpad][jlin]) continue;
543       Double_t maxcont=0;
544       Int_t ilmax=-1;
545       for(Int_t jjj=fTbMin[jlin];jjj<fTbMax[jlin];jjj++){
546         Double_t cont=fHisto->GetBinContent(jjj,ian+1);
547         if(cont>maxcont){
548           maxcont=cont;
549           ilmax=jjj;
550         }
551       }
552       Double_t intCont=0;
553       Int_t jjj=ilmax;
554       while(1){
555         Double_t cont=fHisto->GetBinContent(jjj,ian+1);
556         if(cont<fLowThreshold) break;
557         if(cont<fgkSaturation){
558           fCentroid[jpad][jlin]+=cont*(Double_t)jjj;
559           fRMSCentroid[jpad][jlin]+=cont*(Double_t)jjj*(Double_t)jjj;
560           intCont+=cont;
561         }
562         jjj--;
563       }
564       jjj=ilmax+1;
565       while(1){
566         Double_t cont=fHisto->GetBinContent(jjj,ian+1);
567         if(cont<fLowThreshold) break;
568         if(cont<fgkSaturation){
569           fCentroid[jpad][jlin]+=cont*float(jjj);
570           fRMSCentroid[jpad][jlin]+=cont*(Double_t)jjj*(Double_t)jjj;
571           intCont+=cont;
572         }
573         jjj++;
574       }
575       if(intCont>0){ 
576         fCentroid[jpad][jlin]/=intCont;
577         fRMSCentroid[jpad][jlin]=TMath::Sqrt(fRMSCentroid[jpad][jlin]/intCont-fCentroid[jpad][jlin]*fCentroid[jpad][jlin])/TMath::Sqrt(intCont);
578       }
579       else{ 
580         fCentroid[jpad][jlin]=0.;
581         fRMSCentroid[jpad][jlin]=0.;
582         fGoodInj[jpad][jlin]=0;
583       }
584       if(fRMSCentroid[jpad][jlin]==0) fGoodInj[jpad][jlin]=0;
585     }
586   }
587 }
588 //______________________________________________________________________
589 void AliITSOnlineSDDInjectors::PrintInjectorStatus(){
590   //
591   for(Int_t jpad=0;jpad<kInjPads;jpad++){
592     printf("Line%d-Anode%d: %d %d %d\n",jpad,GetAnodeNumber(jpad),fGoodInj[jpad][0],fGoodInj[jpad][1],fGoodInj[jpad][2]);
593   }
594 }
595 //______________________________________________________________________
596 void AliITSOnlineSDDInjectors::PrintCentroids(){
597   //
598   for(Int_t jpad=0;jpad<kInjPads;jpad++){
599     printf("Line%d-Anode%d: %f+-%f %f+-%f %f+-%f\n",jpad,GetAnodeNumber(jpad),fCentroid[jpad][0],fRMSCentroid[jpad][0],fCentroid[jpad][1],fRMSCentroid[jpad][1],fCentroid[jpad][2],fRMSCentroid[jpad][2]);
600   }
601 }
602 //______________________________________________________________________
603 void AliITSOnlineSDDInjectors::WriteToASCII(Int_t evNumb, UInt_t timeStamp, Int_t optAppend){
604   //
605   TString outfilnam;
606   outfilnam.Form("SDDinj_ddl%02dc%02d_sid%d.data",fDDL,fCarlos,fSide);  
607   FILE* outf;
608   if(optAppend==0){ 
609     outf=fopen(outfilnam.Data(),"w");
610     fprintf(outf,"%d\n",fActualPolDegree);
611   }
612   else outf=fopen(outfilnam.Data(),"a");
613   fprintf(outf,"%d   %d   ",evNumb,timeStamp);
614   for(Int_t ic=0;ic<fPolDegree+1;ic++){
615     fprintf(outf,"%G ",fParam[ic]);
616   }
617   fprintf(outf,"\n");
618   fclose(outf);  
619 }
620 //______________________________________________________________________
621 TH1F* AliITSOnlineSDDInjectors::GetMeanDriftSpeedVsPadHisto() const{
622   TString hisnam;
623   hisnam.Form("hdrsp%02dc%02ds%d",fDDL,fCarlos,fSide);
624   TH1F* h=new TH1F(hisnam.Data(),"",kInjPads,-0.5,kInjPads-0.5);
625   if(fNEvents>0){
626     for(Int_t i=0;i<kInjPads;i++){ 
627       h->SetBinContent(i+1,GetMeanDriftSpeed(i));    
628       Double_t rms=GetRMSDriftSpeed(i);
629       Double_t err=0.;
630       if(rms>0.) err=rms/TMath::Sqrt(fNEventsInPad[i]);
631       h->SetBinError(i+1,err);
632     }
633   }
634   return h;
635 }
636 //______________________________________________________________________
637 Bool_t AliITSOnlineSDDInjectors::WriteToROOT(TFile *fil) const {
638   //
639   if(fil==0){ 
640     AliWarning("Invalid pointer to ROOT file");
641     return kFALSE;    
642   }  
643   TString hisnam;
644   fil->cd();
645   hisnam.Form("hdrsp%02dc%02ds%d",fDDL,fCarlos,fSide);
646   TH1F hdsp(hisnam.Data(),"",kInjPads,-0.5,kInjPads-0.5);
647   if(fNEvents==0){
648     AliWarning("Zero analyzed events");
649     return kFALSE;    
650   }  
651     
652   for(Int_t i=0;i<kInjPads;i++){ 
653     hdsp.SetBinContent(i+1,GetMeanDriftSpeed(i));    
654     Double_t rms=GetRMSDriftSpeed(i);
655     Double_t err=0.;
656     if(rms>0.) err=rms/TMath::Sqrt(fNEventsInPad[i]);
657     hdsp.SetBinError(i+1,err);
658   }
659   hdsp.Write();
660   return kTRUE;    
661 }
662 //______________________________________________________________________
663 void AliITSOnlineSDDInjectors::WriteInjectorStatusToASCII(){
664   // dump status of injectors encoded into UInt_t
665   // 5 bits (value 0-31) to store number of pads with given status
666   TString outfilnam;
667   outfilnam.Form("SDDinj_ddl%02dc%02d_sid%d.data",fDDL,fCarlos,fSide);  
668   FILE* outf=fopen(outfilnam.Data(),"a");
669   Int_t n[8]={0,0,0,0,0,0,0,0};
670   for(Int_t jpad=fFirstPadForFit; jpad<=fLastPadForFit; jpad++){
671     Int_t statusPad=GetInjPadStatus(jpad);
672     ++n[statusPad];
673   }
674   UInt_t statusInj=0;
675   statusInj+=(n[7]&0x1F)<<25; // bits 25-29: n. of pads with status 7
676   statusInj+=(n[6]&0x1F)<<20; // bits 20-24: n. of pads with status 6
677   statusInj+=(n[5]&0x1F)<<15; // bits 15-19: n. of pads with status 5
678   statusInj+=(n[4]&0x1F)<<10; // bits 10-14: n. of pads with status 4
679   statusInj+=(n[3]&0x1F)<<5;  // bits  5- 9: n. of pads with status 3
680   statusInj+=(n[2]&0x1F);     // bits  0- 4: n. of pads with status 2
681
682   fprintf(outf,"-99 %u\n",statusInj); // -99 used in preprocessor to find line
683                                       // with injector status info
684   fclose(outf);  
685   
686 }