1 /**************************************************************************
2 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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"
17 #include <TGraphErrors.h>
22 ///////////////////////////////////////////////////////////////////
24 // Implementation of the class used for SDD injector analysis //
25 // Origin: F.Prino, Torino, prino@to.infn.it //
27 ///////////////////////////////////////////////////////////////////
29 ClassImp(AliITSOnlineSDDInjectors)
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};
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)
44 // default constructor
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)
51 // standard constructor
55 //______________________________________________________________________
56 AliITSOnlineSDDInjectors::~AliITSOnlineSDDInjectors(){
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;
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();
75 //______________________________________________________________________
76 void AliITSOnlineSDDInjectors::SetPositions(){
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
85 //______________________________________________________________________
86 void AliITSOnlineSDDInjectors::Reset(){
88 for(Int_t i=0;i<kInjPads;i++){
92 for(Int_t i=0;i<kInjPads;i++){
93 for(Int_t j=0;j<kInjLines;j++){
96 fRMSCentroid[i][j]=0.;
100 //______________________________________________________________________
101 void AliITSOnlineSDDInjectors::AnalyzeEvent(TH2F* his){
108 for(Int_t j=0;j<kInjPads;j++) CalcDriftSpeed(j);
109 FitDriftSpeedVsAnode();
111 //______________________________________________________________________
112 TGraphErrors* AliITSOnlineSDDInjectors::GetTimeVsDistGraph(Int_t jpad) const{
114 const Int_t kPts=kInjLines+1;
115 Float_t x[kPts],y[kPts],ex[kPts],ey[kPts];
120 for(Int_t i=0;i<kInjLines;i++){
123 y[i+1]=fCentroid[jpad][i];
124 ey[i+1]=fRMSCentroid[jpad][i];
126 TGraphErrors *g=new TGraphErrors(4,x,y,ex,ey);
130 //______________________________________________________________________
131 TGraphErrors* AliITSOnlineSDDInjectors::GetDriftSpeedGraph() const{
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]);
144 //______________________________________________________________________
145 TGraphErrors* AliITSOnlineSDDInjectors::GetSelectedDriftSpeedGraph(Int_t minAcceptStatus) const{
146 // TGraphErrors with only pads with status of injector >= minAcceptStatus
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]);
159 //______________________________________________________________________
160 void AliITSOnlineSDDInjectors::CalcTimeBinZero(){
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);
172 if(intCont>0) fTbZero=tzero/intCont;
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];
182 for(Int_t k1=0;k1<kNn;k1++){
184 for(Int_t k2=0;k2<kNn;k2++){
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);
195 for(Int_t k2=0;k2<kNn;k2++){
196 mat[k1][k2]+=TMath::Power(x,k1+k2)/TMath::Power(fDriftSpeedErr[jpad],2);
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;
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++){
213 for(Int_t j=0;j<kNn;j++){
215 for(Int_t k=0;k<kNn;k++){
217 if(TMath::Abs(mat[j][k])>=big){
218 big=TMath::Abs(mat[j][k]);
229 for(Int_t l=0;l<kNn;l++){
231 mat[iRow][l]=mat[iCol][l];
235 vect[iRow]=vect[iCol];
240 if(mat[iCol][iCol]==0) break;
241 Float_t pivinv=1./mat[iCol][iCol];
243 for(Int_t l=0;l<kNn;l++) mat[iCol][l]*=pivinv;
245 for(Int_t m=0;m<kNn;m++){
249 for(Int_t n=0;n<kNn;n++) mat[m][n]-=mat[iCol][n]*aux;
250 vect[m]-=vect[iCol]*aux;
259 if(fParam) delete [] fParam;
260 fParam=new Float_t[kNn];
261 for(Int_t i=0; i<kNn;i++)fParam[i]=vect[i];
264 for(Int_t i=0; i < kNn; i++) delete [] mat[i];
268 //______________________________________________________________________
269 void AliITSOnlineSDDInjectors::CalcDriftSpeed(Int_t jpad){
271 Float_t sumY=0,sumX=0,sumXX=0,sumYY=0.,sumXY=0,sumWEI=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];
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];
292 Float_t vel=0,evel=0;
294 Float_t slope=(sumWEI*sumXY-sumY*sumX)/(sumWEI*sumXX-sumX*sumX);
295 Float_t eslope=TMath::Sqrt(sumWEI/(sumWEI*sumXX-sumX*sumX));
297 vel=1./slope*10000./25.;// micron/ns
298 evel=eslope/slope/slope*10000./25.;// micron/ns
302 Float_t slope=(sumY-tzero)/sumX;
303 Float_t eslope=erry/sumX;
305 vel=1./slope*10000./25.;// micron/ns
306 evel=eslope/slope/slope*10000./25.;// micron/ns
309 if(vel>fMaxDriftSpeed||vel<fMinDriftSpeed || evel>fMaxDriftSpeedErr){
313 fDriftSpeed[jpad]=vel;
314 fDriftSpeedErr[jpad]=evel;
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
322 if(iInjPad>=kInjPads) return ian;
323 if(fSide==1){ // right side
325 if(iInjPad==32) ian--;
328 if(iInjPad==0) ian=0;
332 //______________________________________________________________________
333 Int_t AliITSOnlineSDDInjectors::GetInjPadNumberFromAnode(Int_t nAnode) const{
336 if(fSide==1){ // right side
337 if(nAnode%8==0) iInjPad=nAnode/8;
338 if(nAnode==255) iInjPad=32;
340 if(nAnode%8==7) iInjPad=1+nAnode/8;
341 if(nAnode==0) iInjPad=0;
343 if(nAnode>=256) iInjPad=-1;
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
352 // status=1 --> 001 only 1st line (close to anodes) good
353 // status=0 --> 000 all lines are bad
355 if(jpad>=0 && jpad<kInjPads){
356 for(Int_t jlin=0;jlin<kInjLines;jlin++) istatus+=fGoodInj[jpad][jlin]<<jlin;
360 //______________________________________________________________________
361 void AliITSOnlineSDDInjectors::FindGoodInjectors(){
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;
378 //______________________________________________________________________
379 void AliITSOnlineSDDInjectors::FindCentroids(){
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;
387 for(Int_t jjj=fTbMin[jlin];jjj<fTbMax[jlin];jjj++){
388 Float_t cont=fHisto->GetBinContent(jjj,ian+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);
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);
418 fCentroid[jpad][jlin]/=intCont;
419 fRMSCentroid[jpad][jlin]=TMath::Sqrt(fRMSCentroid[jpad][jlin]/intCont-fCentroid[jpad][jlin]*fCentroid[jpad][jlin]);
422 fCentroid[jpad][jlin]=0.;
423 fRMSCentroid[jpad][jlin]=0.;
424 fGoodInj[jpad][jlin]=0;
426 if(fRMSCentroid[jpad][jlin]==0) fGoodInj[jpad][jlin]=0;
430 //______________________________________________________________________
431 void AliITSOnlineSDDInjectors::PrintInjectorStatus(){
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]);
437 //______________________________________________________________________
438 void AliITSOnlineSDDInjectors::PrintCentroids(){
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]);
444 //______________________________________________________________________
445 void AliITSOnlineSDDInjectors::WriteToASCII(Int_t evNumb, UInt_t timeStamp, Int_t optAppend){
447 Char_t outfilnam[100];
448 sprintf(outfilnam,"SDDinj_ddl%02dc%02d_sid%d.data",fDDL,fCarlos,fSide);
451 outf=fopen(outfilnam,"w");
452 fprintf(outf,"%d\n",fPolOrder);
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]);