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