1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 #include "AliGenHBTosl.h"
21 //__________________________________________________________
22 /////////////////////////////////////////////////////////////
24 // class AliGenHBTosl //
26 // Genarator simulating particle correlations //
28 // The main idea of the generator is to produce particles //
29 // according to some distribution of two particle //
30 // property. In HBT they are qout,qsie and qlong. //
31 // In order to be able to generate signal that produces //
32 // given two particle correlation background must be //
33 // known before in order to produce the shape of signal //
34 // to randomize given distribution from. //
36 // The generator works as follows: //
37 // 1. Coarse Background (fQCoarseBackground) is generated //
38 // ade from the particles //
39 // given by the external generator (variable //
40 // fGenerator) by the mixing technique. //
41 // 2. Coarse signal is prduced by multiplying Coarse //
42 // background by a required function //
43 // See method FillCoarseSignal //
44 // 3. Signal is randomized out of the coarse signal //
45 // histogram (two particle property). First particle //
46 // is taken from the external generator, and the //
47 // second one is CALCULATED on the basis of the first //
48 // one and the two particle property (qout,qside,qlong)//
49 // Background is made by the mixing out of the //
50 // genereted signal events. //
51 // This step is cotinued up to the moment signal //
52 // histogram has enough statistics (data member //
54 // See method StartSignalPass1() //
55 // 4. chi is calculated for each bin (chiarray variqable) //
56 // (not the chi2 because sign is important) //
57 // Two particle prioperty //
58 // (qout,qside,qlong) is chosen at the points that //
59 // chi is the smallest. First particle is taken from //
60 // the the external generator (fGenerator) and second's /
61 // momenta are caclulated out of their momenta and //
62 // (qout,qside,qlong). Background is updated //
63 // continuesely for all the events. This step is //
64 // continued until stability conditions are fullfiled //
65 // or maximum number of iteration is reached. //
66 // 5. The same as step 4 but events are stored. //
68 ////////////////////////////////////////////////////////////
76 #include <TParticle.h>
80 #include <TStopwatch.h>
83 #include "AliGenCocktailAfterBurner.h"
84 #include "AliGeVSimParticle.h"
85 #include "AliGenGeVSim.h"
86 #include "AliGenHIJINGpara.h"
89 /***********************************************************/
94 ClassImp(AliGenHBTosl)
96 AliGenHBTosl::AliGenHBTosl():
98 fQCoarseBackground(0x0),
103 fQSecondBackground(0x0),
109 fNBinsToScale(Int_t(fQNBins*0.1)),
111 fSignalShapeCreated(0),
112 fMaxIterations(1000),
113 fMaxChiSquereChange(0.01),
114 fMaxChiSquerePerNDF(1.5),
117 fSamplePhiMin(-0.01),
118 fSamplePhiMax(TMath::TwoPi()+0.01),
124 //default constructor
126 /***********************************************************/
128 AliGenHBTosl::AliGenHBTosl(Int_t n, Int_t pid):
130 fQCoarseBackground(0x0),
135 fQSecondBackground(0x0),
141 fNBinsToScale(Int_t(fQNBins*0.1)),
143 fSignalShapeCreated(kFALSE),
144 fMaxIterations(1000),
145 fMaxChiSquereChange(0.01),
146 fMaxChiSquerePerNDF(1.5),
149 fSamplePhiMin(-0.01),
150 fSamplePhiMax(TMath::TwoPi()+0.01),
156 //default constructor
159 AliGenHBTosl::AliGenHBTosl(const AliGenHBTosl & hbt):
161 fQCoarseBackground(0x0),
166 fQSecondBackground(0x0),
172 fNBinsToScale(Int_t(fQNBins*0.1)),
174 fSignalShapeCreated(kFALSE),
175 fMaxIterations(1000),
176 fMaxChiSquereChange(0.01),
177 fMaxChiSquerePerNDF(1.5),
180 fSamplePhiMin(-0.01),
181 fSamplePhiMax(TMath::TwoPi()+0.01),
190 /***********************************************************/
192 AliGenHBTosl::~AliGenHBTosl()
195 delete fQCoarseSignal;
196 delete fQCoarseBackground;
200 delete fQSecondSignal;
201 delete fQSecondBackground;
204 /***********************************************************/
206 void AliGenHBTosl::Init()
208 //Initializes generator
209 if (fGenerator == 0x0)
212 AliGenHIJINGpara* bkggen = new AliGenHIJINGpara(fNpart*4);
216 AliGenGeVSim * gevsim = new AliGenGeVSim(0.0);
217 AliGeVSimParticle* kplus = new AliGeVSimParticle(fPID,1,fNpart, 0.17, 0.9);
218 gevsim->AddParticleType(kplus);
225 AliMevSimConfig *c = new AliMevSimConfig(1);
226 c->SetRectPlane(1); // reaction plane control, model 4
229 AliGenMevSim *mevsim = new AliGenMevSim(c);
230 mevsim->SetPtRange(0.001, 3);
231 mevsim->SetMomentumRange(0.1, 3);
232 mevsim->SetTrackingFlag(0);
233 mevsim->SetOrigin(0.0, 0.0, 0.0);
234 mevsim->SetSigma(0.0, 0.0, 0.0);
235 AliMevSimParticle *kplus = new AliMevSimParticle(kKPlus, fNpart, 0, 0.25, 0.0, 2, 0.15, 0.0, 0.0 );
236 mevsim->AddParticleType(kplus);
240 fGenerator->SetOrigin(fOrigin[0],fOrigin[1],fOrigin[2]);
241 static const Double_t kDegToRadCF = 180./TMath::Pi();
242 fGenerator->SetMomentumRange(fPtMin,fPtMax);
243 fGenerator->SetPhiRange(kDegToRadCF*fPhiMin,kDegToRadCF*fPhiMax);
244 fGenerator->SetYRange(fYMin,fYMax);
245 fGenerator->SetThetaRange(kDegToRadCF*fThetaMin,kDegToRadCF*fThetaMax);
250 // fQCoarseBackground = new TH3D("fQCoarseBackground","",fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange);
251 // fQCoarseSignal = new TH3D("fQCoarseSignal","fQCoarseSignal",fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange);
252 // fQCoarseBackground->Sumw2();
253 // fQCoarseSignal->Sumw2();
255 fQSignal = new TH3D("fQSignal1","fQSignal",fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange);
256 fQBackground = new TH3D("fQBackground1","fQBackground",fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange);
258 fQSecondSignal = new TH3D("fQSignal2","fQSignal",fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange);
259 fQSecondBackground = new TH3D("fQBackground2","fQBackground",fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange);
262 fQBackground->Sumw2();
263 fQSecondSignal->Sumw2();
264 fQSecondBackground->Sumw2();
266 fLogFile = new ofstream("BadEvent",ios::out);
269 /***********************************************************/
271 void AliGenHBTosl::Generate()
275 ofstream& logfile = *fLogFile;
276 logfile<<"Generate"<<"Attempts to generate "<<fNpart<<" particles.";
279 if (fStackBuffer == 0x0) fStackBuffer = new TList();
280 //Here is initialization level
281 if (fSignalShapeCreated == kFALSE)
283 TH3D *hs = 0x0, *hb = 0x0;
286 file = TFile::Open("QTSignal.root");
289 hs = (TH3D*)file->Get("fQSignal1");
290 if (hs) hs->SetDirectory(0x0);
294 file = TFile::Open("QTBackground.root");
297 hb = (TH3D*)file->Get("fQBackground1");
298 if (hb) hb->SetDirectory(0x0);
304 Info("Generate","**********************************");
305 Info("Generate","Found starting histograms in files");
306 Info("Generate","**********************************");
314 TH3D *cs = 0x0, *cb = 0x0;
315 file = TFile::Open("QTCoarseBackground.root");
318 cb = (TH3D*)file->Get("fQCoarseBackground");
319 if (cb) cb->SetDirectory(0x0);
323 file = TFile::Open("QTCoarseSignal.root");
326 cs = (TH3D*)file->Get("fQCoarseSignal");
327 if (cs) cs->SetDirectory(0x0);
334 Info("Generate","Got Coarse signal and bkg from files");
335 delete fQCoarseBackground;
336 delete fQCoarseSignal;
338 fQCoarseBackground = cb;
344 Info("Generate","Got Coarse bkg from file");
345 delete fQCoarseBackground;
346 fQCoarseBackground = cb;
350 fQCoarseBackground = new TH3D("fQCoarseBackground","",fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange);
351 fQCoarseBackground->Sumw2();
353 FillCoarse(); //create coarse background - just to know the spectrum
356 fQCoarseSignal = new TH3D("fQCoarseSignal","fQCoarseSignal",fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange);
357 fQCoarseSignal->Sumw2();
358 FillCoarseSignal();//create first coarse signal by brutal multplication coarse background and required function shape
361 StartSignal(); //Initilizes the stack that is used for generation
363 fSignalShapeCreated = kTRUE;
366 AliStack* stack = RotateStack();
368 AliStack* genstack = fGenerator->GetStack();
371 genstack = new AliStack(fNpart);
372 fGenerator->SetStack(genstack);
379 fGenerator->Generate();
381 if ( genstack->GetNtrack() < fNpart/2)
383 Warning("Generate","************************************************************");
384 Warning("Generate","Generator generated (%d) less particles then expected (%d).",
385 stack->GetNtrack(),fNpart/2);
386 Warning("Generate","************************************************************");
389 TH3D* work = new TH3D("work","work",fQNBins,-fQRange,fQRange,fQNBins,-fQRange,fQRange,fQNBins,-fQRange,fQRange);
390 work->SetDirectory(0x0);
393 Double_t*** chiarray = new Double_t** [fQNBins+1];
394 Double_t*** sigarray = new Double_t** [fQNBins+1];
396 for (Int_t i = 1; i<=fQNBins; i++)
398 chiarray[i] = new Double_t* [fQNBins+1];
399 sigarray[i] = new Double_t* [fQNBins+1];
401 for (Int_t k = 1; k<=fQNBins; k++)
403 chiarray[i][k] = new Double_t [fQNBins+1];
404 sigarray[i][k] = new Double_t [fQNBins+1];
409 Double_t scale = Scale(fQSignal,fQBackground);
410 work->Divide(fQSignal,fQBackground,scale);
412 Double_t binwdh = work->GetBinWidth(1)/2.;
414 for (Int_t k = 1; k<=fQNBins; k++)
416 Double_t z = work->GetZaxis()->GetBinCenter(k);
417 for (Int_t j = 1; j<=fQNBins; j++)
419 Double_t y = work->GetYaxis()->GetBinCenter(j);
420 for (Int_t i = 1; i<=fQNBins; i++)
422 sigarray[i][j][k] = fQSignal->GetBinContent(i,j,k);//store current value of signal histogram
423 Double_t x = work->GetXaxis()->GetBinCenter(i);//get center value of a bin (qinv)
424 Double_t v = GetQOutQSideQLongCorrTheorValue(x,y,z);//get expected value of CF in that qinv
425 Double_t diff = v - work->GetBinContent(i,j,k);//store difference betweeon current value, and desired value
426 chiarray[i][j][k] = diff; // no-x x is a weight to get good distribution
433 snprintf(msg,1000, "\n");
434 Int_t middlebin = fQNBins/2;
436 for (Int_t k = middlebin-5; k < middlebin+5; k++)
438 Double_t tx = work->GetXaxis()->GetBinCenter(30);
439 Double_t ty = work->GetYaxis()->GetBinCenter(30);
440 Double_t tz = work->GetZaxis()->GetBinCenter(k);
441 snprintf(msg,1000, "% 6.5f ",GetQOutQSideQLongCorrTheorValue(tx,ty,tz));
446 for (Int_t k = middlebin-5; k < middlebin+5; k++)
448 snprintf(msg,1000, "% 6.5f ",work->GetBinContent(30,30,k));
453 for (Int_t k = middlebin-5; k < middlebin+5; k++)
455 snprintf(msg, 1000, "% 6.5f ",chiarray[30][30][k]);
460 TParticle particle(fPID,0,-1,-1,-1,-1,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
461 TParticle* second = &particle;
463 Bool_t shortloop = kTRUE;
464 Int_t sc = 0;//security check against infinite loop
466 while ( (ntr+1) < fNpart)
488 loopmax = fQNBins/2+fQNBins/4;
489 loopmin = fQNBins/2-fQNBins/4;
493 for (Int_t k = loopmin; k <=loopmax; k++ )
495 qlong = work->GetZaxis()->GetBinCenter(k);
496 for (Int_t j = loopmin; j<=loopmax; j++)
498 qside = work->GetYaxis()->GetBinCenter(j);
499 for (Int_t i = loopmin; i<=loopmax; i++)
501 qout = work->GetXaxis()->GetBinCenter(i);
502 if (chiarray[xmax][ymax][zmax] < chiarray[i][j][k])
509 // Double_t qdist = TMath::Sqrt(qout*qout + qside*qside + qlong*qlong);
511 // Double_t fact = chiarray[i][j][k];//chiarray is chi2
512 // if (fact > work->GetBinError(i,j,k))//if differece between what we want and
513 // { //what we have is bigger than stat. error
514 // xmax = i; //we force to fill that bin
522 Double_t qlongc = work->GetZaxis()->GetBinCenter(zmax);
523 Double_t qsidec = work->GetYaxis()->GetBinCenter(ymax);
524 Double_t qoutc = work->GetXaxis()->GetBinCenter(xmax);
527 snprintf(msg,1000, "Generate Fill bin chi2(%d,%d,%d)=%f",xmax,ymax,zmax,chiarray[xmax][ymax][zmax]);
530 qout = gRandom->Uniform(qoutc -binwdh, qoutc +binwdh);
531 qside = gRandom->Uniform(qsidec-binwdh, qsidec+binwdh);
532 qlong = gRandom->Uniform(qlongc-binwdh, qlongc+binwdh);
534 TParticle* first = 0;
537 while (jj < genstack->GetNtrack())
539 TParticle* tmpp = genstack->Particle(jj++);
540 if (tmpp->GetPdgCode() == fPID)
542 if (CheckParticle(tmpp,0x0,stack) == kFALSE)
552 if ( fDebug > 2 ) Info("StartSignal","No more particles of that type");
556 //Here put the check if this particle do not fall into signal region with other partticle
558 Int_t retval = GetThreeD(first,second,qout,qside,qlong);
561 //Info("StartSignal","Can not find momenta for this OSL and particle");
564 //in case this particle is falling into signal area with another
565 //particle we take a another pair
566 //it can intruduce artificial correlations
567 Bool_t checkresult = CheckParticle(second,first,stack);
568 if ( checkresult && (sc < 10) )
575 //Put on output stack
577 SetTrack(second,ntr);
579 //Put on internal stack
581 SetTrack(first,etmp,stack);
582 SetTrack(second,etmp,stack);
584 Double_t y = GetQOutQSideQLongCorrTheorValue(qoutc,qsidec,qlongc);
586 sigarray[xmax][ymax][zmax] ++;
587 chiarray[xmax][ymax][zmax] = scale*sigarray[xmax][ymax][zmax]/fQBackground->GetBinContent(xmax,ymax,zmax);
588 chiarray[xmax][ymax][zmax] = (y - chiarray[xmax][ymax][zmax]);
592 Mix(fStackBuffer,fQBackground,fQSecondSignal); //upgrate background
593 Mix(stack,fQSignal,fQSecondBackground); //upgrate signal
597 for (Int_t i = 1; i<=fQNBins; i++)
599 for (Int_t k = 1; k<=fQNBins; k++)
601 delete [] chiarray[i][k];
602 delete [] sigarray[i][k];
604 delete [] chiarray[i];
605 delete [] sigarray[i];
610 /***********************************************************/
612 void AliGenHBTosl::GetOneD(TParticle* first, TParticle* second,Double_t qinv)
614 //deprecated method that caclulates momenta of the second particle
615 // out of qinv and the first particle
616 //first particle is rotated that only X is non-zero
619 Double_t m = first->GetMass();
620 Double_t msqrd = m*m;
621 Double_t fourmassSquered = 4.*msqrd;
623 //Condition that R must fullfill to be possible to have qinv less smaller then randomized
624 // Double_t rRange = qinv*TMath::Sqrt(qinv*qinv + fourmassSquered)/fourmassSquered;
625 // Double_t r = gRandom->Uniform(rRange);
627 Double_t r = gRandom->Uniform(qinv);
628 Double_t phi = gRandom->Uniform(TMath::TwoPi());
630 Double_t firstPx = first->P();//first particle is rotated that only X is non-zero thus P==Px
631 Double_t px = 2.*msqrd*firstPx + firstPx*qinv*qinv;
632 Double_t temp = qinv*qinv*qinv*qinv + fourmassSquered * (qinv*qinv - r*r );
635 Error("GetOneD","temp is less then 0: %f",temp);
638 temp = temp*(msqrd+firstPx*firstPx);
640 px = (px - TMath::Sqrt(temp))/(2.*msqrd);
642 Double_t py = r*TMath::Sin(phi);
643 Double_t pz = r*TMath::Cos(phi);
645 TVector3 firstpvector(first->Px(),first->Py(),first->Pz());
646 TVector3 vector(px,py,pz);
647 Rotate(firstpvector,vector);
649 Double_t e = TMath::Sqrt(msqrd + vector.X()*vector.X() + vector.Y()*vector.Y() + vector.Z()*vector.Z());
650 second->SetMomentum(vector.X(),vector.Y(),vector.Z(),e);
651 // TParticle* f = new TParticle(first->GetPdgCode(),0,-1,-1,-1,-1, firstPx,0,0,e=TMath::Sqrt(msqrd+firstPx*firstPx),0.0,0.0,0.0,0.0);
652 // TParticle(pdg, is, parent, -1, kFirstDaughter, kLastDaughter,
653 // px, py, pz, e, vx, vy, vz, tof);
655 AliDebug(1,Form("Randomized qinv = %f, obtained = %f",qinv,GetQInv(first,second)));
658 /***********************************************************/
660 Int_t AliGenHBTosl::GetThreeD(TParticle* first,TParticle* second, Double_t qout, Double_t qside, Double_t qlong)
662 //deprecated method that caclulates momenta of the second particle
663 //out of qout qside and qlong and the first particle
664 Double_t m = first->GetMass();
667 Double_t px = first->P();//first particle is rotated that only X is non-zero thus P==Px
668 Double_t px2 = px*px;
671 Double_t qout2 = qout*qout;
672 Double_t qside2 = qside*qside;
673 Double_t qlong2 = qlong*qlong;
676 Double_t util1 = 4.*px2 - qside2;//4*P1x^2 - Y^2
679 Info("GetThreeD","4.*px2* - qside2 is negative px: %f, qside: %f",px,qside);
682 Double_t util2 = TMath::Sqrt(px2*qout2*util1);
685 Double_t p2x,p2y,p2z;
687 // if ( (qside >= 0) && (qout >= 0) && (qlong >= 0))
691 Double_t tmp = px*(2.*px2 - qside2);
696 tmp = qout - TMath::Sqrt(util1);
697 p2y = - (tmp*qside)/(2.*px);
700 tmp = 4.*m2 + 2.*qout2+qlong2;
702 tmp -= 2.*util2;//!!!
706 Double_t m2px2 = m2+px2;
707 Double_t tmp2 = m2px2*tmp;
709 tmp = 4.*(m2px2+qout2) + qlong2;
712 tmp *= 4.*(m2px2) + qlong2;
713 tmp *= qlong2*qlong2;
718 Error("","Argument of sqrt is negative");
722 tmp2 += TMath::Sqrt(tmp);
724 tmp = 8.0*px*m2px2*m2px2;
725 p2z = -TMath::Sqrt(tmp2/tmp);
726 if (qlong < 0) p2z = -p2z;
731 Double_t tmp = px*(2.*px2 - qside2);
736 tmp = qout - TMath::Sqrt(util1);
737 p2y = - (tmp*qside)/(2.*px);
740 tmp = 4.*m2 + 2.*qout2+qlong2;
742 tmp += 2.*util2;//!!!
746 Double_t m2px2 = m2+px2;
747 Double_t tmp2 = m2px2*tmp;
749 tmp = 4.*(m2px2+qout2) + qlong2;
752 tmp *= 4.*(m2px2) + qlong2;
753 tmp *= qlong2*qlong2;
758 Error("","Argument of sqrt is negative");
762 tmp2 += TMath::Sqrt(tmp);
764 tmp = 8.0*px*m2px2*m2px2;
765 p2z = -TMath::Sqrt(tmp2/tmp);
766 if (qlong < 0) p2z = -p2z;
769 // if ( (qside >= 0) && (qout >= 0) && (qlong >= 0)) p2z = -p2z;
771 TVector3 firstpvector(first->Px(),first->Py(),first->Pz());
772 TVector3 vector(p2x,p2y,p2z);
773 Rotate(firstpvector,vector);
775 Double_t e = TMath::Sqrt(m2 + vector.X()*vector.X() + vector.Y()*vector.Y() + vector.Z()*vector.Z());
776 second->SetMomentum(vector.X(),vector.Y(),vector.Z(),e);
779 if ( AliDebugLevel() > 3 )
781 e=TMath::Sqrt(m2+px*px);
782 TParticle* f = new TParticle(first->GetPdgCode(),0,-1,-1,-1,-1, px , 0.0, 0.0, e,0.0,0.0,0.0,0.0);
784 e = TMath::Sqrt(m2 + p2x*p2x + p2y*p2y + p2z*p2z);
785 TParticle* s = new TParticle(first->GetPdgCode(),0,-1,-1,-1,-1, p2x, p2y, p2z, e, 0.0, 0.0, 0.0, 0.0);
788 GetQOutQSideQLong(f,s,qo, qs, ql);
790 Info("GetThreeD","TEST");
793 Info("GetThreeD","Required %f %f %f",qout,qside,qlong);
794 Info("GetThreeD","Got %f %f %f",qo,qs,ql);
798 Info("GetThreeD","!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
803 /***********************************************************/
805 void AliGenHBTosl::StartSignal()
807 //Starts the signal histograms
808 ofstream& logfile = *fLogFile;
810 logfile<<"************************************************"<<endl;
811 logfile<<"************************************************"<<endl;
812 logfile<<" StartSignal "<<endl;
813 logfile<<"************************************************"<<endl;
814 logfile<<"************************************************"<<endl;
820 TParticle particle(fPID,0,-1,-1,-1,-1,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
821 TParticle* second = &particle;
823 TIter next(fStackBuffer);
824 while(( stack=(AliStack*)next() ))
829 AliStack* genstack = fGenerator->GetStack();
832 genstack = new AliStack(fNpart);
833 fGenerator->SetStack(genstack);
841 //We alread have detailed histograms and we do not need Coarse anymore
842 delete fQCoarseSignal;
843 delete fQCoarseBackground;
844 fQCoarseSignal = 0x0;
845 fQCoarseBackground = 0x0;
848 const Double_t kNDF = fQNBins*fQNBins*fQNBins;
850 TH3D* work = new TH3D("work","work",fQNBins,-fQRange,fQRange,fQNBins,-fQRange,fQRange,fQNBins,-fQRange,fQRange);
852 work->SetDirectory(0x0);
855 Double_t binwdh = work->GetBinWidth(1)/2.;
857 Double_t*** chiarray = new Double_t** [fQNBins+1];
858 Double_t*** sigarray = new Double_t** [fQNBins+1];
860 for (Int_t i = 1; i<=fQNBins; i++)
862 chiarray[i] = new Double_t* [fQNBins+1];
863 sigarray[i] = new Double_t* [fQNBins+1];
865 for (Int_t k = 1; k<=fQNBins; k++)
867 chiarray[i][k] = new Double_t [fQNBins+1];
868 sigarray[i][k] = new Double_t [fQNBins+1];
873 Float_t chisqrchange = fMaxChiSquereChange + 1.;
874 Float_t chisqrPerDF = fMaxChiSquerePerNDF;
875 Float_t chisqrold = 0.0;
878 Int_t niterations = 1;
879 Int_t rotaxisorder = 1;//defines order of looping over 3D histo (X,Y,Z or Y,Z,X or Z,X,Y)
882 Bool_t shortloop = kTRUE;
883 TCanvas* c1 = new TCanvas();
887 Info("StartSignal","\n\n\n\nSecond Pass\n\n\n\n");
889 while ( ( (chisqrPerDF > fMaxChiSquereChange) || flag) && (niterations++ < fMaxIterations) )
892 logfile<<"StartSignal\n";
893 logfile<<" Row 1 Theory, 2 current value, 3 Chi2 \n";
895 Double_t chisqrnew = 0.0;
898 Double_t scale = Scale(fQSignal,fQBackground);
899 work->Divide(fQSignal,fQBackground,scale);
901 if ( (counter%100) == 0)
905 snprintf(buff,50, "QTWorkPass2.%3d.root",counter);
906 TFile* file = TFile::Open(buff,"update");
908 work->SetDirectory(0x0);
912 snprintf(buff,50, "QTBackgroundPass2.%3d.root",counter);
913 file = TFile::Open(buff,"update");
914 fQBackground->Write();
915 fQBackground->SetDirectory(0x0);
919 snprintf(buff,50, "QTSignalPass2.%3d.root",counter);
920 file = TFile::Open(buff,"update");
922 fQSignal->SetDirectory(0x0);
928 Int_t novertresh = 0;
929 for (Int_t k = 1; k<=fQNBins; k++)
931 Double_t z = work->GetZaxis()->GetBinCenter(k);
932 for (Int_t j = 1; j<=fQNBins; j++)
934 Double_t y = work->GetYaxis()->GetBinCenter(j);
935 for (Int_t i = 1; i<=fQNBins; i++)
937 Double_t x = work->GetXaxis()->GetBinCenter(i);//get center value of a bin (qout)
938 sigarray[i][j][k] = fQSignal->GetBinContent(i,j,k);//store current value of signal histogram
939 Double_t v = GetQOutQSideQLongCorrTheorValue(x,y,z);//get expected value of CF in that qinv
940 Double_t diff = v - work->GetBinContent(i,j,k);//store difference betweeon current value, and desired value
941 chiarray[i][j][k] = diff; // no-x x is a weight to get good distribution
942 Double_t be = work->GetBinError(i,j,k);
943 chisqrnew += diff*diff/(be*be);//add up chisq
945 //even if algorithm is stable (chi sqr change less then threshold)
946 //and any bin differs more then 5% from expected value we continue
947 Double_t fact = diff;
948 if (TMath::Abs(fact) > 0.1)
962 for (Int_t k = 25; k < 36; k++)
964 Double_t tx = work->GetXaxis()->GetBinCenter(30);
965 Double_t ty = work->GetYaxis()->GetBinCenter(30);
966 Double_t tz = work->GetZaxis()->GetBinCenter(k);
967 snprintf(msg,1000, "% 6.5f ",GetQOutQSideQLongCorrTheorValue(tx,ty,tz));
972 for (Int_t k = 25; k < 36; k++)
974 snprintf(msg, 1000, "%6.5f ",work->GetBinContent(30,30,k));
979 for (Int_t k = 25; k < 36; k++)
981 snprintf(msg,1000, "% 6.5f ",chiarray[30][30][k]);
986 chisqrchange = TMath::Abs(chisqrnew - chisqrold)/chisqrnew;
987 chisqrold = chisqrnew;
989 chisqrPerDF = chisqrnew/kNDF;
991 Info("StartSignal","Iteration %d Chi-sq change %f%%",niterations,chisqrchange*100.0);
992 Info("StartSignal","ChiSq = %f, NDF = %f, ChiSq/NDF = %f",chisqrnew, kNDF, chisqrPerDF );
993 Info("StartSignal","novertresh = %d",novertresh);
996 stack = RotateStack();
998 fGenerator->Generate();
999 Int_t ninputparticle = 0, ntr = 0;
1000 if ( genstack->GetNtrack() < fNpart/2)
1002 Warning("StartSignal","**********************************");
1003 Warning("StartSignal","Generator generated (%d) less particles then expected (%d).",
1004 genstack->GetNtrack(),fNpart/2);
1005 Warning("StartSignal","**********************************");
1008 Int_t sc = 0; //security check against infinite loop
1009 while ( (ntr+1) < fNpart)//ntr is number of track generated up to now
1024 switch (rotaxisorder)
1043 if (rotaxisorder > 3) rotaxisorder = 1;
1057 // Bool_t force = kFALSE;
1058 for ( k = 1; k <=nrange;k++ )
1060 for ( j = 1; j<=nrange; j++)
1062 for ( i = 1; i<=nrange; i++)
1064 if ( (chiarray[*cx][*cy][*cz]) > (chiarray[xmax][ymax][zmax]) )
1071 // Double_t fact = chiarray[*cx][*cy][*cz];//chiarray is chi2*qinv
1072 // if (fact > work->GetBinError(*cx,*cy,*cz))//if differece between what we want and
1073 // { //what we have is bigger than stat. error
1074 // //we force to fill that bin
1075 // qout = work->GetXaxis()->GetBinCenter(*cx);
1076 // qside = work->GetYaxis()->GetBinCenter(*cy);
1077 // qlong = work->GetZaxis()->GetBinCenter(*cz);
1079 // Info("StartSignal"," bin: (%d,%d,%d) loop status (%d,%d,%d) \nUsing Force: chiarray: %f \nq(o,s,l): (%f,%f,%f) signal: %d background: %d binerror: %f",
1080 // *cx,*cy,*cz,i,j,k,fact,qout,qside,qlong,
1081 // (Int_t)sigarray[*cx][*cy][*cz],(Int_t)fQBackground->GetBinContent(*cx,*cy,*cz),work->GetBinError(*cx,*cy,*cz));
1087 // if (force) break;
1089 // if (force) break;
1093 qout = work->GetXaxis()->GetBinCenter(xmax);
1094 qside = work->GetYaxis()->GetBinCenter(ymax);
1095 qlong = work->GetZaxis()->GetBinCenter(zmax);
1097 // Info("StartSignal"," bin: (%d,%d,%d) chiarray: %f \nq(o,s,l): (%f,%f,%f) signal: %d background: %d binerror: %f",
1098 // xmax,ymax,zmax,chiarray[xmax][ymax][zmax],qout,qside,qlong,
1099 // (Int_t)sigarray[xmax][ymax][zmax],
1100 // (Int_t)fQBackground->GetBinContent(xmax,ymax,zmax),
1101 // work->GetBinError(xmax,ymax,zmax));
1103 qout = gRandom->Uniform(qout-binwdh,qout+binwdh);
1104 qside = gRandom->Uniform(qside-binwdh,qside+binwdh);
1105 qlong = gRandom->Uniform(qlong-binwdh,qlong+binwdh);
1107 TParticle* first = 0;
1108 while (ninputparticle < genstack->GetNtrack())
1110 TParticle* tmpp = genstack->Particle(ninputparticle++);
1111 if (tmpp->GetPdgCode() == fPID)
1113 if (CheckParticle(tmpp,0x0,stack) == kFALSE)
1123 if ( fDebug > 2 ) Info("StartSignal","No more particles of that type");
1127 Int_t retval = GetThreeD(first,second,qout,qside,qlong);
1130 Info("StartSignal","Can not find momenta for this OSL and particle OSL = %f %f %f",qout,qside,qlong);
1136 //in case this particle is falling into signal area with another
1137 //particle we take a another pair
1138 //it can intruduce artificial correlations
1139 Bool_t checkresult = CheckParticle(second,first,stack);
1140 if ( checkresult && (sc < 10) )
1147 //Put on output stack
1148 SetTrack(first,ntr,stack);
1149 SetTrack(second,ntr,stack);
1151 Double_t y = GetQOutQSideQLongCorrTheorValue(qout,qside,qlong);
1153 sigarray[xmax][ymax][zmax] ++;
1154 chiarray[xmax][ymax][zmax] = scale*sigarray[xmax][ymax][zmax]/fQBackground->GetBinContent(xmax,ymax,zmax);
1155 chiarray[xmax][ymax][zmax] = (y - chiarray[xmax][ymax][zmax]);
1158 Info("StartSignal","Mixing background...");
1159 Mix(fStackBuffer,fQBackground,fQSecondBackground); //upgrate background
1160 Info("StartSignal","Mixing signal...");
1161 Mix(stack,fQSignal,fQSecondSignal); //upgrate background
1164 // if ( (chisqrPerDF < 2.0) && (fSwapped == kFALSE) )
1166 // SwapGeneratingHistograms();
1170 TFile* filef = TFile::Open("QTBackground.root","recreate");
1171 fQBackground->Write();
1172 fQBackground->SetDirectory(0x0);
1176 filef = TFile::Open("QTSignal.root","recreate");
1178 fQSignal->SetDirectory(0x0);
1186 for (Int_t i = 1; i<=fQNBins; i++)
1188 for (Int_t k = 1; k<=fQNBins; k++)
1190 delete [] chiarray[i][k];
1191 delete [] sigarray[i][k];
1193 delete [] chiarray[i];
1194 delete [] sigarray[i];
1200 /***********************************************************/
1202 void AliGenHBTosl::StartSignalPass1()
1204 //This method makes first part of the initialization of working histograms
1205 //It randomizes qout, qside and qlong from the coarse signal histogram
1207 Bool_t flag = kTRUE;
1208 TParticle particle(fPID,0,-1,-1,-1,-1,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0);
1209 TParticle* second = &particle;
1214 Info("StartSignalPass1","\n\nFirst Pass\n\n");
1218 Info("StartSignalPass1","NextEvent");
1219 AliStack* stack = RotateStack();
1220 AliStack* genstack = fGenerator->GetStack();
1222 fGenerator->Generate();
1223 Int_t j = 0, ntr = 0;
1224 if ( genstack->GetNtrack() < fNpart/2)
1226 Warning("StartSignalPass1","**********************************");
1227 Warning("StartSignalPass1","Generator generated (%d) less particles then expected (%d).",
1228 genstack->GetNtrack(),fNpart/2);
1229 Warning("StartSignalPass1","**********************************");
1232 Int_t sc = 0;//security check against infinite loop
1233 while ((ntr+1)<fNpart)
1236 // Info("StartSignal","Number of track on output stack: = %d", ntr);
1237 // Info("StartSignal","Number of track on input stack: = %d\n", j);
1239 TParticle* first = 0;
1240 while (j < genstack->GetNtrack())
1242 TParticle* tmpp = genstack->Particle(j++);
1243 if (tmpp->GetPdgCode() == fPID)
1245 if (CheckParticle(tmpp,0x0,stack) == kFALSE)
1252 Info("StartSignalPass1","Particle did not pass the safety check 1");
1260 if ( fDebug > 2 ) Info("StartSignalPass1","No more particles of that type");
1265 SetTrack(first,ntr,stack);
1267 fQCoarseSignal->GetRandom3(qout,qside,qlong);
1269 Int_t retval = GetThreeD(first,second,qout,qside,qlong);
1272 //Info("StartSignal","Can not find momenta for this OSL and particle");
1275 //in case this particle is falling into signal area with another
1276 //particle we take a another pair
1277 //it can intruduce artificial correlations
1278 Bool_t checkresult = CheckParticle(second,first,stack);
1279 if ( checkresult && (sc < 10) )
1282 Info("StartSignalPass1","Particle did not pass the safety check 2");
1289 SetTrack(second,ntr,stack);
1292 Mix(stack,fQSignal,fQSecondSignal);
1293 Mix(fStackBuffer,fQBackground,fQSecondBackground);
1297 for (Int_t k = 1; k<=fQNBins; k++)
1299 for (j = 1; j<=fQNBins; j++)
1301 for (Int_t i = 1; i<=fQNBins; i++)
1303 if ( (fQBackground->GetBinContent(i,j,k) < fMinFill) )
1305 //(fQSignal->GetBinContent(i,j,k) < fMinFill) ||
1306 Info("StartSignalPass1","bin (%d,%d,%d): signal=%f background=%f",i,j,k,
1307 fQSignal->GetBinContent(i,j,k),fQBackground->GetBinContent(i,j,k));
1308 flag = kTRUE;//continue while
1309 break;//breakes for not while
1312 if (flag == kTRUE) break;
1314 if (flag == kTRUE) break;
1321 /***********************************************************/
1323 void AliGenHBTosl::FillCoarseSignal()
1325 //Makes coarse signal by multiplying the coarse background and required function
1326 Info("FillCoarseSignal","START");
1327 for (Int_t k = 1; k <=fQNBins ;k++ )
1329 Double_t z = fQCoarseBackground->GetZaxis()->GetBinCenter(k);
1330 for (Int_t j = 1; j <=fQNBins; j++)
1332 Double_t y = fQCoarseBackground->GetYaxis()->GetBinCenter(j);
1333 for (Int_t i = 1; i <=fQNBins; i++)
1335 Double_t x = fQCoarseBackground->GetXaxis()->GetBinCenter(i);
1336 Double_t v = GetQOutQSideQLongCorrTheorValue(x,y,z);
1337 Info("FillCoarseSignal","Bin (%d,%d,%d): osl(%f,%f,%f)=%f",i,j,k,x,y,z,v);
1338 fQCoarseSignal->SetBinContent(i,j,k,v*fQCoarseBackground->GetBinContent(i,j,k));
1343 //if (AliDebugLevel())
1346 Info("FillCoarseSignal","DONE");
1348 /***********************************************************/
1350 void AliGenHBTosl::FillCoarse()
1352 //creates the statistical background histogram on the base of input from
1354 Info("FillCoarse","START");
1360 TH3D tmph("tmph","tmph",2,0,1,2,0,1,2,0,1);
1365 // if (niter > 20) break;
1367 cout<<niter++<<" bincont "<<fQCoarseBackground->GetBinContent(30,30,28)
1368 <<" "<<fQCoarseBackground->GetBinContent(30,30,29)
1369 <<" "<<fQCoarseBackground->GetBinContent(30,30,30)
1370 <<" "<<fQCoarseBackground->GetBinContent(30,30,31)
1371 <<" "<<fQCoarseBackground->GetBinContent(30,30,32)
1375 stack = RotateStack();
1376 fGenerator->SetStack(stack);
1378 fGenerator->Generate();
1380 Mix(fStackBuffer,fQCoarseBackground,&tmph);
1384 Info("FillCoarse","fMinFill = %d",fMinFill);
1385 for (Int_t k = 1; k<=fQNBins; k++)
1387 for (Int_t j = 1; j<=fQNBins; j++)
1389 for (Int_t i = 1; i<=fQNBins; i++)
1391 if ( fQCoarseBackground->GetBinContent(i,j,k) < fMinFill )
1394 Info("FillCoarse","bin (%d,%d,%d)=%f",i,j,k,fQCoarseBackground->GetBinContent(i,j,k));
1406 fGenerator->SetStack(0x0);
1407 Info("FillCoarse","DONE");
1410 /***********************************************************/
1412 void AliGenHBTosl::Mix(TList* eventbuffer,TH3D* denominator,TH3D* denominator2)
1414 //Fills denominators
1415 //Mixes events stored in the eventbuffer and fills the background histograms
1416 static TStopwatch stoper;
1418 if (eventbuffer == 0x0)
1420 Error("Mix","Buffer List is null.");
1424 if (denominator == 0x0)
1426 Error("Mix","Denominator histogram is null.");
1430 if (denominator2 == 0x0)
1432 Error("Mix","Denominator2 histogram is null.");
1436 Info("Mix","%s",denominator->GetName());
1439 TIter next(eventbuffer);
1440 AliStack* firstevent;
1441 AliStack* secondevent = 0x0;
1443 while(( firstevent=(AliStack*)next() ))
1445 if (secondevent == 0x0)
1447 secondevent = firstevent;
1450 // Info("Mix","Mixing %#x with %#x",firstevent,secondevent);
1451 for(Int_t j = 0; j < firstevent->GetNtrack(); j++ )
1453 TParticle* firstpart = firstevent->Particle(j);
1455 Float_t phi = firstpart->Phi();
1456 if ( (phi < fSamplePhiMin) || ( phi > fSamplePhiMax)) continue;
1458 // Info("Mix","Mixing %d phi %f min %f max %f",j,phi,fSamplePhiMin,fSamplePhiMax);
1460 for(Int_t i = 0; i < secondevent->GetNtrack(); i++ )
1462 TParticle* secondpart = secondevent->Particle(i);
1463 phi = secondpart->Phi();
1464 if ( (phi < fSamplePhiMin) || ( phi > fSamplePhiMax)) continue;
1469 GetQOutQSideQLong(firstpart,secondpart,qout,qside,qlong);
1470 denominator->Fill(qout,qside,qlong);
1471 denominator2->Fill(qout,qside,qlong);
1475 secondevent = firstevent;
1481 /***********************************************************/
1483 void AliGenHBTosl::Mix(AliStack* stack, TH3D* numerator, TH3D* numerator2)
1485 //fils numerator with particles from stack
1486 static TStopwatch stoper;
1489 Error("Mix","Stack is null.");
1493 if ( (numerator == 0x0) || (numerator2 == 0x0) )
1495 Error("Mix","Numerator histogram is null.");
1499 Info("Mix","%s",numerator->GetName());
1502 for(Int_t j = 0; j < stack->GetNtrack(); j++ )
1504 TParticle* firstpart = stack->Particle(j);
1505 Float_t phi = firstpart->Phi();
1506 if ( (phi < fSamplePhiMin) || ( phi > fSamplePhiMax)) continue;
1508 for(Int_t i = j+1; i < stack->GetNtrack(); i++ )
1510 TParticle* secondpart = stack->Particle(i);
1511 phi = secondpart->Phi();
1512 if ( (phi < fSamplePhiMin) || ( phi > fSamplePhiMax)) continue;
1516 GetQOutQSideQLong(firstpart,secondpart,qout,qside,qlong);
1517 numerator->Fill(qout,qside,qlong);
1518 numerator2->Fill(qout,qside,qlong);
1525 /***********************************************************/
1527 Double_t AliGenHBTosl::GetQInv(TParticle* f, TParticle* s)
1530 // cout<<f->Px()<<" "<<s->Px()<<endl;
1531 Double_t pxdiff = f->Px() - s->Px();
1532 Double_t pydiff = f->Py() - s->Py();
1533 Double_t pzdiff = f->Pz() - s->Pz();
1534 Double_t ediff = f->Energy() - s->Energy();
1536 Double_t qinvl = ediff*ediff - ( pxdiff*pxdiff + pydiff*pydiff + pzdiff*pzdiff );
1537 Double_t qinv = TMath::Sqrt(TMath::Abs(qinvl));
1540 /***********************************************************/
1542 void AliGenHBTosl::GetQOutQSideQLong(TParticle* f, TParticle* s,Double_t& out, Double_t& side, Double_t& lon)
1544 //returns qout,qside and qlong of the pair of particles
1545 out = side = lon = 10e5;
1547 Double_t pxsum = f->Px() + s->Px();
1548 Double_t pysum = f->Py() + s->Py();
1549 Double_t pzsum = f->Pz() + s->Pz();
1550 Double_t esum = f->Energy() + s->Energy();
1551 Double_t pxdiff = f->Px() - s->Px();
1552 Double_t pydiff = f->Py() - s->Py();
1553 Double_t pzdiff = f->Pz() - s->Pz();
1554 Double_t ediff = f->Energy() - s->Energy();
1555 Double_t kt = 0.5*TMath::Hypot(pxsum,pysum);
1557 Double_t k2 = pxsum*pxdiff+pysum*pydiff;
1568 side = (f->Px()*s->Py()-s->Px()*f->Py())/kt;
1571 Double_t beta = pzsum/esum;
1572 Double_t gamma = 1.0/TMath::Sqrt((1.-beta)*(1.+beta));
1574 lon = gamma * ( pzdiff - beta*ediff );
1576 // out = TMath::Abs(out);
1577 // side = TMath::Abs(side);
1578 // lon = TMath::Abs(lon);
1581 /***********************************************************/
1583 Double_t AliGenHBTosl::Scale(TH3D* num, TH3D* den)
1585 //Calculates the factor that should be used to scale
1586 //quatience of num and den to 1 at tail
1588 AliDebug(1,"Entered");
1591 AliError("No numerator");
1596 AliError("No denominator");
1600 if(fNBinsToScale < 1)
1602 AliError("Number of bins for scaling is smaller than 1");
1605 Int_t fNBinsToScaleX = fNBinsToScale;
1606 Int_t fNBinsToScaleY = fNBinsToScale;
1607 Int_t fNBinsToScaleZ = fNBinsToScale;
1609 Int_t nbinsX = num->GetNbinsX();
1610 if (fNBinsToScaleX > nbinsX)
1612 AliError("Number of X bins for scaling is bigger thnan number of bins in histograms");
1616 Int_t nbinsY = num->GetNbinsX();
1617 if (fNBinsToScaleY > nbinsY)
1619 AliError("Number of Y bins for scaling is bigger thnan number of bins in histograms");
1623 Int_t nbinsZ = num->GetNbinsZ();
1624 if (fNBinsToScaleZ > nbinsZ)
1626 AliError("Number of Z bins for scaling is bigger thnan number of bins in histograms");
1630 AliDebug(1,"No errors detected");
1632 Int_t offsetX = nbinsX - fNBinsToScaleX - 1; //bin that we start loop over bins in axis X
1633 Int_t offsetY = nbinsY - fNBinsToScaleY - 1; //bin that we start loop over bins in axis Y
1634 Int_t offsetZ = nbinsZ - fNBinsToScaleZ - 1; //bin that we start loop over bins in axis Z
1636 Double_t densum = 0.0;
1637 Double_t numsum = 0.0;
1639 for (Int_t k = offsetZ; k<nbinsZ; k++)
1640 for (Int_t j = offsetY; j<nbinsY; j++)
1641 for (Int_t i = offsetX; i<nbinsX; i++)
1643 if ( num->GetBinContent(i,j,k) > 0.0 )
1646 densum += den->GetBinContent(i,j,k);
1647 numsum += num->GetBinContent(i,j,k);
1651 AliDebug(1,Form("numsum=%f densum=%f fNBinsToScaleX=%d fNBinsToScaleY=%d fNBinsToScaleZ=%d",
1652 numsum,densum,fNBinsToScaleX,fNBinsToScaleY,fNBinsToScaleZ));
1654 if (numsum == 0) return 0.0;
1655 Double_t ret = densum/numsum;
1657 AliDebug(1,Form("returning %f",ret));
1661 /***********************************************************/
1663 void AliGenHBTosl::TestCoarseSignal()
1665 //Tests how works filling from generated histogram shape
1666 TH3D* work = new TH3D("work","work",fQNBins,-fQRange,fQRange,fQNBins,-fQRange,fQRange,fQNBins,-fQRange,fQRange);
1668 // for (Int_t i = 0; i < fQCoarseBackground->GetEntries() ;i++)
1671 // fQCoarseSignal->GetRandom3(x,y,z);
1672 // work->Fill(x,y,z);
1675 TCanvas* c1 = new TCanvas();
1678 c1->SaveAs("QTwork.root");
1679 TFile* file = TFile::Open("QTwork.root","update");
1681 work->SetDirectory(0x0);
1684 fQCoarseSignal->Draw();
1685 c1->SaveAs("QTCoarseSignal.root");
1686 file = TFile::Open("QTCoarseSignal.root","update");
1687 fQCoarseSignal->Write();
1688 fQCoarseSignal->SetDirectory(0x0);
1691 fQCoarseBackground->Draw();
1692 c1->SaveAs("QTCoarseBackground.root");
1693 file = TFile::Open("QTCoarseBackground.root","update");
1694 fQCoarseBackground->Write();
1695 fQCoarseBackground->SetDirectory(0x0);
1698 TH1 *result = (TH1*)fQCoarseBackground->Clone("ratio");
1699 result->SetTitle("ratio");
1700 Float_t normfactor = Scale(work,fQCoarseBackground);
1701 result->Divide(work,fQCoarseBackground,normfactor);//work
1706 c1->SaveAs("QTresult.root");
1707 file = TFile::Open("QTresult.root","update");
1709 result->SetDirectory(0x0);
1715 /***********************************************************/
1717 void AliGenHBTosl::SetTrack(TParticle* p, Int_t& ntr)
1719 //Shortcut to PushTrack(bla,bla,bla,bla.............)
1722 Error("SetTrack(TParticle*,Int_t&)","Particle has zero momentum");
1727 Int_t pdg = p->GetPdgCode();
1728 Double_t px = p->Px();
1729 Double_t py = p->Py();
1730 Double_t pz = p->Pz();
1731 Double_t e = p->Energy();
1732 Double_t vx = p->Vx();
1733 Double_t vy = p->Vy();
1734 Double_t vz = p->Vz();
1735 Double_t tof = p->T();
1738 p->GetPolarisation(pol);
1740 Double_t polx = pol.X();
1741 Double_t poly = pol.Y();
1742 Double_t polz = pol.Z();
1743 TMCProcess mech = AliGenCocktailAfterBurner::IntToMCProcess(p->GetUniqueID());
1744 Float_t weight = p->GetWeight();
1746 AliGenerator::PushTrack(fTrackIt, -1, pdg, px, py, pz, e, vx, vy, vz, tof,polx, poly, polz, mech, ntr, weight);
1748 /***********************************************************/
1750 void AliGenHBTosl::SetTrack(TParticle* p, Int_t& ntr, AliStack* stack) const
1752 //Shortcut to SetTrack(bla,bla,bla,bla.............)
1755 Error("SetTrack(TParticle*,Int_t&,AliStack*)","Particle has zero momentum");
1759 Int_t pdg = p->GetPdgCode();
1760 Double_t px = p->Px();
1761 Double_t py = p->Py();
1762 Double_t pz = p->Pz();
1763 Double_t e = p->Energy();
1765 stack->PushTrack(fTrackIt, -1, pdg, px, py, pz, e, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, kPPrimary, ntr,1,0);
1767 /***********************************************************/
1769 void AliGenHBTosl::Rotate(TVector3& relvector, TVector3& vector)
1771 //This method rotates vector about the angeles that are needed to rotate
1772 //relvector from postion (firstPx,0,0) to its actual positon
1773 //In other words: To make equations easier
1775 static TVector3 first;
1776 if (AliDebugLevel()>=1)
1778 first.SetXYZ(relvector.x(),relvector.y(),relvector.z());
1781 Double_t firstPx = TMath::Sqrt( relvector.x()*relvector.x() +
1782 relvector.y()*relvector.y() +
1783 relvector.z()*relvector.z() );
1785 Double_t rotAngleZ = -TMath::ATan2(relvector.y(),relvector.x());//calculating rot angles
1786 relvector.RotateZ(rotAngleZ);
1787 rotAngleZ = -rotAngleZ;
1788 Double_t rotAngleY = -TMath::ATan2(relvector.z(),relvector.x());
1790 vector.RotateY(rotAngleY);
1791 vector.RotateZ(rotAngleZ);
1793 if (AliDebugLevel()>5)
1795 TVector3 test(firstPx,0.0,0.0);
1796 test.RotateY(rotAngleY);
1797 test.RotateZ(rotAngleZ);
1798 AliInfo(Form("Rotation test: px %f %f",first.x(),test.x()));
1799 AliInfo(Form("Rotation test: py %f %f",first.y(),test.y()));
1800 AliInfo(Form("Rotation test: pz %f %f",first.z(),test.z()));
1803 /***********************************************************/
1805 Double_t AliGenHBTosl::Rotate(Double_t x,Double_t y,Double_t z)
1807 //Rotates vector to base where only x - coordinate is no-zero, and returns that
1809 Double_t xylength = TMath::Hypot(x,y);
1810 Double_t sinphi = -y/xylength;
1811 Double_t cosphi = x/xylength;
1813 Double_t xprime = cosphi*x - sinphi*y;
1814 Double_t yprime = sinphi*x + cosphi*y;
1817 Double_t a1 = -TMath::ATan2(v.Y(),v.X());
1819 if (AliDebugLevel()>5)
1821 AliInfo(Form("Xpr = %f Ypr = %f",xprime,yprime));
1822 AliInfo(Form("Calc sin = %f, and %f",sinphi,TMath::Sin(a1)));
1823 AliInfo(Form("Calc cos = %f, and %f",cosphi,TMath::Cos(a1)));
1826 Double_t xprimezlength = TMath::Hypot(xprime,z);
1828 Double_t sintheta = z/xprimezlength;
1829 Double_t costheta = xprime/xprimezlength;
1832 Double_t xbis = sintheta*z + costheta*(cosphi*x - sinphi*y);
1834 AliInfo(Form("Calculated rot %f, modulus %f",xbis,TMath::Sqrt(x*x+y*y+z*z)));
1837 /***********************************************************/
1839 AliStack* AliGenHBTosl::RotateStack()
1841 //swaps to next stack last goes to first and is reseted
1844 if ( fStackBuffer->GetSize() >= fBufferSize )
1846 stack = (AliStack*)fStackBuffer->Remove(fStackBuffer->Last());
1850 stack = new AliStack(fNpart);
1853 fStackBuffer->AddFirst(stack);
1857 /***********************************************************/
1859 Double_t AliGenHBTosl::GetQInvCorrTheorValue(Double_t qinv) const
1861 //Function (deprecated)
1862 static const Double_t kFactorsqrd = 0.197*0.197;//squared conversion factor SI<->eV
1864 return 1.0 + 0.5*TMath::Exp(-qinv*qinv*fQRadius*fQRadius/kFactorsqrd);
1866 /***********************************************************/
1868 Double_t AliGenHBTosl::GetQOutQSideQLongCorrTheorValue(Double_t& out, Double_t& side, Double_t& lon) const
1870 //Theoretical function. Wa want to get correlation of the shape of this function
1871 static const Double_t kFactorsqrd = 0.197*0.197;//squared conversion factor SI<->eV
1872 return 1.0 + 0.7*TMath::Exp(-fQRadius*fQRadius*(out*out+side*side+lon*lon)/kFactorsqrd);
1874 /***********************************************************/
1876 Bool_t AliGenHBTosl::CheckParticle(TParticle* p, TParticle* aupair ,AliStack* stack)
1878 //Checks if a given particle is falling into signal region with any other particle
1879 //already existing on stack
1882 if (fSignalRegion <=0) return kFALSE;
1884 for (Int_t i = 0; i < stack->GetNtrack(); i++)
1886 TParticle* part = stack->Particle(i);
1887 if (part == aupair) continue;
1888 Double_t qout = 10e5;
1889 Double_t qside= 10e5;
1890 Double_t qlong= 10e5;
1891 GetQOutQSideQLong(p,part,qout,qside,qlong);
1893 if (TMath::Abs(qout) < fSignalRegion)
1894 if (TMath::Abs(qside) < fSignalRegion)
1895 if (TMath::Abs(qlong) < fSignalRegion)
1900 /***********************************************************/
1902 void AliGenHBTosl::SwapGeneratingHistograms()
1904 //Checks if it is time to swap signal and background histograms
1905 //if yes it swaps them
1906 Int_t threshold = fMinFill;
1907 for (Int_t k = 1; k<=fQNBins; k++)
1909 for (Int_t j = 1; j<=fQNBins; j++)
1911 for (Int_t i = 1; i<=fQNBins; i++)
1913 if ( fQSecondBackground->GetBinContent(i,j,k) < threshold) return;
1920 Info("SwapGeneratingHistograms","*******************************************");
1921 Info("SwapGeneratingHistograms","*******************************************");
1922 Info("SwapGeneratingHistograms","*******************************************");
1923 Info("SwapGeneratingHistograms","**** SWAPPING HISTOGRAMS ****");
1924 Info("SwapGeneratingHistograms","*******************************************");
1925 Info("SwapGeneratingHistograms","*******************************************");
1926 Info("SwapGeneratingHistograms","*******************************************");
1930 fQSignal = fQSecondSignal;
1932 fQSecondSignal->Reset();
1933 fQSecondSignal->SetDirectory(0x0);
1936 fQBackground = fQSecondBackground;
1937 fQSecondBackground = h;
1938 fQSecondBackground->Reset();
1939 fQSecondBackground->SetDirectory(0x0);
1945 AliGenHBTosl& AliGenHBTosl::operator=(const AliGenHBTosl& rhs)
1947 // Assignment operator
1952 void AliGenHBTosl::Copy(TObject&) const
1957 Fatal("Copy","Not implemented!\n");