Coding conventions (E.Fragiacomo)
[u/mrichter/AliRoot.git] / ITS / AliITSOnlineSDDInjectors.cxx
CommitLineData
348f80b7 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 **************************************************************************/
456ec396 15#include <TFile.h>
348f80b7 16#include "AliITSOnlineSDDInjectors.h"
456ec396 17#include "AliLog.h"
348f80b7 18#include <TH2F.h>
915c0469 19#include <TF1.h>
348f80b7 20#include <TGraphErrors.h>
21#include <TMath.h>
c115d279 22#include <TString.h>
348f80b7 23
4c82df4c 24/* $Id$ */
25
348f80b7 26///////////////////////////////////////////////////////////////////
27// //
28// Implementation of the class used for SDD injector analysis //
29// Origin: F.Prino, Torino, prino@to.infn.it //
30// //
31///////////////////////////////////////////////////////////////////
32
33ClassImp(AliITSOnlineSDDInjectors)
34
35const Float_t AliITSOnlineSDDInjectors::fgkSaturation = 1008.;
9f026db8 36const Float_t AliITSOnlineSDDInjectors::fgkDefaultLThreshold = 5.;
37const Float_t AliITSOnlineSDDInjectors::fgkDefaultHThreshold = 25.;
38const Float_t AliITSOnlineSDDInjectors::fgkDefaultMinSpeed = 5.5;
39const Float_t AliITSOnlineSDDInjectors::fgkDefaultMaxSpeed = 9.0;
40const Float_t AliITSOnlineSDDInjectors::fgkDefaultMaxErr = 1.5;
915c0469 41const Int_t AliITSOnlineSDDInjectors::fgkDefaultPolDegree = 3;
f4e26d31 42const Float_t AliITSOnlineSDDInjectors::fgkDefaultTimeStep = 50.;
43const UShort_t AliITSOnlineSDDInjectors::fgkDefaultTbMin[kInjLines] = {10,50,100};
44const UShort_t AliITSOnlineSDDInjectors::fgkDefaultTbMax[kInjLines] = {20,70,120};
348f80b7 45
46//______________________________________________________________________
915c0469 47AliITSOnlineSDDInjectors::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)
348f80b7 48{
49 // default constructor
348f80b7 50 SetPositions();
9f026db8 51 SetDefaults();
f4e26d31 52 SetTimeStep(fgkDefaultTimeStep);
c115d279 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();
348f80b7 61}
62//______________________________________________________________________
915c0469 63AliITSOnlineSDDInjectors::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)
beb262b4 64{
65// standard constructor
348f80b7 66 SetPositions();
9f026db8 67 SetDefaults();
f4e26d31 68 SetTimeStep(fgkDefaultTimeStep);
c115d279 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();
348f80b7 77}
78//______________________________________________________________________
79AliITSOnlineSDDInjectors::~AliITSOnlineSDDInjectors(){
80 // Destructor
19f1458a 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;
348f80b7 84 if(fParam) delete [] fParam;
85}
86//______________________________________________________________________
9f026db8 87void AliITSOnlineSDDInjectors::SetDefaults(){
1397fe91 88 for(Int_t i=0;i<kInjLines;i++) {
9f026db8 89 SetInjLineRange(i,fgkDefaultTbMin[i],fgkDefaultTbMax[i]);
1397fe91 90 SetUseLine(i,kTRUE);
91 }
9f026db8 92 SetThresholds(fgkDefaultLThreshold,fgkDefaultHThreshold);
915c0469 93 SetPolDegree(fgkDefaultPolDegree);
9f026db8 94 SetMinDriftSpeed(fgkDefaultMinSpeed);
95 SetMaxDriftSpeed(fgkDefaultMaxSpeed);
96 SetMaxDriftSpeedErr(fgkDefaultMaxErr);
97 SetFitLimits(1,kInjPads-2); // exclude first and last pad
98 SetPadStatusCutForFit();
99}
100//______________________________________________________________________
348f80b7 101void AliITSOnlineSDDInjectors::SetPositions(){
102 //
2ca27861 103 Double_t xLinFromCenterUm[kInjLines]={31860.,17460.,660.};
104 Double_t xAnodeFromCenterUm=35085;
9f026db8 105 for(Int_t i=0;i<kInjLines;i++){
106 fPosition[i]=xAnodeFromCenterUm-xLinFromCenterUm[i];
348f80b7 107 fPosition[i]/=10000.; // from microns to cm
108 }
109}
110//______________________________________________________________________
111void AliITSOnlineSDDInjectors::Reset(){
beb262b4 112 //
9f026db8 113 for(Int_t i=0;i<kInjPads;i++){
114 fDriftSpeed[i]=0.;
115 fDriftSpeedErr[i]=0.;
348f80b7 116 }
9f026db8 117 for(Int_t i=0;i<kInjPads;i++){
118 for(Int_t j=0;j<kInjLines;j++){
348f80b7 119 fGoodInj[i][j]=0;
120 fCentroid[i][j]=0.;
121 fRMSCentroid[i][j]=0.;
122 }
123 }
124}
125//______________________________________________________________________
126void AliITSOnlineSDDInjectors::AnalyzeEvent(TH2F* his){
127 //
456ec396 128 AddEvent(his);
9f026db8 129 FitDriftSpeedVsAnode();
348f80b7 130}
131//______________________________________________________________________
2ca27861 132void 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.;
e89a0633 138 fSumPadStatus[i]=0;
139 fSumPadStatusCut[i]=0;
140 fNEventsInPad[i]=0;
2ca27861 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);
e89a0633 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 }
2ca27861 158 }
159 ++fNEvents;
160}
161//______________________________________________________________________
162Double_t AliITSOnlineSDDInjectors::GetRMSDriftSpeed(Int_t ipad) const {
163 //
e89a0633 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;
2ca27861 167 if(diff<0.) diff=0.;
168 return TMath::Sqrt(diff);
169}
170
171//______________________________________________________________________
172void AliITSOnlineSDDInjectors::FitMeanDriftSpeedVsAnode(){
173 // Calculates
174 if(fNEvents==0) return;
175 for(Int_t i=0;i<kInjPads;i++){
176 fDriftSpeed[i]=GetMeanDriftSpeed(i);
e89a0633 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){
2ca27861 180 Double_t rms=GetRMSDriftSpeed(i);
e89a0633 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;
2ca27861 184 }
185 }
186 FitDriftSpeedVsAnode();
e89a0633 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 }
2ca27861 191}
192//______________________________________________________________________
9f026db8 193TGraphErrors* AliITSOnlineSDDInjectors::GetTimeVsDistGraph(Int_t jpad) const{
348f80b7 194 //
9f026db8 195 const Int_t kPts=kInjLines+1;
196 Float_t x[kPts],y[kPts],ex[kPts],ey[kPts];
348f80b7 197 x[0]=0.;
198 ex[0]=0.;
199 y[0]=fTbZero;
200 ey[0]=0.;
9f026db8 201 for(Int_t i=0;i<kInjLines;i++){
348f80b7 202 x[i+1]=fPosition[i];
203 ex[i+1]=0.;
9f026db8 204 y[i+1]=fCentroid[jpad][i];
205 ey[i+1]=fRMSCentroid[jpad][i];
348f80b7 206 }
207 TGraphErrors *g=new TGraphErrors(4,x,y,ex,ey);
208 return g;
209}
9f026db8 210
348f80b7 211//______________________________________________________________________
9f026db8 212TGraphErrors* AliITSOnlineSDDInjectors::GetDriftSpeedGraph() const{
348f80b7 213 //
348f80b7 214 Int_t ipt=0;
215 TGraphErrors *g=new TGraphErrors(0);
9f026db8 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]);
348f80b7 220 ipt++;
221 }
222 }
223 return g;
224}
225//______________________________________________________________________
84df0230 226TGraphErrors* 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//______________________________________________________________________
348f80b7 241void AliITSOnlineSDDInjectors::CalcTimeBinZero(){
784a52ed 242 // Get time zero from trigger signal
2ca27861 243 Double_t tzero=0.,intCont=0.,rmsPeak=0.;
784a52ed 244 Bool_t isTbUsed[256];
245 Int_t nTbUsed=0;
246 for(Int_t i=0;i<256;i++) isTbUsed[i]=0;
348f80b7 247 for(Int_t ian=0;ian<fgkNAnodes;ian++){
248 for(Int_t itb=1;itb<fTbMin[0];itb++){
2ca27861 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);
9f026db8 252 if(cont>fLowThreshold){
784a52ed 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 }
348f80b7 262 }
263 }
264 }
784a52ed 265 if(intCont>0){
266 fTbZero=tzero/intCont;
267 fRMSTbZero=TMath::Sqrt(rmsPeak/intCont-fTbZero*fTbZero);
268 }
269 if(nTbUsed==1) fRMSTbZero=0.5;
348f80b7 270}
915c0469 271
348f80b7 272//______________________________________________________________________
9f026db8 273void AliITSOnlineSDDInjectors::FitDriftSpeedVsAnode(){
251c7c7c 274 // fits the anode dependence of drift speed
915c0469 275
915c0469 276 Float_t rangeForMax[2]={78.,178.};
251c7c7c 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 }
915c0469 310 }
251c7c7c 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;
915c0469 316 }
317 }
318 }
915c0469 319}
320//______________________________________________________________________
251c7c7c 321void AliITSOnlineSDDInjectors::PolyFit(Int_t degree){
915c0469 322 // fits the anode dependence of drift speed with a polynomial function
251c7c7c 323 const Int_t kNn=degree+1;
324 const Int_t kDimens=fPolDegree+1;
325
2ca27861 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];
9f026db8 329
4ff6aa93 330 for(Int_t k1=0;k1<kNn;k1++){
348f80b7 331 vect[k1]=0;
4ff6aa93 332 for(Int_t k2=0;k2<kNn;k2++){
348f80b7 333 mat[k1][k2]=0;
348f80b7 334 }
335 }
06bb3583 336 Int_t npts = 0;
4ff6aa93 337 for(Int_t k1=0;k1<kNn;k1++){
9f026db8 338 for(Int_t jpad=fFirstPadForFit; jpad<=fLastPadForFit; jpad++){
2ca27861 339 Double_t x=(Double_t)GetAnodeNumber(jpad);
9f026db8 340 if(fDriftSpeed[jpad]>0 && GetInjPadStatus(jpad)>fPadStatusCutForFit){
e89a0633 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 }
9f026db8 346 }
348f80b7 347 }
348 }
915c0469 349 if(npts<fPolDegree+1){
06bb3583 350 if(fParam) delete [] fParam;
251c7c7c 351 fParam=new Double_t[kDimens];
352 for(Int_t i=0; i<kDimens;i++)fParam[i]=0;
06bb3583 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++){
2ca27861 360 Double_t big=0.;
06bb3583 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 }
348f80b7 371 }
372 }
373 }
06bb3583 374 iPivot[iCol]++;
2ca27861 375 Double_t aux;
06bb3583 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;
348f80b7 385 }
06bb3583 386 indxR[i]=iRow;
387 indxC[i]=iCol;
388 if(mat[iCol][iCol]==0) break;
2ca27861 389 Double_t pivinv=1./mat[iCol][iCol];
06bb3583 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 }
348f80b7 401 }
06bb3583 402 delete [] iPivot;
403 delete [] indxR;
404 delete [] indxC;
405
406
407 if(fParam) delete [] fParam;
251c7c7c 408 fParam=new Double_t[kDimens];
06bb3583 409 for(Int_t i=0; i<kNn;i++)fParam[i]=vect[i];
251c7c7c 410 if(degree<fPolDegree) for(Int_t i=kNn; i<kDimens;i++)fParam[i]=0.;
348f80b7 411 }
348f80b7 412
4ff6aa93 413 for(Int_t i=0; i < kNn; i++) delete [] mat[i];
348f80b7 414 delete [] mat;
415 delete [] vect;
416}
417//______________________________________________________________________
9f026db8 418void AliITSOnlineSDDInjectors::CalcDriftSpeed(Int_t jpad){
348f80b7 419 //
2ca27861 420 Double_t sumY=0,sumX=0,sumXX=0,sumYY=0.,sumXY=0,sumWEI=0.;
348f80b7 421 Int_t npt=0;
2ca27861 422 Double_t y[kInjLines],ey[kInjLines];
423 Double_t tzero=0,erry=0;
9f026db8 424 for(Int_t i=0;i<kInjLines;i++){
425 y[i]=fCentroid[jpad][i];
426 ey[i]=fRMSCentroid[jpad][i];
348f80b7 427 }
9f026db8 428 for(Int_t i=0;i<kInjLines;i++){
1397fe91 429 if(!fUseLine[i]) continue;
9f026db8 430 if(fGoodInj[jpad][i] && ey[i]!=0){
348f80b7 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];
784a52ed 438 erry=ey[i]/ey[i]/ey[i];
348f80b7 439 npt++;
440 }
441 }
2ca27861 442 Double_t slope=0.,eslope=0.;
784a52ed 443 if(npt==1){
444 slope=(sumY-tzero)/sumX;
445 eslope=erry/sumX;
446 }
348f80b7 447 if(npt>1){
784a52ed 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;
53855521 455 }
784a52ed 456 slope=(sumWEI*sumXY-sumY*sumX)/(sumWEI*sumXX-sumX*sumX);
457 eslope=TMath::Sqrt(sumWEI/(sumWEI*sumXX-sumX*sumX));
348f80b7 458 }
784a52ed 459
2ca27861 460 Double_t vel=0,evel=0;
784a52ed 461 if(slope!=0. && fTimeStep>0.){
462 vel=1./slope*10000./fTimeStep;// micron/ns
463 evel=eslope/slope/slope*10000./fTimeStep;// micron/ns
348f80b7 464 }
9f026db8 465 if(vel>fMaxDriftSpeed||vel<fMinDriftSpeed || evel>fMaxDriftSpeedErr){
348f80b7 466 vel=0.;
467 evel=0.;
468 }
9f026db8 469 fDriftSpeed[jpad]=vel;
470 fDriftSpeedErr[jpad]=evel;
348f80b7 471}
472//______________________________________________________________________
9f026db8 473Int_t AliITSOnlineSDDInjectors::GetAnodeNumber(Int_t iInjPad) const{
61606350 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
348f80b7 477 Int_t ian=-1;
9f026db8 478 if(iInjPad>=kInjPads) return ian;
61606350 479 if(fSide==1){ // right side
9f026db8 480 ian=iInjPad*8;
481 if(iInjPad==32) ian--;
61606350 482 }else{ // left side
9f026db8 483 ian=iInjPad*8-1;
484 if(iInjPad==0) ian=0;
348f80b7 485 }
486 return ian;
487}
84c6e6c0 488//______________________________________________________________________
9f026db8 489Int_t AliITSOnlineSDDInjectors::GetInjPadNumberFromAnode(Int_t nAnode) const{
84c6e6c0 490 //
9f026db8 491 Int_t iInjPad=-1;
61606350 492 if(fSide==1){ // right side
9f026db8 493 if(nAnode%8==0) iInjPad=nAnode/8;
494 if(nAnode==255) iInjPad=32;
61606350 495 }else{ // left side
9f026db8 496 if(nAnode%8==7) iInjPad=1+nAnode/8;
497 if(nAnode==0) iInjPad=0;
84c6e6c0 498 }
9f026db8 499 if(nAnode>=256) iInjPad=-1;
500 return iInjPad;
84c6e6c0 501}
502//______________________________________________________________________
9f026db8 503Int_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
84c6e6c0 510 Int_t istatus=0;
9f026db8 511 if(jpad>=0 && jpad<kInjPads){
512 for(Int_t jlin=0;jlin<kInjLines;jlin++) istatus+=fGoodInj[jpad][jlin]<<jlin;
84c6e6c0 513 }
514 return istatus;
515}
348f80b7 516//______________________________________________________________________
517void AliITSOnlineSDDInjectors::FindGoodInjectors(){
518 //
9f026db8 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++){
348f80b7 523 Float_t c1=fHisto->GetBinContent(jjj,ian+1);
524 Float_t c2=fHisto->GetBinContent(jjj+1,ian+1);
a7996467 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 }
348f80b7 531 }
532 }
348f80b7 533 }
534 }
535}
536//______________________________________________________________________
537void AliITSOnlineSDDInjectors::FindCentroids(){
538 //
9f026db8 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;
2ca27861 543 Double_t maxcont=0;
348f80b7 544 Int_t ilmax=-1;
9f026db8 545 for(Int_t jjj=fTbMin[jlin];jjj<fTbMax[jlin];jjj++){
2ca27861 546 Double_t cont=fHisto->GetBinContent(jjj,ian+1);
348f80b7 547 if(cont>maxcont){
548 maxcont=cont;
549 ilmax=jjj;
550 }
551 }
2ca27861 552 Double_t intCont=0;
348f80b7 553 Int_t jjj=ilmax;
554 while(1){
2ca27861 555 Double_t cont=fHisto->GetBinContent(jjj,ian+1);
9f026db8 556 if(cont<fLowThreshold) break;
348f80b7 557 if(cont<fgkSaturation){
2ca27861 558 fCentroid[jpad][jlin]+=cont*(Double_t)jjj;
559 fRMSCentroid[jpad][jlin]+=cont*(Double_t)jjj*(Double_t)jjj;
348f80b7 560 intCont+=cont;
561 }
562 jjj--;
563 }
564 jjj=ilmax+1;
565 while(1){
2ca27861 566 Double_t cont=fHisto->GetBinContent(jjj,ian+1);
9f026db8 567 if(cont<fLowThreshold) break;
348f80b7 568 if(cont<fgkSaturation){
9f026db8 569 fCentroid[jpad][jlin]+=cont*float(jjj);
2ca27861 570 fRMSCentroid[jpad][jlin]+=cont*(Double_t)jjj*(Double_t)jjj;
348f80b7 571 intCont+=cont;
572 }
573 jjj++;
574 }
575 if(intCont>0){
9f026db8 576 fCentroid[jpad][jlin]/=intCont;
2ca27861 577 fRMSCentroid[jpad][jlin]=TMath::Sqrt(fRMSCentroid[jpad][jlin]/intCont-fCentroid[jpad][jlin]*fCentroid[jpad][jlin])/TMath::Sqrt(intCont);
348f80b7 578 }
579 else{
9f026db8 580 fCentroid[jpad][jlin]=0.;
581 fRMSCentroid[jpad][jlin]=0.;
582 fGoodInj[jpad][jlin]=0;
348f80b7 583 }
9f026db8 584 if(fRMSCentroid[jpad][jlin]==0) fGoodInj[jpad][jlin]=0;
348f80b7 585 }
586 }
587}
588//______________________________________________________________________
9f026db8 589void AliITSOnlineSDDInjectors::PrintInjectorStatus(){
348f80b7 590 //
9f026db8 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]);
348f80b7 593 }
594}
595//______________________________________________________________________
596void AliITSOnlineSDDInjectors::PrintCentroids(){
597 //
9f026db8 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]);
348f80b7 600 }
601}
602//______________________________________________________________________
4c82df4c 603void AliITSOnlineSDDInjectors::WriteToASCII(Int_t evNumb, UInt_t timeStamp, Int_t optAppend){
348f80b7 604 //
c115d279 605 TString outfilnam;
606 outfilnam.Form("SDDinj_ddl%02dc%02d_sid%d.data",fDDL,fCarlos,fSide);
4c82df4c 607 FILE* outf;
18da6e54 608 if(optAppend==0){
c115d279 609 outf=fopen(outfilnam.Data(),"w");
915c0469 610 fprintf(outf,"%d\n",fActualPolDegree);
18da6e54 611 }
c115d279 612 else outf=fopen(outfilnam.Data(),"a");
4c82df4c 613 fprintf(outf,"%d %d ",evNumb,timeStamp);
915c0469 614 for(Int_t ic=0;ic<fPolDegree+1;ic++){
348f80b7 615 fprintf(outf,"%G ",fParam[ic]);
616 }
617 fprintf(outf,"\n");
618 fclose(outf);
619}
456ec396 620//______________________________________________________________________
e5b2f7f2 621TH1F* AliITSOnlineSDDInjectors::GetMeanDriftSpeedVsPadHisto() const{
c115d279 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);
e5b2f7f2 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.;
e89a0633 630 if(rms>0.) err=rms/TMath::Sqrt(fNEventsInPad[i]);
e5b2f7f2 631 h->SetBinError(i+1,err);
632 }
633 }
634 return h;
635}
636//______________________________________________________________________
456ec396 637Bool_t AliITSOnlineSDDInjectors::WriteToROOT(TFile *fil) const {
638 //
639 if(fil==0){
640 AliWarning("Invalid pointer to ROOT file");
641 return kFALSE;
642 }
c115d279 643 TString hisnam;
456ec396 644 fil->cd();
c115d279 645 hisnam.Form("hdrsp%02dc%02ds%d",fDDL,fCarlos,fSide);
646 TH1F hdsp(hisnam.Data(),"",kInjPads,-0.5,kInjPads-0.5);
456ec396 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.;
e89a0633 656 if(rms>0.) err=rms/TMath::Sqrt(fNEventsInPad[i]);
456ec396 657 hdsp.SetBinError(i+1,err);
658 }
659 hdsp.Write();
660 return kTRUE;
661}
50d25e98 662//______________________________________________________________________
663void 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
c115d279 666 TString outfilnam;
667 outfilnam.Form("SDDinj_ddl%02dc%02d_sid%d.data",fDDL,fCarlos,fSide);
668 FILE* outf=fopen(outfilnam.Data(),"a");
50d25e98 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}