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