1 /// \class AliTPCclusterFast
4 /// gSystem->Load("libSTAT");
7 /// .L $ALICE_ROOT/TPC/fastSimul/AliTPCclusterFast.cxx+
9 /// AliTPCclusterFast::fPRF = new TF1("fprf","gausn",-5,5);
10 /// AliTPCclusterFast::fTRF = new TF1("ftrf","gausn",-5,5);
11 /// AliTPCclusterFast::fPRF->SetParameters(1,0,0.5);
12 /// AliTPCclusterFast::fTRF->SetParameters(1,0,0.5);
14 /// AliTPCtrackFast::Simul("trackerSimul.root",100);
15 /// // AliTPCclusterFast::Simul("cluterSimul.root",20000);
18 /// Modifications to add:
19 /// 1. modigy mode ==> dEdxMode
20 /// 2. Create hardware setup class
21 /// (fNoise, fGain, fBRounding, fBAddpedestal, ....)
22 /// 3. Create arrays of registered hardware setups
23 /// 4. Extend on the fly functions to use registered hardware setups, identified by ID.
33 #include "TClonesArray.h"
34 #include "TTreeStream.h"
37 class AliTPCclusterFast: public TObject {
42 virtual ~AliTPCclusterFast();
43 void SetParam(Float_t mnprim, Float_t diff, Float_t diffL, Float_t y, Float_t z, Float_t ky, Float_t kz);
44 static void GenerElectrons(AliTPCclusterFast *cl0, AliTPCclusterFast *clm, AliTPCclusterFast *clp);
46 Double_t GetQtot(Float_t gain,Float_t thr, Float_t noise, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE);
47 Double_t GetQmax(Float_t gain,Float_t thr, Float_t noise, Bool_t rounding=kTRUE, Bool_t addPedestal=kTRUE);
48 Double_t GetQmaxCorr(Float_t rmsy0, Float_t rmsz0);
49 Double_t GetQtotCorr(Float_t rmsy0, Float_t rmsz0, Float_t gain, Float_t thr);
52 //static void Simul(const char* simul, Int_t npoints);
53 static Double_t GaussConvolution(Double_t x0, Double_t x1, Double_t k0, Double_t k1, Double_t s0, Double_t s1);
54 static Double_t GaussExpConvolution(Double_t x0, Double_t s0,Double_t t1);
55 static Double_t GaussGamma4(Double_t x, Double_t s0, Double_t p1);
56 static Double_t Gamma4(Double_t x, Double_t p0, Double_t p1);
58 Float_t fMNprim; ///< mean number of primary electrons
59 // //electrons part input
60 Int_t fNprim; ///< mean number of primary electrons
61 Int_t fNtot; ///< total number of electrons
62 Float_t fQtot; ///< total charge - Gas gain flucuation taken into account
64 Float_t fDiff; ///< diffusion sigma
65 Float_t fDiffLong; ///< diffusion sigma longitudinal direction
66 Float_t fY; ///< y position
67 Float_t fZ; ///< z postion
68 Float_t fAngleY; ///< y angle - tan(y)
69 Float_t fAngleZ; ///< z angle - tan z
72 // // electron part simul
73 TVectorD fSec; //!< number of secondary electrons
74 TVectorD fPosY; //!< position y for each electron
75 TVectorD fPosZ; //!< position z for each electron
76 TVectorD fGain; //!< gg for each electron
78 TVectorD fStatY; //!< stat Y
79 TVectorD fStatZ; //!< stat Y
83 TMatrixD fDigits; ///< response matrix
84 static TF1* fPRF; ///< Pad response
85 static TF1* fTRF; ///< Time response function
86 ClassDef(AliTPCclusterFast,1) // container for
90 class AliTPCtrackFast: public TObject {
93 void Add(AliTPCtrackFast &track2);
95 static void Simul(const char* simul, Int_t ntracks, Double_t diff);
96 Double_t CookdEdxNtot(Double_t f0,Float_t f1);
97 Double_t CookdEdxQtot(Double_t f0,Float_t f1);
98 Double_t CookdEdxNtotThr(Double_t f0,Float_t f1, Double_t thr, Int_t dEdxMode);
99 Double_t CookdEdxQtotThr(Double_t f0,Float_t f1, Double_t thr, Int_t dEdxMode);
101 Double_t CookdEdxDtot(Double_t f0,Float_t f1, Float_t gain,Float_t thr, Float_t noise, Bool_t corr, Int_t dEdxMode);
102 Double_t CookdEdxDmax(Double_t f0,Float_t f1,Float_t gain,Float_t thr, Float_t noise, Bool_t corr, Int_t dEdxMode);
104 Double_t CookdEdx(Int_t npoints, Double_t *amp, Double_t f0,Float_t f1, Int_t dEdxMode);
106 Float_t fMNprim; ///< mean number of primary electrons
107 Float_t fAngleY; ///< y angle - tan(y)
108 Float_t fAngleZ; ///< z angle - tan z
109 Float_t fDiff; ///< diffusion
110 Float_t fDiffLong; ///< diffusion sigma longitudinal direction
111 Int_t fN; ///< number of clusters
112 TClonesArray *fCl; ///< array of clusters
114 Bool_t fInit; ///< initialization flag
117 ClassDef(AliTPCtrackFast,2)
122 ClassImp(AliTPCclusterFast)
123 ClassImp(AliTPCtrackFast)
126 TF1 *AliTPCclusterFast::fPRF=0;
127 TF1 *AliTPCclusterFast::fTRF=0;
130 AliTPCtrackFast::AliTPCtrackFast():
143 void AliTPCtrackFast::Add(AliTPCtrackFast &track2){
144 if (!track2.fInit) return;
150 void AliTPCtrackFast::MakeTrack(){
153 if (!fCl) fCl = new TClonesArray("AliTPCclusterFast",160);
155 // 0.) Init data structure
157 for (Int_t i=0;i<fN;i++){
158 AliTPCclusterFast * cluster = (AliTPCclusterFast*) fCl->UncheckedAt(i);
159 if (!cluster) cluster = new ((*fCl)[i]) AliTPCclusterFast;
163 // 1.) Create hits - with crosstalk diffusion
165 for (Int_t i=0;i<fN;i++){
166 Double_t tY = i*fAngleY;
167 Double_t tZ = i*fAngleZ;
168 AliTPCclusterFast * cluster = (AliTPCclusterFast*) fCl->UncheckedAt(i);
169 AliTPCclusterFast * clusterm = (AliTPCclusterFast*) fCl->UncheckedAt(TMath::Max(i-1,0));
170 AliTPCclusterFast * clusterp = (AliTPCclusterFast*) fCl->UncheckedAt(TMath::Min(i+1,159));
171 if (!cluster) cluster = new ((*fCl)[i]) AliTPCclusterFast;
173 Double_t posY = tY-TMath::Nint(tY);
174 Double_t posZ = tZ-TMath::Nint(tZ);
175 cluster->SetParam(fMNprim,fDiff, fDiffLong, posY,posZ,fAngleY,fAngleZ);
177 cluster->GenerElectrons(cluster, clusterm, clusterp);
180 // 2.) make digitization
182 for (Int_t i=0;i<fN;i++){
183 AliTPCclusterFast * cluster = (AliTPCclusterFast*) fCl->UncheckedAt(i);
189 Double_t AliTPCtrackFast::CookdEdxNtot(Double_t f0,Float_t f1){
190 /// Double_t CookdEdxNtot(Double_t f0,Float_t f1); // dEdx_{hit} reconstructed meen number of electrons
193 for (Int_t i=0;i<fN;i++){
194 AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
195 amp[i]=cluster->fNtot;
197 return CookdEdx(fN,amp,f0,f1,0);
200 Double_t AliTPCtrackFast::CookdEdxQtot(Double_t f0,Float_t f1){
201 /// dEdx_{Q} reconstructed mean number of electronsxGain
204 for (Int_t i=0;i<fN;i++){
205 AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
206 amp[i]=cluster->fQtot;
208 return CookdEdx(fN,amp,f0,f1,0);
212 Double_t AliTPCtrackFast::CookdEdxNtotThr(Double_t f0,Float_t f1, Double_t thr, Int_t dEdxMode){
213 /// dEdx_{hit} reconstructed mean number of electrons
214 /// thr = threshold in terms of the number of electrons
215 /// dEdxMode = algorithm to deal with trhesold values replacing
220 Double_t minAbove=-1;
221 for (Int_t i=0;i<fN;i++){
222 AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
223 Double_t clQ= cluster->fNtot;
228 if (minAbove<0) minAbove=clQ;
229 if (minAbove>clQ) minAbove=clQ;
232 if (dEdxMode==-1) return Double_t(nBellow)/Double_t(fN);
234 for (Int_t i=0;i<fN;i++){
235 AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
236 Double_t clQ= cluster->fNtot;
238 if (dEdxMode==0) amp[i]=clQ; // dEdxMode0 - not threshold - keep default
241 if (dEdxMode==1 && clQ>thr) amp[i]=clQ; // dEdxMode1 - skip if bellow
242 if (dEdxMode==1 && clQ<thr) amp[i]=0; // dEdxMode1 - skip if bellow
245 if (dEdxMode==2 && clQ>thr) amp[i]=clQ; // dEdxMode2 - use 0 if below
246 if (dEdxMode==2 && clQ<thr) amp[i]=0; // dEdxMode2 - use 0 if below
249 if (dEdxMode==3) amp[i]=(clQ>thr)?clQ:thr; // dEdxMode3 - use thr if below
250 if (dEdxMode==4) amp[i]=(clQ>thr)?clQ:minAbove; // dEdxMode4 - use minimal above threshold if bellow thr
252 return CookdEdx(fN,amp,f0,f1, dEdxMode);
257 Double_t AliTPCtrackFast::CookdEdxQtotThr(Double_t f0,Float_t f1, Double_t thr, Int_t dEdxMode){
258 /// dEdx_{Q} reconstructed mean number of electrons xgain
259 /// thr = threshold in terms of the number of electrons
260 /// dEdxMode = algorithm to deal with trhesold values replacing
266 Double_t minAbove=-1;
267 for (Int_t i=0;i<fN;i++){
268 AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
269 Double_t clQ= cluster->fQtot;
274 if (minAbove<0) minAbove=clQ;
275 if (minAbove>clQ) minAbove=clQ;
278 if (dEdxMode==-1) return Double_t(nBellow)/Double_t(fN);
280 for (Int_t i=0;i<fN;i++){
281 AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
282 Double_t clQ= cluster->fQtot;
284 if (dEdxMode==0) amp[i]=clQ; // dEdxMode0 - not threshold - keep default
287 if (dEdxMode==1 && clQ>thr) amp[i]=clQ; // dEdxMode1 - skip if bellow
288 if (dEdxMode==1 && clQ<thr) amp[i]=0; // dEdxMode1 - skip if bellow
291 if (dEdxMode==2 && clQ>thr) amp[i]=clQ; // dEdxMode2 - use 0 if below
292 if (dEdxMode==2 && clQ<thr) amp[i]=0; // dEdxMode2 - use 0 if below
295 if (dEdxMode==3) amp[i]=(clQ>thr)?clQ:thr; // dEdxMode3 - use thr if below
296 if (dEdxMode==4) amp[i]=(clQ>thr)?clQ:minAbove; // dEdxMode4 - use minimal above threshold if bellow thr
298 return CookdEdx(fN,amp,f0,f1, dEdxMode);
305 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){
306 /// total charge in the cluster (sum of the pad x time matrix ), hits were digitized before, but additional
307 /// actions can be specified by switches // dEdx_{Qtot}
312 for (Int_t i=0;i<fN;i++){
313 AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
315 if (dEdxMode==0) camp = cluster->GetQtot(gain,0,noise);
317 camp = cluster->GetQtot(gain,thr,noise);
319 if (doCorr) corr = cluster->GetQtotCorr(0.5,0.5,gain,thr);
323 if (minAmp <0) minAmp=camp;
324 if (minAmp >camp) minAmp=camp;
327 if (dEdxMode==3) for (Int_t i=0;i<fN;i++) if (amp[i]<=0) amp[i]=thr;
328 if (dEdxMode==4) for (Int_t i=0;i<fN;i++) if (amp[i]<=0) amp[i]=minAmp;
329 return CookdEdx(fN,amp,f0,f1, dEdxMode);
334 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){
335 /// maximal charge in the cluster (maximal amplitude in the digit matrix), hits were digitized before,
336 /// but additional actions can be specified by switches
341 for (Int_t i=0;i<fN;i++){
342 AliTPCclusterFast * cluster = ( AliTPCclusterFast *)((*fCl)[i]);
344 if (dEdxMode==0) camp = cluster->GetQmax(gain,0,noise);
346 camp = cluster->GetQmax(gain,thr,noise);
348 if (doCorr) corr = cluster->GetQmaxCorr(0.5,0.5);
352 if (minAmp <0) minAmp=camp;
353 if (minAmp >camp) minAmp=camp;
356 if (dEdxMode==3) for (Int_t i=0;i<fN;i++) if (amp[i]<=0) amp[i]=thr;
357 if (dEdxMode==4) for (Int_t i=0;i<fN;i++) if (amp[i]<=0) amp[i]=minAmp;
358 return CookdEdx(fN,amp,f0,f1, dEdxMode);
362 Double_t AliTPCtrackFast::CookdEdx(Int_t npoints, Double_t *amp,Double_t f0,Float_t f1, Int_t dEdxMode){
363 /// Calculate truncated mean
364 /// npoints - number of points in array
365 /// amp - array with points
366 /// f0-f1 - truncation range
367 /// dEdxMode - specify handling of the 0 clusters, actual handling - filling of amplitude defiend in algorithm above
368 /// dEdxMode = 0 - accept everything
369 /// dEdxMode = 1 - do not count 0 amplitudes
370 /// dEdxMode = 2 - use 0 amplitude as it is
371 /// dEdxMode = 3 - use amplitude as it is (in above function amp. replace by the thr)
372 /// dEdxMode = 4 - use amplitude as it is (in above function amp. replace by the minimal amplitude)
375 // 0. sorted the array of amplitudes
378 TMath::Sort(npoints,amp,index,kFALSE);
380 // 1.) Calculate truncated mean from the selected range of the array (ranking statistic )
381 // dependening on the dEdxMode 0 amplitude can be skipped
382 Float_t sum0=0, sum1=0,sum2=0;
385 for (Int_t i=0;i<npoints;i++) if (amp[index[i]]>0) above++;
387 for (Int_t i=0;i<npoints;i++){
389 if (dEdxMode==1 && amp[index[i]]==0) {
392 if (accepted<npoints*f0) continue;
393 if (accepted>npoints*f1) continue;
395 sum1+= amp[index[i]];
396 sum2+= amp[index[i]];
399 if (dEdxMode==-1) return 1-Double_t(above)/Double_t(npoints);
400 if (sum0<=0) return 0;
404 void AliTPCtrackFast::Simul(const char* fname, Int_t ntracks, Double_t diffFactor){
407 AliTPCtrackFast fast;
408 TTreeSRedirector *pcstream = new TTreeSRedirector(fname,"recreate");
409 for (Int_t itr=0; itr<ntracks; itr++){
411 fast.fMNprim=(10.+100*gRandom->Rndm());
412 if (gRandom->Rndm()>0.5) fast.fMNprim=1./(0.00001+gRandom->Rndm()*0.1);
414 fast.fDiff =0.01 +0.35*gRandom->Rndm();
415 // fast.fDiffLong = fast.fDiff*0.6/1.;
416 fast.fDiffLong = fast.fDiff*diffFactor/1.;
418 fast.fAngleY = 4.0*(gRandom->Rndm()-0.5);
419 fast.fAngleZ = 4.0*(gRandom->Rndm()-0.5);
422 if (itr%100==0) printf("%d\n",itr);
423 (*pcstream)<<"simulTrack"<<
433 AliTPCclusterFast::AliTPCclusterFast(){
436 fDigits.ResizeTo(5,7);
439 void AliTPCclusterFast::Init(){
440 /// reset all counters
442 const Int_t knMax=10000;
443 fMNprim=0; // mean number of primary electrons
444 // //electrons part input
445 fNprim=0; // mean number of primary electrons
446 fNtot=0; // total number of electrons
447 fQtot=0; // total charge - Gas gain flucuation taken into account
449 fPosY.ResizeTo(knMax);
450 fPosZ.ResizeTo(knMax);
451 fGain.ResizeTo(knMax);
452 fSec.ResizeTo(knMax);
455 for (Int_t i=0; i<knMax; i++){
465 AliTPCclusterFast::~AliTPCclusterFast(){
469 void AliTPCclusterFast::SetParam(Float_t mnprim, Float_t diff, Float_t diffL,Float_t y, Float_t z, Float_t ky, Float_t kz){
472 fMNprim = mnprim; fDiff = diff; fDiffLong=diffL;
474 fAngleY=ky; fAngleZ=kz;
476 Double_t AliTPCclusterFast::GetNsec(){
477 /// Generate number of secondary electrons
478 /// copy of procedure implemented in geant
480 const Double_t FPOT=20.77E-9, EEND=10E-6, EEXPO=2.2; // EEND1=1E-6;
481 const Double_t XEXPO=-EEXPO+1, YEXPO=1/XEXPO;
482 const Double_t W=20.77E-9;
483 Float_t RAN = gRandom->Rndm();
484 //Double_t edep = TMath::Power((TMath::Power(FPOT,XEXPO)*(1-RAN)+TMath::Power(EEND,XEXPO)*RAN),YEXPO);
485 //edep = TMath::Min(edep, EEND);
486 //return TMath::Nint(edep/W);
487 return TMath::Nint(TMath::Power((TMath::Power(FPOT,XEXPO)*(1-RAN)+TMath::Power(EEND,XEXPO)*RAN),YEXPO)/W);
490 void AliTPCclusterFast::GenerElectrons(AliTPCclusterFast *cl0, AliTPCclusterFast *clm, AliTPCclusterFast *clp){
493 const Int_t knMax=1000;
494 cl0->fNprim = gRandom->Poisson(cl0->fMNprim); //number of primary electrons
495 // cl0->fNtot=0; //total number of electrons
496 // cl0->fQtot=0; //total number of electrons after gain multiplification
503 // for (Int_t i=0;i<knMax;i++){
506 for (Int_t iprim=0; iprim<cl0->fNprim;iprim++){
507 Float_t dN = cl0->GetNsec();
509 Double_t yc = cl0->fY+(gRandom->Rndm()-0.5)*cl0->fAngleY;
510 Double_t zc = cl0->fZ+(gRandom->Rndm()-0.5)*cl0->fAngleZ;
511 Double_t rc = (gRandom->Rndm()-0.5);
513 for (Int_t isec=0;isec<=dN;isec++){
516 Double_t y = gRandom->Gaus(0,cl0->fDiff)+yc;
517 Double_t z = gRandom->Gaus(0,cl0->fDiff)+zc;
518 Double_t r = gRandom->Gaus(0,cl0->fDiffLong)+rc;
520 AliTPCclusterFast *cl=cl0;
521 if (r<-0.5 &&cl) cl=clm;
522 if (r>0.5 &&cl) cl=clp;
524 Double_t gg = -TMath::Log(gRandom->Rndm());
525 cl->fPosY[cl->fNtot]=y;
526 cl->fPosZ[cl->fNtot]=z;
527 cl->fGain[cl->fNtot]=gg;
533 // cl->sumY2Q+=gg*y*y;
535 // cl->sumZ2Q+=gg*z*z;
536 if (cl->fNtot>=knMax) continue;
538 if (cl0->fNtot>=knMax) break;
543 // fStatY[1]=sumYQ/sumQ;
544 // fStatY[2]=sumY2Q/sumQ-fStatY[1]*fStatY[1];
546 // fStatZ[1]=sumZQ/sumQ;
547 // fStatZ[2]=sumZ2Q/sumQ-fStatZ[1]*fStatZ[1];
551 void AliTPCclusterFast::Digitize(){
554 for (Int_t i=0; i<5;i++)
555 for (Int_t j=0; j<7;j++){
560 for (Int_t iel = 0; iel<fNtot; iel++){
561 for (Int_t di=-2; di<=2;di++)
562 for (Int_t dj=-3; dj<=3;dj++){
563 Float_t fac = fPRF->Eval(di-fPosY[iel])*fTRF->Eval(dj-fPosZ[iel]);
565 fDigits(2+di,3+dj)+=fac;
575 // void AliTPCclusterFast::Simul(const char* fname, Int_t npoints){
579 // AliTPCclusterFast fast;
580 // TTreeSRedirector cstream(fname);
581 // for (Int_t icl=0; icl<npoints; icl++){
582 // Float_t nprim=(10+20*gRandom->Rndm());
583 // Float_t diff =0.01 +0.35*gRandom->Rndm();
584 // Float_t posY = gRandom->Rndm()-0.5;
585 // Float_t posZ = gRandom->Rndm()-0.5;
587 // Float_t ky = 4.0*(gRandom->Rndm()-0.5);
588 // Float_t kz = 4.0*(gRandom->Rndm()-0.5);
589 // fast.SetParam(nprim,diff,posY,posZ,ky,kz);
590 // fast.GenerElectrons();
592 // if (icl%10000==0) printf("%d\n",icl);
593 // cstream<<"simul"<<
600 Double_t AliTPCclusterFast::GetQtot(Float_t gain, Float_t thr, Float_t noise, Bool_t brounding, Bool_t baddPedestal){
604 for (Int_t ip=0;ip<5;ip++){
605 Float_t pedestal=gRandom->Rndm()-0.5; //pedestal offset different for each pad
606 for (Int_t it=0;it<7;it++){
607 Float_t amp = gain*fDigits(ip,it)+gRandom->Gaus()*noise;
608 if (baddPedestal) amp+=pedestal;
609 if (brounding) amp=TMath::Nint(amp);
610 if (amp>thr) sum+=amp;
616 Double_t AliTPCclusterFast::GetQmax(Float_t gain, Float_t thr, Float_t noise, Bool_t brounding, Bool_t baddPedestal){
620 for (Int_t ip=0;ip<5;ip++){
621 Float_t pedestal=gRandom->Rndm()-0.5; //pedestal offset different for each pad
622 for (Int_t it=0;it<7;it++){
623 Float_t amp = gain*fDigits(ip,it)+gRandom->Gaus()*noise;
624 if (baddPedestal) amp+=pedestal;
625 if (brounding) amp=TMath::Nint(amp);
626 if (amp>max && amp>thr) max=amp;
634 Double_t AliTPCclusterFast::GetQmaxCorr(Float_t rmsy0, Float_t rmsz0){
635 /// Gaus distribution convolueted with rectangular
636 /// Gaus width sy and sz is determined by RF width and diffusion
637 /// Integral of Q is equal 1
638 /// Q max is calculated at position fY,fX
640 Double_t sy = TMath::Sqrt(rmsy0*rmsy0+fDiff*fDiff);
641 Double_t sz = TMath::Sqrt(rmsz0*rmsz0+fDiff*fDiff);
642 return GaussConvolution(fY,fZ, fAngleY,fAngleZ,sy,sz);
646 Double_t AliTPCclusterFast::GetQtotCorr(Float_t rmsy0, Float_t rmsz0, Float_t gain, Float_t thr){
647 /// Calculates the fraction of the charge over threshol to total charge
648 /// The response function
650 Double_t sy = TMath::Sqrt(rmsy0*rmsy0+fDiff*fDiff);
651 Double_t sz = TMath::Sqrt(rmsz0*rmsz0+fDiff*fDiff);
652 Double_t sumAll=0,sumThr=0;
653 Double_t qtot = GetQtot(gain,thr,0); // sum of signal over threshold
654 Double_t qmax = GetQmax(gain,thr,0); // qmax
658 for (Int_t iter=0;iter<2;iter++){
659 for (Int_t iy=-2;iy<=2;iy++)
660 for (Int_t iz=-2;iz<=2;iz++){
661 Double_t val = GaussConvolution(fY-iy,fZ-iz, fAngleY,fAngleZ,sy,sz);
662 Double_t qlocal =TMath::Nint(qnorm*val);
663 if (qlocal>thr) sumThr+=qlocal;
666 if (sumAll>0&&sumThr>0) corr=(sumThr)/sumAll;
667 if (sumThr==0) corr=GetQmaxCorr(0.5,0.5);
669 if (corr>0) qnorm=qtot/corr;
679 Double_t AliTPCclusterFast::GaussConvolution(Double_t x0, Double_t x1, Double_t k0, Double_t k1, Double_t s0, Double_t s1){
680 /// 2 D gaus convoluted with angular effect
681 /// See in mathematica:
682 /// Simplify[Integrate[Exp[-(x0-k0*xd)*(x0-k0*xd)/(2*s0*s0)-(x1-k1*xd)*(x1-k1*xd)/(2*s1*s1)]/(s0*s1),{xd,-1/2,1/2}]]
684 /// TF1 f1("f1","AliTPCclusterFast::GaussConvolution(x,0,1,0,0.1,0.1)",-2,2)
685 /// TF2 f2("f2","AliTPCclusterFast::GaussConvolution(x,y,1,1,0.1,0.1)",-2,2,-2,2)
687 const Float_t kEpsilon = 0.0001;
688 if ((TMath::Abs(k0)+TMath::Abs(k1))<kEpsilon*(s0+s1)){
689 // small angular effect
690 Double_t val = (TMath::Gaus(x0,0,s0)*TMath::Gaus(x1,0,s1))/(s0*s1*2.*TMath::Pi());
694 Double_t sigma2 = k1*k1*s0*s0+k0*k0*s1*s1;
695 Double_t exp0 = TMath::Exp(-(k1*x0-k0*x1)*(k1*x0-k0*x1)/(2*sigma2));
697 Double_t sigmaErf = 2*s0*s1*TMath::Sqrt(2*sigma2);
698 Double_t erf0 = TMath::Erf( (k0*s1*s1*(k0-2*x0)+k1*s0*s0*(k1-2*x1))/sigmaErf);
699 Double_t erf1 = TMath::Erf( (k0*s1*s1*(k0+2*x0)+k1*s0*s0*(k1+2*x1))/sigmaErf);
700 Double_t norm = 1./TMath::Sqrt(sigma2);
701 norm/=2.*TMath::Sqrt(2.*TMath::Pi());
702 Double_t val = norm*exp0*(erf0+erf1);
708 Double_t AliTPCclusterFast::GaussExpConvolution(Double_t x0, Double_t s0,Double_t t1){
709 /// 2 D gaus convoluted with exponential
710 /// Integral nomalized to 1
711 /// See in mathematica:
712 /// Simplify[Integrate[Exp[-(x0-x1)*(x0-x1)/(2*s0*s0)]*Exp[-x1*t1],{x1,0,Infinity}]]
713 /// TF1 fgexp("fgexp","AliTPCclusterFast::GaussExpConvolution(x,0.5,1)",-2,2)
715 Double_t exp1 = (s0*s0*t1-2*x0)*t1/2.;
716 exp1 = TMath::Exp(exp1);
717 Double_t erf = 1+TMath::Erf((-s0*s0*t1+x0)/(s0*TMath::Sqrt(2.)));
718 Double_t val = exp1*erf;
725 Double_t AliTPCclusterFast::Gamma4(Double_t x, Double_t p0, Double_t p1){
726 /// Gamma 4 Time response function of ALTRO
729 Double_t g1 = TMath::Exp(-4.*x/p1);
730 Double_t g2 = TMath::Power(x/p1,4);
736 Double_t AliTPCclusterFast::GaussGamma4(Double_t x, Double_t s0, Double_t p1){
737 /// Gamma 4 Time response function of ALTRO convoluted with Gauss
738 /// Simplify[Integrate[Exp[-(x0-x1)*(x0-x1)/(2*s0*s0)]*Exp[-4*x1/p1]*(x/p1)^4/s0,{x1,0,Infinity}]]
739 /// TF1 fgg4("fgg4","AliTPCclusterFast::GaussGamma4(x,0.5,0.5)",-2,2)
741 Double_t exp1 = (8*s0*s0-4.*p1*x)/(p1*p1);
742 exp1 = TMath::Exp(exp1);
743 Double_t erf1 = 1+TMath::Erf((-4*s0/p1+x/s0)/TMath::Sqrt(2));
744 // Double_t xp14 = TMath::Power(TMath::Abs((x/p1)),4);
750 // Analytical sollution only in 1D - too long expression
751 // Simplify[Integrate[Exp[-(x0-(x1-k*x2))*(x0-(x1-k*x2))/(2*s0*s0)]*Exp[-(x1*t1-k*x2)],{x2,-1,1}]]
754 // No analytical solution
756 //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}]]