AliRoot Core  3dc7879 (3dc7879)
AliTPCclusterFast.cxx
Go to the documentation of this file.
1 
20 /*
21  Example usage in the test mode:
22  .x ~/rootlogon.C
23 
24  .L $AliRoot_SRC/TPC/fastSimul/AliTPCclusterFast.cxx+
25  AliTPCclusterFast::InitFormulas();
26  AliTPCclusterFast::fPRF = new TF1("fprf","gausn",-5,5); //MWPC
27  AliTPCclusterFast::fPRF->SetParameters(1,0,0.5);
28  //
29  AliTPCclusterFast::fPRF =new TF1("fprf"," GEMPRF(x,0.02)",-3,3); // GEM
30  //
31  //AliTPCclusterFast::fTRF = new TF1("ftrf","gausn",-5,5);
32  AliTPCclusterFast::fTRF = new TF1("gamma4Norm","Gamma4Norm(x)",-3,3); //Gamma4 TRF in bin units (100ns)
33 
34  TStopwatch timer; AliTPCtrackFast::Simul("trackerSimul.root",20,0.6); timer.Print();
35 
36  TFile * ftrack = TFile::Open("trackerSimul.root");
37  TTree *tree = (TTree*)ftrack->Get("simulTrack");
38  tree->SetMarkerStyle(25);
39  tree->SetMarkerSize(0.6);
40  testTree=tree;
41  AliTPCclusterFast::SetMetadata(tree);
42  AliTPCclusterFast::UnitTest();
43 
44 */
55 
56 #include "TObject.h"
57 #include "TF1.h"
58 #include "TMath.h"
59 #include "TRandom.h"
60 #include "TVectorF.h"
61 #include "TMatrixF.h"
62 #include "TH1.h"
63 #include "AliTPCreco.h"
64 #include "TClonesArray.h"
65 #include "TTreeStream.h"
66 #include "TGrid.h"
67 #include "TStatToolkit.h"
68 #include "AliTPCParamSR.h"
69 #include "TFormulaPrimitive.h"
70 
71 TTree* testTree=0;
72 
73 class AliTPCclusterFast: public TObject {
74 public:
76  void Init();
77 
78  virtual ~AliTPCclusterFast();
79  void SetParam(Float_t mnprim, Float_t diff, Float_t diffL, Int_t padrow, Float_t y, Float_t z, Float_t ky, Float_t kz, Float_t yCenter, Float_t zCenter);
81  void Digitize();
82  Double_t GetQtot(Float_t gain,Float_t thr, Float_t noise, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE);
83  Double_t GetQmax(Float_t gain,Float_t thr, Float_t noise, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE);
84  Double_t GetQmaxCorr(Float_t rmsy0, Float_t rmsz0);
85  Double_t GetQtotCorr(Float_t rmsy0, Float_t rmsz0, Float_t gain, Float_t thr);
86  Double_t GetClusterProperties(TVectorF &param, Int_t addOverlap, Float_t gain=0.8, Float_t thr=2, Float_t noise=0.7, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE, Int_t skipSample=0);
87  Double_t GetCOG(Int_t returnType, Int_t addOverlap, Float_t gain=0.8, Float_t thr=2, Float_t noise=0.7, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE,Int_t skipSample=0);
88  Double_t GetCOGHit(Int_t returnType);
89  Float_t UnfoldCluster(Float_t & meani, Float_t & meanj, Float_t & sumu, Float_t & overlap, Int_t addOverlap, Float_t gain=0.8, Float_t thr=2, Float_t noise=0.7, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE,Int_t skipSample=0);
90  Float_t GetCOGUnfolded(Int_t returnType, Int_t addOverlap=kTRUE, Float_t gain=0.8, Float_t thr=2, Float_t noise=0.7, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE,Int_t skipSample=0);
91 
92  Bool_t MakeDigitization(Int_t addOverlap, Float_t gain, Float_t thr, Float_t noise, Bool_t rounding, Bool_t addPedestal,Int_t skipSample);
93  //
94  Double_t GetExpectedRMS(Int_t dim);
95  //Double_t GetExpectedResolution(Int_t dim);
96 
97  Double_t GetNsec();
98  Int_t GetYMaxBin(){return fYMaxBin;}
99  Int_t GetZMaxBin(){return fZMaxBin;}
100  TMatrixF *GetRawDigits(){return &fRawDigits;}
101  Float_t GetRawDigit(Int_t i, Int_t j){return fRawDigits(i,j);};
102  Float_t GetDigit(Int_t i, Int_t j){return fDigits(i,j);};
103  Float_t GetDigitsRawMax(){return TMath::MaxElement(35,fRawDigits.GetMatrixArray());}
104  Float_t GetDigitsMax(){return TMath::MaxElement(35,fDigits.GetMatrixArray());}
105  //static void Simul(const char* simul, Int_t npoints);
106  static void InitFormulas();
107  static Double_t GaussConvolution(Double_t x0, Double_t x1, Double_t k0, Double_t k1, Double_t s0, Double_t s1);
108  static Double_t GaussExpConvolution(Double_t x0, Double_t s0,Double_t t1);
109  static Double_t GaussGamma4(Double_t x, Double_t s0, Double_t p1);
110  static Double_t Gamma4(Double_t x, Double_t p0, Double_t p1);
111  static Double_t Gamma4Norm(Double_t x);
112  static Double_t GEMPRF(Double_t x, Double_t sigma);
113  static void SetMetadata(TTree * tree);
114  //
115  //
116  static Bool_t UnitTest();
117 public: // Cluster parameters expressid in bin units
118  //
119  Float_t fMNprim;
120  // //electrons part input
121  Int_t fNprim;
122  Int_t fNtot;
123  Float_t fQtot;
124  //
125  Float_t fDiff;
126  Float_t fDiffLong;
127  Int_t fPadRow;
128  Float_t fY;
129  Float_t fZ;
130  Float_t fYCenterBin;
131  Float_t fZCenterBin;
132  Int_t fYMaxBin;
133  Int_t fZMaxBin;
134 
135  Float_t fAngleY;
136  Float_t fAngleZ;
138  //
139  //
140  // // electron part simul
141  TVectorF fSec;
142  TVectorF fPosY;
143  TVectorF fPosZ;
144  TVectorF fGain;
145  //
146  TVectorF fStatY; // stat Y
147  TVectorF fStatZ; // stat Y
148  //
149  // digitization part
150  //
151  TMatrixF fDigits;
152  TMatrixF fRawDigits;
153  Float_t fPRFRMS;
154  Float_t fTRFRMS;
155  static TF1* fPRF;
156  static TF1* fTRF;
157  static Float_t fgZSamplingFactor; // z sample at 10 MHz is 2 time narrower as rphi sample
158  static Int_t fgDebugLevel; // debug output downscaling factor
159  ClassDef(AliTPCclusterFast,2) // container for
160 };
161 
162 
163 class AliTPCtrackFast: public TObject {
164 public:
165  AliTPCtrackFast();
166  void MakeTrack();
167  static void Simul(const char* simul, Int_t ntracks, Double_t diff, Bool_t simulOverlap=kTRUE);
168  Double_t CookdEdxNtot(Double_t f0,Float_t f1);
169  Double_t CookdEdxQtot(Double_t f0,Float_t f1);
170  Double_t CookdEdxNtotThr(Double_t f0,Float_t f1, Double_t thr, Int_t dEdxMode);
171  Double_t CookdEdxQtotThr(Double_t f0,Float_t f1, Double_t thr, Int_t dEdxMode);
172  //
173  Double_t CookdEdxDtot(Double_t f0,Float_t f1, Float_t gain,Float_t thr, Float_t noise, Bool_t corr, Int_t dEdxMode);
174  Double_t CookdEdxDmax(Double_t f0,Float_t f1,Float_t gain,Float_t thr, Float_t noise, Bool_t corr, Int_t dEdxMode);
175  //
176  Double_t CookdEdx(Int_t npoints, Double_t *amp, Double_t f0,Float_t f1, Int_t dEdxMode);
177  //
178  Float_t fMNprim;
179  Float_t fTY;
180  Float_t fTZ;
181  Float_t fTAngleY;
182  Float_t fTAngleZ;
183  Float_t fDiff;
184  Float_t fDiffLong;
185  Int_t fN;
186  // overlap track properties
187  Bool_t fBOverlap;
188  Float_t fMNprimOverlap;
189  Float_t fDAngleYOverlap;
190  Float_t fDAngleZOverlap;
191  Float_t fDYOverlap;
192  Float_t fDZOverlap;
193  TClonesArray *fCl;
194  //
195  Bool_t fInit;
196 
198  ClassDef(AliTPCtrackFast,2)
200 };
201 
203 ClassImp(AliTPCclusterFast)
204 ClassImp(AliTPCtrackFast)
206 
207 TF1 *AliTPCclusterFast::fPRF=0;
208 TF1 *AliTPCclusterFast::fTRF=0;
211 AliTPCParamSR paramSR; // parameter class to get TPC properties
212 
213 
214 
216  TObject(),
217  fMNprim(0),
218  fTAngleY(0),
219  fTAngleZ(0),
220  fN(0),
221  fBOverlap(kFALSE),
222  fMNprimOverlap(0),
223  fDAngleYOverlap(0),
224  fDAngleZOverlap(0),
225  fDYOverlap(0),
226  fDZOverlap(0),
227  fCl(0),
228  fInit(kFALSE)
229 {
231 
232 }
233 
235  //
236  // Register formula as a build-in formulas to speed up evaluation
237  //
238  TFormulaPrimitive::AddFormula(new TFormulaPrimitive("GEMPRF","GEMPRF",AliTPCclusterFast::GEMPRF));
239  TFormulaPrimitive::AddFormula(new TFormulaPrimitive("Gamma4","Gamma4",AliTPCclusterFast::Gamma4));
240  TFormulaPrimitive::AddFormula(new TFormulaPrimitive("Gamma4Norm","Gamma4Norm",AliTPCclusterFast::Gamma4Norm));
241 }
242 
243 
248  // - cluster performnce dependes on relative units normalized to bin size
249  // - to keep back compatibility
250  //
251  if (!fCl) fCl = new TClonesArray("AliTPCclusterFast",159);
252  //
253  // 0.) Init data structure
254  //
255  for (Int_t irow=0;irow<fN;irow++){
256  AliTPCclusterFast * cluster = (AliTPCclusterFast*) fCl->UncheckedAt(irow);
257  if (!cluster) cluster = new ((*fCl)[irow]) AliTPCclusterFast;
258  cluster->Init();
259  }
260  //
261  // 1.) Create hits - with crosstalk diffusion
262  //
263  for (Int_t irow=0;irow<fN;irow++){
264  Double_t tX = (irow < paramSR.GetNRow(0)) ? paramSR.GetPadRowRadiiLow(irow): paramSR.GetPadRowRadiiUp(irow-paramSR.GetNRow(0));
265  Double_t tY = fTY+tX*fTAngleY;
266  Double_t tZ = fTZ+tX*fTAngleZ;
267  Double_t padLength= (irow < paramSR.GetNRow(0)) ? paramSR.GetPadPitchLength(0,irow):paramSR.GetPadPitchLength(36,irow-paramSR.GetNRow(0));
268  Double_t padWidth= (irow < paramSR.GetNRow(0)) ? paramSR.GetPadPitchWidth(0):paramSR.GetPadPitchWidth(36);
269  Double_t zWidth= paramSR.GetZWidth()*0.5; // 10 MHz width default
270 
271  //
272  AliTPCclusterFast * cluster = (AliTPCclusterFast*) fCl->UncheckedAt(irow);
273  AliTPCclusterFast * clusterm = (AliTPCclusterFast*) fCl->UncheckedAt(TMath::Max(irow-1,0));
274  AliTPCclusterFast * clusterp = (AliTPCclusterFast*) fCl->UncheckedAt(TMath::Min(irow+1,kMaxRow-1));
275  if (!cluster) cluster = new ((*fCl)[irow]) AliTPCclusterFast;
276  //
277  // Transform cm -> bins and angle to "bin angle"
278  //
279  Double_t tYBin=tY/padWidth;
280  Double_t tZBin=tZ/zWidth;
281  Double_t drift=paramSR.GetZLength()-TMath::Abs(tZ);
282  if (drift<0) drift=0;
283  Double_t driftFactor= TMath::Sqrt(drift/100.); // diffusion convenrsion - drift length in meters
284  Double_t fDiffBin=fDiff*driftFactor/padWidth;
285  Double_t fDiffLongBin=fDiffLong*driftFactor/padLength;
286  Double_t fAngleYBin=fTAngleY*padLength/padWidth;
287  Double_t fAngleZBin=fTAngleZ*padLength/zWidth;
288  //
289  Float_t yCenterBin= TMath::Nint(tYBin);
290  Float_t zCenterBin= TMath::Nint(tZBin*0.5)*2;
291  Double_t posYBin = tYBin-yCenterBin;
292  Double_t posZBin = tZBin-zCenterBin;
293 
294 
295  cluster->SetParam(fMNprim*padLength,fDiffBin, fDiffLongBin, irow, posYBin,posZBin,fAngleYBin,fAngleZBin,yCenterBin,zCenterBin); // when is the cluster plus parameters done
296  //
297  cluster->GenerElectrons(cluster, clusterm, clusterp);
298  if (fBOverlap){ // if we simulate the overlap of tracks
299  AliTPCclusterFast * clusterOverlap = cluster->fOverlapCluster;
300  if (clusterOverlap==NULL){
301  cluster->fOverlapCluster=new AliTPCclusterFast;
302  clusterOverlap= cluster->fOverlapCluster;
303  }
304  clusterOverlap->Init();
305  Double_t posYOverlapBin=posYBin+(fDYOverlap+tX*fDAngleYOverlap)/padWidth;
306  Double_t posZOverlapBin=posZBin+(fDZOverlap+tX*fDAngleZOverlap)/padLength;
307  clusterOverlap->SetParam(fMNprimOverlap*padLength,fDiffBin, fDiffLongBin, irow,posYOverlapBin,posZOverlapBin,fAngleYBin+fDAngleYOverlap/padWidth,fAngleZBin+fDAngleZOverlap/zWidth,yCenterBin,zCenterBin); clusterOverlap->GenerElectrons(clusterOverlap, 0, 0);
308  }
309  }
310  //
311  // 2.) make digitization
312  //
313  for (Int_t i=0;i<fN;i++){
314  AliTPCclusterFast * cluster = (AliTPCclusterFast*) fCl->UncheckedAt(i);
315  cluster->Digitize();
316  if (cluster->fOverlapCluster) cluster->fOverlapCluster->Digitize();
317  }
318 
319 }
320 
321 Double_t AliTPCtrackFast::CookdEdxNtot(Double_t f0,Float_t f1){
323 
324  Double_t amp[159];
325  for (Int_t i=0;i<fN;i++){
326  AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
327  amp[i]=cluster->fNtot;
328  }
329  return CookdEdx(fN,amp,f0,f1,0);
330 }
331 
332 Double_t AliTPCtrackFast::CookdEdxQtot(Double_t f0,Float_t f1){
334 
335  Double_t amp[159];
336  for (Int_t i=0;i<fN;i++){
337  AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
338  amp[i]=cluster->fQtot;
339  }
340  return CookdEdx(fN,amp,f0,f1,0);
341 }
342 
343 
344 Double_t AliTPCtrackFast::CookdEdxNtotThr(Double_t f0,Float_t f1, Double_t thr, Int_t dEdxMode){
348 
349  Double_t amp[159];
350  Int_t nBellow=0;
351  //
352  Double_t minAbove=-1;
353  for (Int_t i=0;i<fN;i++){
354  AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
355  Double_t clQ= cluster->fNtot;
356  if (clQ<thr) {
357  nBellow++;
358  continue;
359  }
360  if (minAbove<0) minAbove=clQ;
361  if (minAbove>clQ) minAbove=clQ;
362  }
363  //
364  if (dEdxMode==-1) return Double_t(nBellow)/Double_t(fN);
365 
366  for (Int_t i=0;i<fN;i++){
367  AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
368  Double_t clQ= cluster->fNtot;
369  //
370  if (dEdxMode==0) amp[i]=clQ; // dEdxMode0 - not threshold - keep default
371  //
372  //
373  if (dEdxMode==1 && clQ>thr) amp[i]=clQ; // dEdxMode1 - skip if bellow
374  if (dEdxMode==1 && clQ<thr) amp[i]=0; // dEdxMode1 - skip if bellow
375  //
376  //
377  if (dEdxMode==2 && clQ>thr) amp[i]=clQ; // dEdxMode2 - use 0 if below
378  if (dEdxMode==2 && clQ<thr) amp[i]=0; // dEdxMode2 - use 0 if below
379  //
380  //
381  if (dEdxMode==3) amp[i]=(clQ>thr)?clQ:thr; // dEdxMode3 - use thr if below
382  if (dEdxMode==4) amp[i]=(clQ>thr)?clQ:minAbove; // dEdxMode4 - use minimal above threshold if bellow thr
383  }
384  return CookdEdx(fN,amp,f0,f1, dEdxMode);
385 }
386 
387 
388 
389 Double_t AliTPCtrackFast::CookdEdxQtotThr(Double_t f0,Float_t f1, Double_t thr, Int_t dEdxMode){
393 
394  //
395  Double_t amp[159];
396  Int_t nBellow=0;
397  //
398  Double_t minAbove=-1;
399  for (Int_t i=0;i<fN;i++){
400  AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
401  Double_t clQ= cluster->fQtot;
402  if (clQ<thr) {
403  nBellow++;
404  continue;
405  }
406  if (minAbove<0) minAbove=clQ;
407  if (minAbove>clQ) minAbove=clQ;
408  }
409  //
410  if (dEdxMode==-1) return Double_t(nBellow)/Double_t(fN);
411 
412  for (Int_t i=0;i<fN;i++){
413  AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
414  Double_t clQ= cluster->fQtot;
415  //
416  if (dEdxMode==0) amp[i]=clQ; // dEdxMode0 - not threshold - keep default
417  //
418  //
419  if (dEdxMode==1 && clQ>thr) amp[i]=clQ; // dEdxMode1 - skip if bellow
420  if (dEdxMode==1 && clQ<thr) amp[i]=0; // dEdxMode1 - skip if bellow
421  //
422  //
423  if (dEdxMode==2 && clQ>thr) amp[i]=clQ; // dEdxMode2 - use 0 if below
424  if (dEdxMode==2 && clQ<thr) amp[i]=0; // dEdxMode2 - use 0 if below
425  //
426  //
427  if (dEdxMode==3) amp[i]=(clQ>thr)?clQ:thr; // dEdxMode3 - use thr if below
428  if (dEdxMode==4) amp[i]=(clQ>thr)?clQ:minAbove; // dEdxMode4 - use minimal above threshold if bellow thr
429  }
430  return CookdEdx(fN,amp,f0,f1, dEdxMode);
431 }
432 
433 
434 
435 
436 
437 Double_t AliTPCtrackFast::CookdEdxDtot(Double_t f0,Float_t f1, Float_t gain,Float_t thr, Float_t noise, Bool_t doCorr, Int_t dEdxMode){
440 
441  Double_t amp[159];
442  Double_t minAmp=-1;
443  //
444  for (Int_t i=0;i<fN;i++){
445  AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
446  Float_t camp = 0;
447  if (dEdxMode==0) camp = cluster->GetQtot(gain,0,noise);
448  else
449  camp = cluster->GetQtot(gain,thr,noise);
450  Float_t corr = 1;
451  if (doCorr) corr = cluster->GetQtotCorr(0.5,0.5,gain,thr);
452  camp/=corr;
453  amp[i]=camp;
454  if (camp>0){
455  if (minAmp <0) minAmp=camp;
456  if (minAmp >camp) minAmp=camp;
457  }
458  }
459  if (dEdxMode==3) for (Int_t i=0;i<fN;i++) if (amp[i]<=0) amp[i]=thr;
460  if (dEdxMode==4) for (Int_t i=0;i<fN;i++) if (amp[i]<=0) amp[i]=minAmp;
461  return CookdEdx(fN,amp,f0,f1, dEdxMode);
462 }
463 
464 
465 
466 Double_t AliTPCtrackFast::CookdEdxDmax(Double_t f0,Float_t f1, Float_t gain,Float_t thr, Float_t noise, Bool_t doCorr, Int_t dEdxMode){
469 
470  Double_t amp[159];
471  Double_t minAmp=-1;
472  //
473  for (Int_t i=0;i<fN;i++){
474  AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
475  Float_t camp = 0;
476  if (dEdxMode==0) camp = cluster->GetQmax(gain,0,noise);
477  else
478  camp = cluster->GetQmax(gain,thr,noise);
479  Float_t corr = 1;
480  if (doCorr) corr = cluster->GetQmaxCorr(0.5,0.5);
481  camp/=corr;
482  amp[i]=camp;
483  if (camp>0){
484  if (minAmp <0) minAmp=camp;
485  if (minAmp >camp) minAmp=camp;
486  }
487  }
488  if (dEdxMode==3) for (Int_t i=0;i<fN;i++) if (amp[i]<=0) amp[i]=thr;
489  if (dEdxMode==4) for (Int_t i=0;i<fN;i++) if (amp[i]<=0) amp[i]=minAmp;
490  return CookdEdx(fN,amp,f0,f1, dEdxMode);
491 }
492 
493 
494 Double_t AliTPCtrackFast::CookdEdx(Int_t npoints, Double_t *amp,Double_t f0,Float_t f1, Int_t dEdxMode){
505 
506  //
507  // 0. sorted the array of amplitudes
508  //
509  Int_t index[159];
510  TMath::Sort(npoints,amp,index,kFALSE);
511  //
512  // 1.) Calculate truncated mean from the selected range of the array (ranking statistic )
513  // dependening on the dEdxMode 0 amplitude can be skipped
514  Float_t sum0=0, sum1=0,sum2=0;
515  Int_t accepted=0;
516  Int_t above=0;
517  for (Int_t i=0;i<npoints;i++) if (amp[index[i]]>0) above++;
518 
519  for (Int_t i=0;i<npoints;i++){
520  //
521  if (dEdxMode==1 && amp[index[i]]==0) {
522  continue;
523  }
524  if (accepted<npoints*f0) continue;
525  if (accepted>npoints*f1) continue;
526  sum0++;
527  sum1+= amp[index[i]];
528  sum2+= amp[index[i]];
529  accepted++;
530  }
531  if (dEdxMode==-1) return 1-Double_t(above)/Double_t(npoints);
532  if (sum0<=0) return 0;
533  return sum1/sum0;
534 }
535 
536 void AliTPCtrackFast::Simul(const char* fname, Int_t ntracks, Double_t diffFactor, Bool_t simulOverlap){
546 
547  paramSR.Update(); // intitialize TPC parameters used later in the TOY simulation
548 
549  AliTPCtrackFast fast;
550  TTreeSRedirector *pcstream = new TTreeSRedirector(fname,"recreate");
551  for (Int_t itr=0; itr<ntracks; itr++){
552  //
553  fast.fMNprim=(13.+100*gRandom->Rndm());
554  if (gRandom->Rndm()>0.5) fast.fMNprim=1./(0.00001+gRandom->Rndm()*0.1);
555 
556  fast.fDiff =0.22*(1+0.2*(gRandom->Rndm()-0.5)); // diffusion in mm/sqrt(cm) 0.22 cm/sqrt(m) +-10%
557  // fast.fDiffLong = fast.fDiff*0.6/1.;
558  fast.fDiffLong = fast.fDiff*diffFactor/1.;
559  //
560  fast.fTY=gRandom->Gaus(0,0.01); // cm vertex spread for primaries
561  fast.fTZ=gRandom->Gaus(0,7); // 7 cm vertex spread in z
562  if (gRandom->Rndm()>0.5) {
563  fast.fTY=gRandom->Gaus(0,20); // 20 cm vertex spread for secondaries - generate for half of statistic
564  fast.fTZ=gRandom->Gaus(0,20); // 20 cm vertex spread for secondaries - generate one half of statistic
565  }
566 
567  fast.fTAngleY = 4.0*(gRandom->Rndm()-0.5);
568  if (gRandom->Rndm()<0.2) fast.fTAngleY = (gRandom->Rndm()-0.5)*TMath::Pi()/9.; // admixture of high momenta tracks perpendicular to pad row +-10 degrees
569  fast.fTAngleZ = 3.0*(gRandom->Rndm()-0.5); // track range as acceptabel for TPC
570  fast.fN = 159;
571 
572  if (simulOverlap){ //
573  fast.fBOverlap=kTRUE; // flag generate overlap track
574  fast.fMNprimOverlap=1./(0.00001+gRandom->Rndm()*0.1); // mean number of primary electrons for overlap track - flat in 1/Q
575  // // better to get "realistic" q distribution
576  fast.fDAngleYOverlap=(gRandom->Rndm()-0.5)*20./fast.fN; // y angle - tan(y) for overlap track - for full lenght +-10 bins
577  fast.fDAngleZOverlap=(gRandom->Rndm()-0.5)*20./fast.fN; // z angle - tan z for overlap track
578  fast.fDYOverlap=((gRandom->Rndm()-0.5)*5.); // delta y position of overlap track at row 0
579  fast.fDZOverlap=((gRandom->Rndm()-0.5)*5.); // delta z position of overlap track at row 0
580  }
581  fast.MakeTrack();
582  if (itr%100==0) printf("%d\n",itr);
583  (*pcstream)<<"simulTrack"<<
584  "tr.="<<&fast<<
585  "\n";
586  }
587  fast.Write("track");
588  delete pcstream;
589 }
590 
591 
592 
594  fOverlapCluster(0),
595  fPRFRMS(0.5), // pad respons function width
596  fTRFRMS(0.5), // time responsefunction width
597  fRawDigits()
598 {
600  fDigits.ResizeTo(5,7);
601  fRawDigits.ResizeTo(5,7);
602 }
603 
606 
607  const Int_t knMax=10000;
608  fMNprim=0; // mean number of primary electrons
609  // //electrons part input
610  fNprim=0; // mean number of primary electrons
611  fNtot=0; // total number of electrons
612  fQtot=0; // total charge - Gas gain flucuation taken into account
613  fYCenterBin=0;
614  fZCenterBin=0;
615  fPadRow=0;
616  //
617  fPosY.ResizeTo(knMax);
618  fPosZ.ResizeTo(knMax);
619  fGain.ResizeTo(knMax);
620  fSec.ResizeTo(knMax);
621  fStatY.ResizeTo(3);
622  fStatZ.ResizeTo(3);
623  for (Int_t i=0; i<knMax; i++){
624  fPosY[i]=0;
625  fPosZ[i]=0;
626  fGain[i]=0;
627  fSec[i]=0;
628  }
629  fDiff=0;
630  fDiffLong=0;
631  fY=0;
632  fZ=0;
633  fYCenterBin=0;
634  fZCenterBin=0;
635  fAngleY=0;
636  fAngleZ=0;
637 }
638 
639 
640 
642 }
643 
644 
645 void AliTPCclusterFast::SetParam(Float_t mnprim, Float_t diff, Float_t diffL, Int_t padrow, Float_t y, Float_t z, Float_t ky, Float_t kz, Float_t yCenter, Float_t zCenter){
647 
648  fMNprim = mnprim; fDiff = diff; fDiffLong=diffL;
649  fY=y; fZ=z;
650  fAngleY=ky; fAngleZ=kz;
651  fYCenterBin=yCenter;
652  fZCenterBin=zCenter;
653  fPadRow=padrow;
654 
655 }
659 
660  const Double_t FPOT=20.77E-9, EEND=10E-6, EEXPO=2.2; // EEND1=1E-6;
661  const Double_t XEXPO=-EEXPO+1, YEXPO=1/XEXPO;
662  const Double_t W=20.77E-9;
663  Float_t RAN = gRandom->Rndm();
664  //Double_t edep = TMath::Power((TMath::Power(FPOT,XEXPO)*(1-RAN)+TMath::Power(EEND,XEXPO)*RAN),YEXPO);
665  //edep = TMath::Min(edep, EEND);
666  //return TMath::Nint(edep/W);
667  return TMath::Nint(TMath::Power((TMath::Power(FPOT,XEXPO)*(1-RAN)+TMath::Power(EEND,XEXPO)*RAN),YEXPO)/W);
668 }
669 
672  //
673  //
674  const Int_t knMax=1000;
675  cl0->fNprim = gRandom->Poisson(cl0->fMNprim); //number of primary electrons
676  // cl0->fNtot=0; //total number of electrons
677  // cl0->fQtot=0; //total number of electrons after gain multiplification
678  //
679  Double_t sumQ=0;
680  Double_t sumYQ=0;
681  Double_t sumZQ=0;
682  Double_t sumY2Q=0;
683  Double_t sumZ2Q=0;
684  // for (Int_t i=0;i<knMax;i++){
685  // cl0->fSec[i]=0;
686  //}
687  for (Int_t iprim=0; iprim<cl0->fNprim;iprim++){ // loop over primary electrons
688  Float_t dN = cl0->GetNsec();
689  cl0->fSec[iprim]=dN;
690  Double_t rc = (gRandom->Rndm()-0.5); // primary electrons distributed randomly along pad row
691  Double_t yc = cl0->fY+rc*cl0->fAngleY; // primary electorns along stright line trajectory +-0.5 bin (pad-row)
692  Double_t zc = cl0->fZ+rc*cl0->fAngleZ;
693 
694  for (Int_t isec=0;isec<=dN;isec++){
695  //
696  //
697  Double_t y = gRandom->Gaus(0,cl0->fDiff)+yc;
698  Double_t z = gRandom->Gaus(0,cl0->fDiff*fgZSamplingFactor)+zc;
699  Double_t r = gRandom->Gaus(0,cl0->fDiffLong)+rc;
700  // choose pad row
701  AliTPCclusterFast *cl=cl0;
702  if (r<-0.5 &&clm) cl=clm;
703  if (r>0.5 &&clp) cl=clp;
704  //
705  Double_t gg = -TMath::Log(gRandom->Rndm());
706  cl->fPosY[cl->fNtot]=y;
707  cl->fPosZ[cl->fNtot]=z;
708  cl->fGain[cl->fNtot]=gg;
709  cl->fQtot+=gg;
710  cl->fNtot++;
711  //
712  //
713  if (cl->fNtot>=knMax) continue;
714  }
715  if (cl0->fNtot>=knMax) break;
716  }
717 }
718 
721 
722  for (Int_t i=0; i<5;i++)
723  for (Int_t j=0; j<7;j++){
724  fDigits(i,j)=0;
725  }
726  //
727  // Fill digits
728  fStatY*=0;
729  fStatZ*=0;
730  for (Int_t iel = 0; iel<fNtot; iel++){
731  Double_t gg=fGain[iel];
732  Double_t y=fPosY[iel];
733  Double_t z=fPosZ[iel];
734  fStatY[0]+=gg;
735  fStatY[1]+=gg*y;
736  fStatY[2]+=gg*y*y;
737  fStatZ[0]+=gg;
738  fStatZ[1]+=gg*z;
739  fStatZ[2]+=gg*z*z;
740  for (Int_t di=-2; di<=2;di++)
741  for (Int_t dj=-3; dj<=3;dj++){
742  Float_t fac = fPRF->Eval(di-y)*fTRF->Eval(dj-z);
743  fac*=gg;
744  fDigits(2+di,3+dj)+=fac;
745  }
746  }
747  //
748  //
749  //
750 }
751 
752 
753 Double_t AliTPCclusterFast::GetQtot(Float_t gain, Float_t thr, Float_t noise, Bool_t brounding, Bool_t baddPedestal){
755 
756  Float_t sum =0;
757  for (Int_t ip=0;ip<5;ip++){
758  Float_t pedestal=gRandom->Rndm()-0.5; //pedestal offset different for each pad
759  for (Int_t it=0;it<7;it++){
760  Float_t amp = gain*fDigits(ip,it)+gRandom->Gaus()*noise;
761  if (baddPedestal) amp+=pedestal;
762  if (brounding) amp=TMath::Nint(amp);
763  if (amp>thr) sum+=amp;
764  }
765  }
766  return sum;
767 }
768 
769 Double_t AliTPCclusterFast::GetQmax(Float_t gain, Float_t thr, Float_t noise, Bool_t brounding, Bool_t baddPedestal){
771 
772  Float_t max =0;
773  for (Int_t ip=0;ip<5;ip++){
774  Float_t pedestal=gRandom->Rndm()-0.5; //pedestal offset different for each pad
775  for (Int_t it=0;it<7;it++){
776  Float_t amp = gain*fDigits(ip,it)+gRandom->Gaus()*noise;
777  if (baddPedestal) amp+=pedestal;
778  if (brounding) amp=TMath::Nint(amp);
779  if (amp>max && amp>thr) max=amp;
780  }
781  }
782  return max;
783 }
784 
785 
786 
787 Double_t AliTPCclusterFast::GetQmaxCorr(Float_t rmsy0, Float_t rmsz0){
792 
793  Double_t sy = TMath::Sqrt(rmsy0*rmsy0+fDiff*fDiff);
794  Double_t sz = TMath::Sqrt(rmsz0*rmsz0+fDiff*fDiff);
795  return GaussConvolution(fY,fZ, fAngleY,fAngleZ,sy,sz);
796 }
797 
798 
799 Double_t AliTPCclusterFast::GetQtotCorr(Float_t rmsy0, Float_t rmsz0, Float_t gain, Float_t thr){
802 
803  Double_t sy = TMath::Sqrt(rmsy0*rmsy0+fDiff*fDiff);
804  Double_t sz = TMath::Sqrt(rmsz0*rmsz0+fDiff*fDiff);
805  Double_t sumAll=0,sumThr=0;
806  Double_t qtot = GetQtot(gain,thr,0); // sum of signal over threshold
807  Double_t qmax = GetQmax(gain,thr,0); // qmax
808  //
809  Double_t corr =1;
810  Double_t qnorm=qtot;
811  for (Int_t iter=0;iter<2;iter++){
812  for (Int_t iy=-2;iy<=2;iy++)
813  for (Int_t iz=-2;iz<=2;iz++){
814  Double_t val = GaussConvolution(fY-iy,fZ-iz, fAngleY,fAngleZ,sy,sz);
815  Double_t qlocal =TMath::Nint(qnorm*val);
816  if (qlocal>thr) sumThr+=qlocal;
817  sumAll+=qlocal;
818  }
819  if (sumAll>0&&sumThr>0) corr=(sumThr)/sumAll;
820  if (sumThr==0) corr=GetQmaxCorr(0.5,0.5);
821  //corr = sumThr;
822  if (corr>0) qnorm=qtot/corr;
823 
824  }
825  return corr;
826 }
827 
828 Double_t AliTPCclusterFast::GetClusterProperties(TVectorF &param, Int_t addOverlap, Float_t gain, Float_t thr, Float_t noise, Bool_t rounding, Bool_t addPedestal, Int_t skipSample){
829  //
830  // calculate area, COG, RMS and skeewnes cluster without any correction
831  //
832  Float_t sumW=0;
833  Float_t sumYW=0;
834  Float_t sumZW=0;
835  Float_t sumY2W=0;
836  Float_t sumZ2W=0;
837  Float_t sumY3W=0;
838  Float_t sumZ3W=0;
839  for (Int_t iy=-2;iy<=2;iy++)
840  for (Int_t jz=-2;jz<=2;jz+=1+skipSample){
841  Int_t iz=jz;
842  if (skipSample>0) iz=jz/(1+skipSample);
843  Double_t val = gain*fDigits(iy+2,jz+3);
844  if (addOverlap && fOverlapCluster){
845  val+=gain*fOverlapCluster->fDigits(iy+2,jz+3);
846  }
847  val+=noise*gRandom->Gaus();
848  if (addPedestal) val+=gRandom->Rndm()-0.5; // add random pedestal assuming mean bias value 0
849  if (val>thr){
850  sumW+=val;
851  sumYW+=iy*val;
852  sumZW+=iz*val;
853  sumY2W+=iy*iy*val;
854  sumZ2W+=iz*iz*val;
855  }
856  }
857  if (sumW>0) {
858  sumYW/=sumW;
859  sumZW/=sumW;
860  sumY2W/=sumW;
861  sumZ2W/=sumW;
862  if (skipSample>0){
863  sumZW*=2.;
864  sumZ2W*=4.;
865  }
866  }
867  param[0]=sumW/gain; // total charge
868  param[1]=sumYW; // mean y
869  param[2]=sumZW; // mean z
870  param[3]=TMath::Sqrt(sumY2W-sumYW*sumYW); // rms y
871  param[4]=TMath::Sqrt(sumZ2W-sumZW*sumZW); // rms z
872  //
873  // 3 moment
874  //
875  for (Int_t iy=-2;iy<=2;iy++)
876  for (Int_t iz=-2;iz<=2;iz++){
877  Double_t val = fDigits(iy+2,iz+3);
878  if (addOverlap && fOverlapCluster){
879  val+=fOverlapCluster->fDigits(iy+2,iz+3);
880  }
881  val+=noise;
882  if (addPedestal) val+=gRandom->Rndm()-0.5; // add random pedestal assuming mean bias value 0
883  if (val>thr){
884  Double_t dy=iy-param[1];
885  Double_t dz=iz-param[2];
886  sumY3W+=dy*dy*dy*val;
887  sumZ3W+=dz*dz*dz*val;
888  }
889  }
890  if (sumW>0){
891  param[5]=sumY3W/sumW;
892  param[6]=sumZ3W/sumW;
893  }
894 }
895 
897  //
898  // Idealized -
899  // Expected RMS of cluster in case of not threhsold effect and noise equal 0 in bin units
900  // see:
901  // http://arxiv.org/pdf/physics/0306108.pdf
902  // formulas 26, 27
903  // in the code - all variables in is bin size units - not necessay to normalize to pad length, resp pad width)
904  if (dim==1) return TMath::Sqrt(fPRFRMS*fPRFRMS+fDiff*fDiff+fAngleY*fAngleY/12.);
905  if (dim==2) return TMath::Sqrt(fTRFRMS*fTRFRMS+fDiff*fDiff*fgZSamplingFactor*fgZSamplingFactor+fAngleZ*fAngleZ/12.);
906  return 0;
907 }
908 
909 
910 Double_t AliTPCclusterFast::GetCOG(Int_t returnType, Int_t addOverlap, Float_t gain, Float_t thr, Float_t noise, Bool_t rounding, Bool_t addPedestal, Int_t skipSample){
911  //
912  //
913  //
914  TVectorF properties(20);
915  GetClusterProperties(properties, addOverlap, gain, thr, noise,rounding,addPedestal,skipSample);
916  return properties(returnType);
917 }
918 
919 Double_t AliTPCclusterFast::GetCOGHit(Int_t returnType){
920  //
921  // Return COG using hit inforamtion
922  //
923  if (returnType==0) return fStatY[0];
924  Float_t meanY=(fStatY[0]>0)?fStatY[1]/fStatY[0]:0;
925  if (returnType==1) return meanY; // meanY
926  Float_t meanZ=(fStatZ[0]>0)?fStatZ[1]/fStatZ[0]:0;
927  if (returnType==2) return meanZ; // mean Z
928 
929  if (returnType==3) return (fStatY[0]>0) ? TMath::Sqrt(fStatY[2]/fStatY[0]-meanY*meanY):0;
930  if (returnType==4) return (fStatZ[0]>0) ? TMath::Sqrt(fStatZ[2]/fStatZ[0]-meanZ*meanZ):0;
931  return 0;
932 }
933 
934 
935 
936 Double_t AliTPCclusterFast::GaussConvolution(Double_t x0, Double_t x1, Double_t k0, Double_t k1, Double_t s0, Double_t s1){
943 
944  const Float_t kEpsilon = 0.0001;
945  if ((TMath::Abs(k0)+TMath::Abs(k1))<kEpsilon*(s0+s1)){
946  // small angular effect
947  Double_t val = (TMath::Gaus(x0,0,s0)*TMath::Gaus(x1,0,s1))/(s0*s1*2.*TMath::Pi());
948  return val;
949  }
950 
951  Double_t sigma2 = k1*k1*s0*s0+k0*k0*s1*s1;
952  Double_t exp0 = TMath::Exp(-(k1*x0-k0*x1)*(k1*x0-k0*x1)/(2*sigma2));
953  //
954  Double_t sigmaErf = 2*s0*s1*TMath::Sqrt(2*sigma2);
955  Double_t erf0 = TMath::Erf( (k0*s1*s1*(k0-2*x0)+k1*s0*s0*(k1-2*x1))/sigmaErf);
956  Double_t erf1 = TMath::Erf( (k0*s1*s1*(k0+2*x0)+k1*s0*s0*(k1+2*x1))/sigmaErf);
957  Double_t norm = 1./TMath::Sqrt(sigma2);
958  norm/=2.*TMath::Sqrt(2.*TMath::Pi());
959  Double_t val = norm*exp0*(erf0+erf1);
960  return val;
961 
962 }
963 
964 
965 Double_t AliTPCclusterFast::GaussExpConvolution(Double_t x0, Double_t s0,Double_t t1){
971 
972  Double_t exp1 = (s0*s0*t1-2*x0)*t1/2.;
973  exp1 = TMath::Exp(exp1);
974  Double_t erf = 1+TMath::Erf((-s0*s0*t1+x0)/(s0*TMath::Sqrt(2.)));
975  Double_t val = exp1*erf;
976  val *=t1/(2.);
977  return val;
978 
979 }
980 
981 Double_t Gamma4(Double_t *x, Double_t *param){
983 
984  if (x[0]<0) return 0;
985  Double_t g1 = TMath::Exp(-4.*x[0]/param[1]);
986  Double_t g2 = TMath::Power(x[0]/param[1],4);
987  return param[0]*g1*g2;
988 }
989 
990 
991 Double_t AliTPCclusterFast::Gamma4(Double_t x, Double_t p0, Double_t p1){
994 
995  if (x<0) return 0;
996  Double_t g1 = TMath::Exp(-4.*x/p1);
997  Double_t g2 = TMath::Power(x/p1,4);
998  return p0*g1*g2;
999 }
1000 
1001 Double_t AliTPCclusterFast::Gamma4Norm(Double_t x){
1006  return AliTPCclusterFast::Gamma4((x+1.98094355865156)*0.1,55,0.160);
1007 }
1008 
1009 
1010 
1011 
1012 
1013 Double_t AliTPCclusterFast::GEMPRF(Double_t x, Double_t sigma){
1014  //
1015  // GEM PRF response function aprroximated as integral of gaussian
1016  // sigma of gaussian is the diffusion of electrons within GEM layers
1017  // in 0.5 cm of the drift lenght + O(0.100)mm GEM pitch ==> 0.2 mm
1018  if (x<0) return (1+TMath::Erf((x+0.5)/sigma))*0.5;
1019  if (x>0) return (1+TMath::Erf(-(x-0.5)/sigma))*0.5;
1020 }
1021 
1022 
1023 Double_t AliTPCclusterFast::GaussGamma4(Double_t x, Double_t s0, Double_t p1){
1027 
1028  Double_t exp1 = (8*s0*s0-4.*p1*x)/(p1*p1);
1029  exp1 = TMath::Exp(exp1);
1030  Double_t erf1 = 1+TMath::Erf((-4*s0/p1+x/s0)/TMath::Sqrt(2));
1031  // Double_t xp14 = TMath::Power(TMath::Abs((x/p1)),4);
1032  return exp1*erf1;
1033 
1034 
1035 }
1036 Float_t AliTPCclusterFast::GetCOGUnfolded(Int_t returnType, Int_t addOverlap, Float_t gain, Float_t thr, Float_t noise, Bool_t rounding, Bool_t addPedestal,Int_t skipSample){
1037  //
1038  //
1039  //
1040  Float_t meani, meanj, sumu,overlap;
1041  UnfoldCluster(meani, meanj, sumu,overlap,addOverlap, gain,thr,noise,rounding,addPedestal,skipSample);
1042  if (returnType==-1) return overlap;
1043  if (returnType==0) return sumu;
1044  if (returnType==1) return meani;
1045  if (returnType==2) return meanj;
1046 }
1047 
1048 
1049 Bool_t AliTPCclusterFast::MakeDigitization(Int_t addOverlap, Float_t gain, Float_t thr, Float_t noise, Bool_t rounding, Bool_t addPedestal,Int_t skipSample){
1050  //
1051  // Conversion ideal digits array to digits
1052  // In addition local max bin calculated
1053  //
1054 
1055  //
1056  // 1.) Make digitization and find the maximal bin
1057  // store position if maximal bin in the array
1058  // in case of rounding can happen we have the same values in maxima
1059  // to avoid bias we should take one position randomly
1060  // this bias is present also in the OFFLINE clusterer - can be seen like assymetry in the peak position
1061  // Numericaly effect is significant at Qmax~ 10 it is about 0.025 bin size
1062 
1063  Float_t maxValue=0;
1064  const Float_t kEpsilon=0.000001;
1065  for (Int_t i=0; i<5; i++){
1066  for (Int_t j=0; j<7; j++){
1067  Float_t value = fDigits(i,j);
1068  if (addOverlap && fOverlapCluster) value+=fOverlapCluster->fDigits(i,j);
1069  value*=gain;
1070  Float_t cNoise=gRandom->Gaus();
1071  value+=noise*cNoise;
1072  if (addPedestal) value+=gRandom->Rndm()-0.5;
1073  if (rounding) value=TMath::Nint(value);
1074  if (value<thr) value=0;
1075  if (skipSample==0) {
1076  fRawDigits(i,j)=value;
1077  if ((value+kEpsilon*cNoise)>=maxValue && TMath::Abs(i-2)<=1 && TMath::Abs(j-3)<=(1+skipSample)){ // check position of local maxima
1078  maxValue=value+kEpsilon*cNoise; // in case of equal values alogn peak chose one randomly
1079  fYMaxBin=i-2;
1080  fZMaxBin=j-3;
1081  }
1082  }
1083  if (skipSample==1 && (j%2)==1 && TMath::Abs(i-2)<=1 && TMath::Abs(j-3)<=(1+skipSample) ) { // check position of local maxima
1084  fRawDigits(i,2+j/2)=value;
1085  if (value+kEpsilon*cNoise>=maxValue){
1086  maxValue=value+kEpsilon*cNoise; // in case of equal values alogn peak chose one randomly
1087  fYMaxBin=i-2;
1088  fZMaxBin=2+j/2-3;
1089  }
1090  }
1091  }
1092  }
1093  //
1094  // shift digits - local maxima should be at predeefinde position y=2 z=3
1095  //
1096  if (fYMaxBin!=0 || fZMaxBin!=0){ //shift digits - local maxima should be at predeefinde position y=2 z=3
1097  TMatrixF tmpDigits(5,7);
1098  for (Int_t i=0; i<5; i++)
1099  for (Int_t j=0; j<7; j++)
1100  if ((i-fYMaxBin)>=0 && (i-fYMaxBin)<5 && (j-fZMaxBin)>=0 && (j-fZMaxBin)<7) {
1101  tmpDigits(i-fYMaxBin,j-fZMaxBin)= fRawDigits(i, j);
1102  }
1103  fRawDigits= tmpDigits;
1104  }
1105 
1106  static Int_t dumpCounter=0;
1107  dumpCounter++;
1108  if (fgDebugLevel>0 && (dumpCounter%fgDebugLevel)==0){
1109  ::Info("AliTPCclusterFast::MakeDigitization","fYMaxBin\t%d fZMaxBin\t%d",fYMaxBin,fZMaxBin);
1110  }
1111  return kTRUE;
1112  /*
1113  */
1114 }
1115 
1116 
1117 
1118 Float_t AliTPCclusterFast::UnfoldCluster(Float_t & meani, Float_t & meanj, Float_t & sumu, Float_t & overlap, Int_t addOverlap, Float_t gain, Float_t thr, Float_t noise, Bool_t rounding, Bool_t addPedestal,Int_t skipSample){
1119  //
1120  // Unforling as used in the AliTPCclusterer::UnfoldCluster - (described in CHEP paper ...)
1121  // - we are not using second local maxima as we assume we know the cluster shape
1122  // - in case of absence of this information local maxima usage to be considered
1123  //
1124  Float_t sum3i[7] = {0,0,0,0,0,0,0};
1125  Float_t sum3j[7] = {0,0,0,0,0,0,0};
1126  meani=0;
1127  meanj=0;
1128  sumu=0;
1129  overlap=0;
1130  //
1131  //
1132  MakeDigitization(addOverlap, gain, thr, noise,rounding, addPedestal, skipSample);
1133 
1134 
1135  for (Int_t k =0;k<7;k++) // sequence array
1136  for (Int_t l = -1; l<=1;l++){ // +- 1 bin loop
1137  if (k>0&&k<6) sum3i[k]+=fRawDigits(k-1,l+3); // i- y direction
1138  sum3j[k]+=fRawDigits(l+2,k);
1139  }
1140  if (sum3i[3]<=3 || sum3j[3]<=3) return 0;
1141 
1142 
1143  Float_t mratio[3][3]={{1,1,1},{1,1,1},{1,1,1}};
1144  //
1145  //unfold y
1146  Float_t sum3wi = 0; //charge minus overlap
1147  Float_t sum3wio = 0; //full charge
1148  Float_t sum3iw = 0; //sum for mean value
1149  for (Int_t dk=-1;dk<=1;dk++){
1150  sum3wio+=sum3i[dk+3];
1151  if (dk==0){
1152  sum3wi+=sum3i[dk+3];
1153  }
1154  else{
1155  Float_t ratio =1;
1156  if ( ( ((sum3i[dk+3]+3)/(sum3i[3]-3))+1 < (sum3i[2*dk+3]-3)/(sum3i[dk+3]+3))||
1157  (sum3i[dk+3]<=sum3i[2*dk+3] && sum3i[dk+3]>2 )){
1158  Float_t xm2 = sum3i[-dk+3];
1159  Float_t xm1 = sum3i[+3];
1160  Float_t x1 = sum3i[2*dk+3];
1161  Float_t x2 = sum3i[3*dk+3];
1162  Float_t w11 = TMath::Max((Float_t)(4.*xm1-xm2),(Float_t)0.000001);
1163  Float_t w12 = TMath::Max((Float_t)(4 *x1 -x2),(Float_t)0.);
1164  ratio = w11/(w11+w12);
1165  for (Int_t dl=-1;dl<=1;dl++)
1166  mratio[dk+1][dl+1] *= ratio;
1167  }
1168  Float_t amp = sum3i[dk+3]*ratio;
1169  sum3wi+=amp;
1170  sum3iw+= dk*amp;
1171  }
1172  }
1173  meani = sum3iw/sum3wi;
1174  Float_t overlapi = (sum3wio-sum3wi)/sum3wio;
1175  //unfold z
1176  Float_t sum3wj = 0; //charge minus overlap
1177  Float_t sum3wjo = 0; //full charge
1178  Float_t sum3jw = 0; //sum for mean value
1179  for (Int_t dk=-1;dk<=1;dk++){
1180  sum3wjo+=sum3j[dk+3];
1181  if (dk==0){
1182  sum3wj+=sum3j[dk+3];
1183  }
1184  else{
1185  Float_t ratio =1;
1186  if ( ( ((sum3j[dk+3]+3)/(sum3j[3]-3))+1 < (sum3j[2*dk+3]-3)/(sum3j[dk+3]+3)) ||
1187  (sum3j[dk+3]<=sum3j[2*dk+3] && sum3j[dk+3]>2)){
1188  Float_t xm2 = sum3j[-dk+3];
1189  Float_t xm1 = sum3j[+3];
1190  Float_t x1 = sum3j[2*dk+3];
1191  Float_t x2 = sum3j[3*dk+3];
1192  Float_t w11 = TMath::Max((Float_t)(4.*xm1-xm2),(Float_t)0.000001);
1193  Float_t w12 = TMath::Max((Float_t)(4 *x1 -x2),(Float_t)0.);
1194  ratio = w11/(w11+w12);
1195  for (Int_t dl=-1;dl<=1;dl++)
1196  mratio[dl+1][dk+1] *= ratio;
1197  }
1198  Float_t amp = sum3j[dk+3]*ratio;
1199  sum3wj+=amp;
1200  sum3jw+= dk*amp;
1201  }
1202  }
1203  meanj = sum3jw/sum3wj;
1204  Float_t overlapj = (sum3wjo-sum3wj)/sum3wjo;
1205  overlap = Int_t(100*TMath::Max(overlapi,overlapj)+3);
1206  sumu = (sum3wj+sum3wi)/2.;
1207 }
1208 
1210  //
1211  //
1212  //
1213  ::Info("AliTPCclusterFast::UnitTest","Test BEGIN");
1214  //
1215  // Test1. local Max position
1216  testTree->SetAlias("IsMaxOK","((fCl.GetRawDigit(2,3)>=fCl.GetRawDigit(1,3))&&(fCl.GetRawDigit(2,3)>=fCl.GetRawDigit(4,3)))!=0");
1217  testTree->Draw("IsMaxOK==0","fCl.GetCOGUnfolded(1, 0, 1, 0.0 , 0.0, 0, 0, 0)!=0","goff",1000);
1218  Double_t mean=TMath::Mean(testTree->GetSelectedRows(),testTree->GetV1());
1219  if (TMath::Abs(mean)<0.001){
1220  ::Info("AliTPCclusterFast::UnitTest","MaxTest OK");
1221  }else{
1222  ::Error("AliTPCclusterFast::UnitTest","MaxTest FAILED");
1223  }
1224 }
1225 
1227  //
1228  //
1229  //
1230  tree->SetAlias("deltaYHit","(fCl.GetCOGHit(1)-fY-0)"); // ideal resolution using pefect readout"
1231  tree->SetAlias("errYHit","sqrt(2.*fCl.fDiff**2/fCl.fQtot+(2*fCl.fAngleY**2)/(12.*sqrt(fCl.fNprim)))"); // resoulution for ideal response detector
1232  tree->SetAlias("errYMWPC","sqrt(0.2**2+2.*fCl.fDiff**2/fCl.fQtot+(2*fCl.fAngleY**2)/(12.*sqrt(fCl.fNprim)))"); // approximate resolution for the MWPC detector
1233 
1234  tree->SetAlias("deltaYUnfoldedDefault","(GetCOGUnfolded(1, 1, 0.8, 2, 0.6, 1, 1, 0)+fCl.GetYMaxBin()-fY)");
1235  tree->SetAlias("deltaYNoOverlapDefault","(fCl.GetCOG(1, 0, 0.8, 2, 0.6, 1, 1, 0)-fY-0)");
1236  tree->SetAlias("deltaYOverlapDefault","(fCl.GetCOG(1, 1, 0.8, 2, 0.6, 1, 1, 0)-fY-0)");
1237  tree->SetAlias("padrow","Iteration$");
1238 
1239  tree->SetAlias("IROC","padrow<63");
1240  tree->SetAlias("OROCMedium","padrow>63&&padrow<127");
1241  tree->SetAlias("OROCLong","padrow>127");
1242  tree->SetAlias("padLength","((IROC)*0.75+(OROCMedium)*1+(OROCLong*1.5))");
1243  tree->SetAlias("padWidth","((IROC)*0.4+(padrow>63)*0.6)");
1244  tree->SetAlias("driftLength","250-abs(fZCenterBin*0.25)");
1245 
1246  //
1247 
1248  //
1249  //
1250  //
1251  TStatToolkit::AddMetadata(tree,"deltaYHit.AxisTitle","#Delta_{r#phi} (bin)");
1252  TStatToolkit::AddMetadata(tree,"deltaYHit.Title","(fCl.GetCOGHit(1)-fY-0)");
1253  TStatToolkit::AddMetadata(tree,"deltaYHit.Legend","#Delta_{rphi} hit COG");
1254  TStatToolkit::AddMetadata(tree,"deltaYHit.Comment","#Delta_{rphi} for COG estimator using hits ");
1255  //
1256  TStatToolkit::AddMetadata(tree,"errYHit.AxisTitle","#sigma_{r#phi} (bin)");
1257  TStatToolkit::AddMetadata(tree,"errYHit.Title","(fCl.GetCOGHit(1)-fY-0)");
1258  TStatToolkit::AddMetadata(tree,"errYHit.Legend","#sigma_{rphi} hit COG");
1259  TStatToolkit::AddMetadata(tree,"rrYHit.Comment","#sigma_{rphi} for COG estimator using hits ");
1260  //
1261  //
1262  TStatToolkit::AddMetadata(tree,"deltaYNoOverlapDefault.AxisTitle","#Delta_{r#phi} (bin)");
1263  TStatToolkit::AddMetadata(tree,"deltaYNoOverlapDefault.Title","(fCl.GetCOG(1, 0, 0.8, 2, 0.6, 1, 1, 0)-fY)");
1264  TStatToolkit::AddMetadata(tree,"deltaYNoOverlapDefault.Legend","#Delta_{rphi} no overlap (10 MHz)");
1265  TStatToolkit::AddMetadata(tree,"deltaYNoOverlapDefault.Comment","#Delta_{rphi} no overlap (10 MHz) \n (fCl.GetCOG(1, 0, 0.8, 2, 0.6, 1, 1, 0)-fY)");
1266  //
1267  TStatToolkit::AddMetadata(tree,"deltaYUnfoldedDefault.AxisTitle","#Delta_{r#phi} (bin)");
1268  TStatToolkit::AddMetadata(tree,"deltaYUnfoldedDefault.Title","(GetCOGUnfolded(1, 1, 0.8, 2, 0.6, 1, 1, 0)+fCl.GetYMaxBin()-fY)");
1269  TStatToolkit::AddMetadata(tree,"deltaYUnfoldedDefault.Legend","#Delta_{rphi} unfolded (10 MHz)");
1270  TStatToolkit::AddMetadata(tree,"deltaYUnfoldedDefault.Comment","#Delta_{rphi} unfolded (10 MHz). Default digitization parameters. \n Sampling rate 10 MHz.\n Alias: (GetCOGUnfolded(1, 1, 0.8, 2, 0.6, 1, 1, 0)+fCl.GetYMaxBin()-fY)");
1271  //
1272  TStatToolkit::AddMetadata(tree,"fY.AxisTitle","r#phi (bin)");
1273  TStatToolkit::AddMetadata(tree,"fY.Title","fY");
1274  TStatToolkit::AddMetadata(tree,"fY.Legend","MC ideal r#phi position");
1275  TStatToolkit::AddMetadata(tree,"fY.Comment","MC ideal r#phi position of cluster");
1276  //
1277  TStatToolkit::AddMetadata(tree,"padrow.AxisTitle","pad row (bin)");
1278  TStatToolkit::AddMetadata(tree,"padrow.Title","padrow");
1279  TStatToolkit::AddMetadata(tree,"padrow.Legend","pad row (bin)");
1280  TStatToolkit::AddMetadata(tree,"padrow.Comment","Cluster - pad row position ");
1281  //
1282 
1283 }
1284 
1285 // Analytical sollution only in 1D - too long expression
1286 // Simplify[Integrate[Exp[-(x0-(x1-k*x2))*(x0-(x1-k*x2))/(2*s0*s0)]*Exp[-(x1*t1-k*x2)],{x2,-1,1}]]
1287 //
1288 //
1289 // No analytical solution
1290 //
1291 //Simplify[Integrate[Exp[-(x0-k0*xd)*(x0-k0*xd)/(2*s0*s0)-(x1-xt-k1*xd)*(x1-xt-k1*xd)/(2*s1*s1)]*Exp[-kt*xt]/(s0*s1),{xd,-1/2,1/2},{xt,0,Infinity}]]
Bool_t fInit
initialization flag
static Double_t GaussConvolution(Double_t x0, Double_t x1, Double_t k0, Double_t k1, Double_t s0, Double_t s1)
Float_t GetPadPitchLength(Int_t isector=0, Int_t padrow=0) const
Definition: AliTPCParam.h:302
TVectorF fPosY
position y for each electron
printf("Chi2/npoints = %f\n", TMath::Sqrt(chi2/npoints))
const Double_t kEpsilon
Int_t fNtot
total number of electrons
Double_t GetClusterProperties(TVectorF &param, Int_t addOverlap, Float_t gain=0.8, Float_t thr=2, Float_t noise=0.7, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE, Int_t skipSample=0)
Double_t CookdEdxQtot(Double_t f0, Float_t f1)
Int_t fZMaxBin
y maximum position as position as calculated in the MakeDigitization (should be 0 in mean ) ...
static Double_t Gamma4(Double_t x, Double_t p0, Double_t p1)
Manager and of geomety classes for set: TPC.
Definition: AliTPCParamSR.h:15
Int_t fPadRow
cluster pad row number
static Double_t GaussExpConvolution(Double_t x0, Double_t s0, Double_t t1)
Float_t fAngleY
z maximum position as position as calculated in the MakeDigitization (should be 0 in mean ) ...
Float_t GetCOGUnfolded(Int_t returnType, Int_t addOverlap=kTRUE, Float_t gain=0.8, Float_t thr=2, Float_t noise=0.7, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE, Int_t skipSample=0)
Float_t fMNprimOverlap
mean number of primary electrons for overlap track
Double_t GetCOGHit(Int_t returnType)
static void Simul(const char *simul, Int_t ntracks, Double_t diff, Bool_t simulOverlap=kTRUE)
Float_t fDZOverlap
delta z position of overlap track at row 0 in dz/dx
TClonesArray * fCl
array of clusters
AliTPCclusterFast * fOverlapCluster
static Double_t GaussGamma4(Double_t x, Double_t s0, Double_t p1)
Float_t fDiff
diffusion sigma
Float_t fDYOverlap
delta y position of overlap track at row 0 in dy/dx
THashList * AddMetadata(TTree *, const char *vartagName, const char *varTagValue)
TMatrixF fDigits
response matrix (ideal signal without noise, trheshold rounding, pile-up)
TTreeSRedirector * pcstream
Double_t CookdEdxNtotThr(Double_t f0, Float_t f1, Double_t thr, Int_t dEdxMode)
Float_t fAngleZ
z angle - tan z
Float_t fDiffLong
diffusion sigma longitudinal direction
Float_t GetPadRowRadiiLow(Int_t irow) const
AliTPCParamSR paramSR
Float_t GetPadPitchWidth(Int_t isector=0) const
Definition: AliTPCParam.h:300
static void GenerElectrons(AliTPCclusterFast *cl0, AliTPCclusterFast *clm, AliTPCclusterFast *clp)
npoints
Definition: driftITSTPC.C:85
Float_t GetDigit(Int_t i, Int_t j)
Float_t fY
y ideal position - center bin
Double_t GetExpectedRMS(Int_t dim)
Bool_t fBOverlap
flag generate overlap track
Float_t fYCenterBin
y center bin
static TF1 * fTRF
Time response function.
Float_t fDAngleYOverlap
y angle - tan(y) for overlap track in cm
static Double_t GEMPRF(Double_t x, Double_t sigma)
void sum()
static Double_t Gamma4Norm(Double_t x)
static Float_t fgZSamplingFactor
static Bool_t UnitTest()
Double_t CookdEdxNtot(Double_t f0, Float_t f1)
Int_t fNprim
mean number of primary electrons
Double_t GetQmaxCorr(Float_t rmsy0, Float_t rmsz0)
TTree * tree
Double_t GetQtot(Float_t gain, Float_t thr, Float_t noise, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE)
Float_t fTRFRMS
pad respons function width
Float_t GetZWidth() const
Definition: AliTPCParam.h:367
Float_t UnfoldCluster(Float_t &meani, Float_t &meanj, Float_t &sumu, Float_t &overlap, Int_t addOverlap, Float_t gain=0.8, Float_t thr=2, Float_t noise=0.7, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE, Int_t skipSample=0)
Float_t GetRawDigit(Int_t i, Int_t j)
Float_t fDiffLong
diffusion sigma longitudinal direction
void simul(Int_t npoints, Double_t diffFactor)
Definition: simul.C:8
Float_t fDiff
diffusion in mm/sqrt(m) - nominal is 2.2 mm/sqrt(m)
Float_t fDAngleZOverlap
z angle - tan z for overlap track in cm
Float_t fTZ
track Z at the vertex in (cm)
Float_t fTAngleY
y angle - tan(y) - dy/dx (cm/cm)
Double_t CookdEdxDtot(Double_t f0, Float_t f1, Float_t gain, Float_t thr, Float_t noise, Bool_t corr, Int_t dEdxMode)
Float_t fZ
z ideal position - center bin
Float_t fQtot
total charge - Gas gain flucuation taken into account
Float_t fPRFRMS
"on the fly caclualted digits matrix" for current version of setup - gain, noise, thr...
Float_t fTY
track Y at the vertex in (cm)
Double_t GetQmax(Float_t gain, Float_t thr, Float_t noise, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE)
Int_t GetNRow(Int_t isec) const
Definition: AliTPCParam.h:309
Double_t CookdEdxQtotThr(Double_t f0, Float_t f1, Double_t thr, Int_t dEdxMode)
Float_t GetPadRowRadiiUp(Int_t irow) const
TVectorF fPosZ
position z for each electron
static void SetMetadata(TTree *tree)
Bool_t MakeDigitization(Int_t addOverlap, Float_t gain, Float_t thr, Float_t noise, Bool_t rounding, Bool_t addPedestal, Int_t skipSample)
void SetParam(Float_t mnprim, Float_t diff, Float_t diffL, Int_t padrow, Float_t y, Float_t z, Float_t ky, Float_t kz, Float_t yCenter, Float_t zCenter)
AliTPCTrackHits * MakeTrack(TClonesArray *arr, TClonesArray *arrp, AliTPCTrackHits *myhits)
static void InitFormulas()
Float_t fMNprim
mean number of primary electrons per cm
Int_t fN
number of clusters simulated
Double_t GetCOG(Int_t returnType, Int_t addOverlap, Float_t gain=0.8, Float_t thr=2, Float_t noise=0.7, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE, Int_t skipSample=0)
TVectorF fGain
gg for each electron
Double_t GetQtotCorr(Float_t rmsy0, Float_t rmsz0, Float_t gain, Float_t thr)
static TF1 * fPRF
time rsponsefunction width
TTree * testTree
TVectorF fSec
number of secondary electrons
Double_t CookdEdx(Int_t npoints, Double_t *amp, Double_t f0, Float_t f1, Int_t dEdxMode)
Float_t GetZLength(Int_t sector=0) const
Definition: AliTPCParam.h:841
Float_t fZCenterBin
z center bin
char * fname
Float_t fTAngleZ
z angle - tan(z) - dy/dx (cm/cm)
Float_t fMNprim
mean number of primary electrons
Double_t CookdEdxDmax(Double_t f0, Float_t f1, Float_t gain, Float_t thr, Float_t noise, Bool_t corr, Int_t dEdxMode)