]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSOnlineSDDInjectors.cxx
New selection cut for drift speed fit (F.Prino)
[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 "AliITSOnlineSDDInjectors.h"
16 #include <TH2F.h>
17 #include <TGraphErrors.h>
18 #include <TMath.h>
19
20 /* $Id$ */
21
22 ///////////////////////////////////////////////////////////////////
23 //                                                               //
24 // Implementation of the class used for SDD injector analysis    //
25 // Origin: F.Prino, Torino, prino@to.infn.it                     //
26 //                                                               //
27 ///////////////////////////////////////////////////////////////////
28
29 ClassImp(AliITSOnlineSDDInjectors)
30
31 const Float_t AliITSOnlineSDDInjectors::fgkSaturation = 1008.;
32 const Float_t AliITSOnlineSDDInjectors::fgkDefaultLThreshold = 5.;
33 const Float_t AliITSOnlineSDDInjectors::fgkDefaultHThreshold = 25.;
34 const Float_t AliITSOnlineSDDInjectors::fgkDefaultMinSpeed = 5.5;
35 const Float_t AliITSOnlineSDDInjectors::fgkDefaultMaxSpeed = 9.0;
36 const Float_t AliITSOnlineSDDInjectors::fgkDefaultMaxErr = 1.5;
37 const Int_t   AliITSOnlineSDDInjectors::fgkDefaultPolOrder = 3;
38 const UShort_t AliITSOnlineSDDInjectors::fgkDefaultTbMin[kInjLines] = {20,90,170};
39 const UShort_t AliITSOnlineSDDInjectors::fgkDefaultTbMax[kInjLines] = {50,160,240};
40
41 //______________________________________________________________________
42 AliITSOnlineSDDInjectors::AliITSOnlineSDDInjectors():AliITSOnlineSDD(),fHisto(),fTbZero(0.),fParam(),fPolOrder(0),fMinDriftSpeed(0.),fMaxDriftSpeed(0.),fMaxDriftSpeedErr(0.),fLowThreshold(0.),fHighThreshold(0.),fFirstPadForFit(0),fLastPadForFit(0),fPadStatusCutForFit(0)
43 {
44   // default constructor
45   SetPositions();
46   SetDefaults();
47 }
48 //______________________________________________________________________
49 AliITSOnlineSDDInjectors::AliITSOnlineSDDInjectors(Int_t nddl, Int_t ncarlos, Int_t sid):AliITSOnlineSDD(nddl,ncarlos,sid),fHisto(),fTbZero(0.),fParam(),fPolOrder(0),fMinDriftSpeed(0.),fMaxDriftSpeed(0.),fMaxDriftSpeedErr(0.),fLowThreshold(0.),fHighThreshold(0.),fFirstPadForFit(0),fLastPadForFit(0),fPadStatusCutForFit(0)
50
51 // standard constructor
52   SetPositions();
53   SetDefaults();
54 }
55 //______________________________________________________________________
56 AliITSOnlineSDDInjectors::~AliITSOnlineSDDInjectors(){
57   // Destructor
58   // fHisto should not be deleted here because it points to an histo created 
59   // by the external code which calls the method AnalyzeEvent
60   // if(fHisto) delete fHisto;  
61   if(fParam) delete [] fParam;
62 }
63 //______________________________________________________________________
64 void AliITSOnlineSDDInjectors::SetDefaults(){
65   for(Int_t i=0;i<kInjLines;i++) 
66     SetInjLineRange(i,fgkDefaultTbMin[i],fgkDefaultTbMax[i]);
67   SetThresholds(fgkDefaultLThreshold,fgkDefaultHThreshold);
68   SetPolOrder(fgkDefaultPolOrder);
69   SetMinDriftSpeed(fgkDefaultMinSpeed);
70   SetMaxDriftSpeed(fgkDefaultMaxSpeed);
71   SetMaxDriftSpeedErr(fgkDefaultMaxErr);
72   SetFitLimits(1,kInjPads-2); // exclude first and last pad
73   SetPadStatusCutForFit();
74 }
75 //______________________________________________________________________
76 void AliITSOnlineSDDInjectors::SetPositions(){
77   // 
78   Float_t xLinFromCenterUm[kInjLines]={31860.,17460.,660.};
79   Float_t xAnodeFromCenterUm=35085;
80   for(Int_t i=0;i<kInjLines;i++){
81     fPosition[i]=xAnodeFromCenterUm-xLinFromCenterUm[i];
82     fPosition[i]/=10000.; // from microns to cm
83   }
84 }
85 //______________________________________________________________________
86 void AliITSOnlineSDDInjectors::Reset(){
87   //
88   for(Int_t i=0;i<kInjPads;i++){ 
89     fDriftSpeed[i]=0.;
90     fDriftSpeedErr[i]=0.;
91   }
92   for(Int_t i=0;i<kInjPads;i++){
93     for(Int_t j=0;j<kInjLines;j++){
94       fGoodInj[i][j]=0;
95       fCentroid[i][j]=0.;
96       fRMSCentroid[i][j]=0.;
97     }
98   }
99 }
100 //______________________________________________________________________
101 void AliITSOnlineSDDInjectors::AnalyzeEvent(TH2F* his){
102   //
103   Reset();
104   fHisto=his;
105   FindGoodInjectors();
106   FindCentroids();
107   CalcTimeBinZero();
108   for(Int_t j=0;j<kInjPads;j++) CalcDriftSpeed(j);
109   FitDriftSpeedVsAnode();
110 }
111 //______________________________________________________________________
112 TGraphErrors* AliITSOnlineSDDInjectors::GetTimeVsDistGraph(Int_t jpad) const{
113   // 
114   const Int_t kPts=kInjLines+1;
115   Float_t x[kPts],y[kPts],ex[kPts],ey[kPts];
116   x[0]=0.;
117   ex[0]=0.;
118   y[0]=fTbZero;
119   ey[0]=0.;
120   for(Int_t i=0;i<kInjLines;i++){
121     x[i+1]=fPosition[i];
122     ex[i+1]=0.;
123     y[i+1]=fCentroid[jpad][i];
124     ey[i+1]=fRMSCentroid[jpad][i];
125   }
126   TGraphErrors *g=new TGraphErrors(4,x,y,ex,ey);
127   return g;
128 }
129
130 //______________________________________________________________________
131 TGraphErrors* AliITSOnlineSDDInjectors::GetDriftSpeedGraph() const{
132   // 
133   Int_t ipt=0;
134   TGraphErrors *g=new TGraphErrors(0);
135   for(Int_t i=0;i<kInjPads;i++){
136     if(fDriftSpeed[i]>0){ 
137       g->SetPoint(ipt,GetAnodeNumber(i),fDriftSpeed[i]);
138       g->SetPointError(ipt,0,fDriftSpeedErr[i]);
139       ipt++;
140     }
141   }
142   return g;
143 }
144 //______________________________________________________________________
145 TGraphErrors* AliITSOnlineSDDInjectors::GetSelectedDriftSpeedGraph(Int_t minAcceptStatus) const{
146   // TGraphErrors with only pads with status of injector >= minAcceptStatus
147   Int_t ipt=0;
148   TGraphErrors *g=new TGraphErrors(0);
149   for(Int_t i=0;i<kInjPads;i++){
150     Int_t padStatus = GetInjPadStatus(i);
151     if(fDriftSpeed[i]>0 && padStatus >= minAcceptStatus ){
152       g->SetPoint(ipt,GetAnodeNumber(i),fDriftSpeed[i]);
153       g->SetPointError(ipt,0,fDriftSpeedErr[i]);
154       ipt++;
155     }
156   }
157   return g;
158 }
159 //______________________________________________________________________
160 void AliITSOnlineSDDInjectors::CalcTimeBinZero(){
161   //
162   Float_t tzero=0.,intCont=0.;
163   for(Int_t ian=0;ian<fgkNAnodes;ian++){
164     for(Int_t itb=1;itb<fTbMin[0];itb++){
165       Float_t cont=fHisto->GetBinContent(itb,ian+1);
166       if(cont>fLowThreshold){
167         tzero+=cont*float(itb);
168         intCont+=cont;
169       }
170     }
171   }
172   if(intCont>0) fTbZero=tzero/intCont;
173 }
174 //______________________________________________________________________
175 void AliITSOnlineSDDInjectors::FitDriftSpeedVsAnode(){
176   // fits the anode dependence of drift speed with a polynomial function
177   const Int_t kNn=fPolOrder+1;
178   Float_t **mat = new Float_t*[kNn];
179   for(Int_t i=0; i < kNn; i++) mat[i] = new Float_t[kNn];
180   Float_t *vect = new Float_t[kNn];
181
182   for(Int_t k1=0;k1<kNn;k1++){
183     vect[k1]=0;
184     for(Int_t k2=0;k2<kNn;k2++){
185       mat[k1][k2]=0;
186     }
187   }
188   Int_t npts = 0;
189   for(Int_t k1=0;k1<kNn;k1++){
190     for(Int_t jpad=fFirstPadForFit; jpad<=fLastPadForFit; jpad++){
191       Float_t x=(Float_t)GetAnodeNumber(jpad);
192       if(fDriftSpeed[jpad]>0 && GetInjPadStatus(jpad)>fPadStatusCutForFit){
193           vect[k1]+=fDriftSpeed[jpad]*TMath::Power(x,k1)/TMath::Power(fDriftSpeedErr[jpad],2);  
194           if(k1==0) npts++;
195           for(Int_t k2=0;k2<kNn;k2++){
196             mat[k1][k2]+=TMath::Power(x,k1+k2)/TMath::Power(fDriftSpeedErr[jpad],2);
197           }
198       }
199     }
200   }
201   if(npts<fPolOrder+1){ 
202     if(fParam) delete [] fParam;
203     fParam=new Float_t[kNn];
204     for(Int_t i=0; i<kNn;i++)fParam[i]=0;
205   }else{
206     Int_t *iPivot = new Int_t[kNn];
207     Int_t *indxR = new Int_t[kNn];
208     Int_t *indxC = new Int_t[kNn];
209     for(Int_t i=0;i<kNn;i++) iPivot[i]=0;
210     Int_t iCol=-1,iRow=-1;
211     for(Int_t i=0;i<kNn;i++){
212       Float_t big=0.;
213       for(Int_t j=0;j<kNn;j++){
214         if(iPivot[j]!=1){
215           for(Int_t k=0;k<kNn;k++){
216             if(iPivot[k]==0){
217               if(TMath::Abs(mat[j][k])>=big){
218                 big=TMath::Abs(mat[j][k]);
219                 iRow=j;
220                 iCol=k;
221               }
222             }
223           }
224         }
225       }
226       iPivot[iCol]++;
227       Float_t aux;
228       if(iRow!=iCol){
229         for(Int_t l=0;l<kNn;l++){
230           aux=mat[iRow][l];
231           mat[iRow][l]=mat[iCol][l];
232           mat[iCol][l]=aux;
233         }
234         aux=vect[iRow];
235         vect[iRow]=vect[iCol];
236         vect[iCol]=aux;
237       }
238       indxR[i]=iRow;
239       indxC[i]=iCol;
240       if(mat[iCol][iCol]==0) break;
241       Float_t pivinv=1./mat[iCol][iCol];
242       mat[iCol][iCol]=1;
243       for(Int_t l=0;l<kNn;l++) mat[iCol][l]*=pivinv;
244       vect[iCol]*=pivinv;
245       for(Int_t m=0;m<kNn;m++){
246         if(m!=iCol){
247           aux=mat[m][iCol];
248           mat[m][iCol]=0;
249           for(Int_t n=0;n<kNn;n++) mat[m][n]-=mat[iCol][n]*aux;
250           vect[m]-=vect[iCol]*aux;
251         }
252       }    
253     }
254     delete [] iPivot;
255     delete [] indxR;
256     delete [] indxC;
257     
258   
259     if(fParam) delete [] fParam;
260     fParam=new Float_t[kNn];
261     for(Int_t i=0; i<kNn;i++)fParam[i]=vect[i];
262   }
263
264   for(Int_t i=0; i < kNn; i++) delete [] mat[i];
265   delete [] mat;
266   delete [] vect;
267 }
268 //______________________________________________________________________
269 void AliITSOnlineSDDInjectors::CalcDriftSpeed(Int_t jpad){
270   // 
271   Float_t sumY=0,sumX=0,sumXX=0,sumYY=0.,sumXY=0,sumWEI=0.;
272   Int_t npt=0;
273   Float_t y[kInjLines],ey[kInjLines];
274   Float_t tzero=0,erry=0;
275   for(Int_t i=0;i<kInjLines;i++){ 
276     y[i]=fCentroid[jpad][i];
277     ey[i]=fRMSCentroid[jpad][i];
278   }
279   for(Int_t i=0;i<kInjLines;i++){
280     if(fGoodInj[jpad][i] && ey[i]!=0){
281       sumY+=y[i]/ey[i]/ey[i];
282       sumX+=fPosition[i]/ey[i]/ey[i];
283       sumXX+=fPosition[i]*fPosition[i]/ey[i]/ey[i];
284       sumYY+=y[i]*y[i]/ey[i]/ey[i];
285       sumXY+=fPosition[i]*y[i]/ey[i]/ey[i];
286       sumWEI+=1./ey[i]/ey[i];
287       tzero=fTbZero/ey[i]/ey[i];
288       erry=ey[i];
289       npt++;
290     }
291   }
292   Float_t vel=0,evel=0;
293   if(npt>1){ 
294     Float_t slope=(sumWEI*sumXY-sumY*sumX)/(sumWEI*sumXX-sumX*sumX);
295     Float_t eslope=TMath::Sqrt(sumWEI/(sumWEI*sumXX-sumX*sumX));
296     if(slope!=0){
297       vel=1./slope*10000./25.;// micron/ns
298       evel=eslope/slope/slope*10000./25.;// micron/ns
299     }
300   }
301   if(npt==1){
302     Float_t slope=(sumY-tzero)/sumX;
303     Float_t eslope=erry/sumX;
304     if(slope!=0){
305       vel=1./slope*10000./25.;// micron/ns    
306       evel=eslope/slope/slope*10000./25.;// micron/ns
307     }
308   }
309   if(vel>fMaxDriftSpeed||vel<fMinDriftSpeed || evel>fMaxDriftSpeedErr){ 
310     vel=0.;
311     evel=0.;
312   }
313   fDriftSpeed[jpad]=vel;
314   fDriftSpeedErr[jpad]=evel;
315 }
316 //______________________________________________________________________
317 Int_t AliITSOnlineSDDInjectors::GetAnodeNumber(Int_t iInjPad) const{
318   // Injectors location along anodes:
319   // Side left  (UP)   - channel 0: injectors on anodes 0,7,15,...,247,255 
320   // Side right (DOWN) - channel 1: injectors on anodes 0,8,16,...,248,255 
321   Int_t ian=-1;
322   if(iInjPad>=kInjPads) return ian;
323   if(fSide==1){  // right side
324     ian=iInjPad*8;
325     if(iInjPad==32) ian--;
326   }else{         // left side
327     ian=iInjPad*8-1;
328     if(iInjPad==0) ian=0;
329   }
330   return ian;
331 }
332 //______________________________________________________________________
333 Int_t AliITSOnlineSDDInjectors::GetInjPadNumberFromAnode(Int_t nAnode) const{
334   //
335   Int_t iInjPad=-1;
336   if(fSide==1){  // right side
337     if(nAnode%8==0) iInjPad=nAnode/8;
338     if(nAnode==255) iInjPad=32;
339   }else{         // left side
340     if(nAnode%8==7) iInjPad=1+nAnode/8;
341     if(nAnode==0) iInjPad=0;
342   }
343   if(nAnode>=256) iInjPad=-1;
344   return iInjPad;
345 }
346 //______________________________________________________________________
347 Int_t AliITSOnlineSDDInjectors::GetInjPadStatus(Int_t jpad) const{
348   // returns an integer value with status of injector lines for given pad/anode
349   // status=7  -->  111  all injector are good
350   // status=6  -->  110  1st line (close to anodes) is bad, other two are good
351   // ....
352   // status=1  -->  001  only 1st line (close to anodes) good
353   // status=0  -->  000  all lines are bad
354   Int_t istatus=0;
355   if(jpad>=0 && jpad<kInjPads){
356     for(Int_t jlin=0;jlin<kInjLines;jlin++) istatus+=fGoodInj[jpad][jlin]<<jlin;
357   }
358   return istatus;
359 }
360 //______________________________________________________________________
361 void AliITSOnlineSDDInjectors::FindGoodInjectors(){
362   // 
363   for(Int_t jpad=0;jpad<kInjPads;jpad++){
364     Int_t ian=GetAnodeNumber(jpad);
365     for(Int_t jlin=0;jlin<kInjLines;jlin++){
366       for(Int_t jjj=fTbMin[jlin];jjj<fTbMax[jlin];jjj++){
367         Float_t c1=fHisto->GetBinContent(jjj,ian+1);
368         Float_t c2=fHisto->GetBinContent(jjj+1,ian+1);
369         Float_t c3=fHisto->GetBinContent(jjj+2,ian+1);
370         if(c1>fLowThreshold && c2>fHighThreshold && c3>fLowThreshold){ 
371           fGoodInj[jpad][jlin]=1;
372           break;
373         }
374       }
375     }
376   }
377 }
378 //______________________________________________________________________
379 void AliITSOnlineSDDInjectors::FindCentroids(){
380   // 
381   for(Int_t jpad=0;jpad<kInjPads;jpad++){
382     Int_t ian=GetAnodeNumber(jpad);
383     for(Int_t jlin=0;jlin<kInjLines;jlin++){
384       if(!fGoodInj[jpad][jlin]) continue;
385       Float_t maxcont=0;
386       Int_t ilmax=-1;
387       for(Int_t jjj=fTbMin[jlin];jjj<fTbMax[jlin];jjj++){
388         Float_t cont=fHisto->GetBinContent(jjj,ian+1);
389         if(cont>maxcont){
390           maxcont=cont;
391           ilmax=jjj;
392         }
393       }
394       Float_t intCont=0;
395       Int_t jjj=ilmax;
396       while(1){
397         Float_t cont=fHisto->GetBinContent(jjj,ian+1);
398         if(cont<fLowThreshold) break;
399         if(cont<fgkSaturation){
400           fCentroid[jpad][jlin]+=cont*(Float_t)jjj;
401           fRMSCentroid[jpad][jlin]+=cont*TMath::Power((Float_t)jjj,2);
402           intCont+=cont;
403         }
404         jjj--;
405       }
406       jjj=ilmax+1;
407       while(1){
408         Float_t cont=fHisto->GetBinContent(jjj,ian+1);
409         if(cont<fLowThreshold) break;
410         if(cont<fgkSaturation){
411           fCentroid[jpad][jlin]+=cont*float(jjj);
412           fRMSCentroid[jpad][jlin]+=cont*TMath::Power((Float_t)jjj,2);
413           intCont+=cont;
414         }
415         jjj++;
416       }
417       if(intCont>0){ 
418         fCentroid[jpad][jlin]/=intCont;
419         fRMSCentroid[jpad][jlin]=TMath::Sqrt(fRMSCentroid[jpad][jlin]/intCont-fCentroid[jpad][jlin]*fCentroid[jpad][jlin]);
420       }
421       else{ 
422         fCentroid[jpad][jlin]=0.;
423         fRMSCentroid[jpad][jlin]=0.;
424         fGoodInj[jpad][jlin]=0;
425       }
426       if(fRMSCentroid[jpad][jlin]==0) fGoodInj[jpad][jlin]=0;
427     }
428   }
429 }
430 //______________________________________________________________________
431 void AliITSOnlineSDDInjectors::PrintInjectorStatus(){
432   //
433   for(Int_t jpad=0;jpad<kInjPads;jpad++){
434     printf("Line%d-Anode%d: %d %d %d\n",jpad,GetAnodeNumber(jpad),fGoodInj[jpad][0],fGoodInj[jpad][1],fGoodInj[jpad][2]);
435   }
436 }
437 //______________________________________________________________________
438 void AliITSOnlineSDDInjectors::PrintCentroids(){
439   //
440   for(Int_t jpad=0;jpad<kInjPads;jpad++){
441     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]);
442   }
443 }
444 //______________________________________________________________________
445 void AliITSOnlineSDDInjectors::WriteToASCII(Int_t evNumb, UInt_t timeStamp, Int_t optAppend){
446   //
447   Char_t outfilnam[100];
448   sprintf(outfilnam,"SDDinj_ddl%02dc%02d_sid%d.data",fDDL,fCarlos,fSide);  
449   FILE* outf;
450   if(optAppend==0){ 
451     outf=fopen(outfilnam,"w");
452     fprintf(outf,"%d\n",fPolOrder);
453   }
454   else outf=fopen(outfilnam,"a");
455   fprintf(outf,"%d   %d   ",evNumb,timeStamp);
456   for(Int_t ic=0;ic<fPolOrder+1;ic++){
457     fprintf(outf,"%G ",fParam[ic]);
458   }
459   fprintf(outf,"\n");
460   fclose(outf);  
461 }