]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - EVGEN/AliGenHBTosl.cxx
Fixing coverity bugs
[u/mrichter/AliRoot.git] / EVGEN / AliGenHBTosl.cxx
... / ...
CommitLineData
1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16/* $Id$ */
17
18#include "AliGenHBTosl.h"
19#include "AliLog.h"
20
21//__________________________________________________________
22/////////////////////////////////////////////////////////////
23// //
24// class AliGenHBTosl //
25// //
26// Genarator simulating particle correlations //
27// //
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. //
35// //
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 //
53// fMinFill) //
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. //
67// //
68////////////////////////////////////////////////////////////
69
70#include <TCanvas.h>
71
72
73#include <TH3D.h>
74#include <TList.h>
75#include <TPDGCode.h>
76#include <TParticle.h>
77#include <AliStack.h>
78#include <TMath.h>
79#include <TVector3.h>
80#include <TStopwatch.h>
81#include <TFile.h>
82
83#include "AliGenCocktailAfterBurner.h"
84#include "AliGeVSimParticle.h"
85#include "AliGenGeVSim.h"
86#include "AliGenHIJINGpara.h"
87
88
89/***********************************************************/
90using std::cout;
91using std::endl;
92using std::ofstream;
93using std::ios;
94ClassImp(AliGenHBTosl)
95
96AliGenHBTosl::AliGenHBTosl():
97 AliGenerator(),
98 fQCoarseBackground(0x0),
99 fQCoarseSignal(0x0),
100 fQSignal(0x0),
101 fQBackground(0x0),
102 fQSecondSignal(0x0),
103 fQSecondBackground(0x0),
104 fQRange(0.06),
105 fQNBins(60),
106 fGenerator(0x0),
107 fStackBuffer(0),
108 fBufferSize(5),
109 fNBinsToScale(Int_t(fQNBins*0.1)),
110 fDebug(0),
111 fSignalShapeCreated(0),
112 fMaxIterations(1000),
113 fMaxChiSquereChange(0.01),
114 fMaxChiSquerePerNDF(1.5),
115 fQRadius(8.0),
116 fPID(kPiPlus),
117 fSamplePhiMin(-0.01),
118 fSamplePhiMax(TMath::TwoPi()+0.01),
119 fSignalRegion(0.0),
120 fMinFill(1000),
121 fSwapped(0),
122 fLogFile(0x0)
123{
124//default constructor
125}
126/***********************************************************/
127
128AliGenHBTosl::AliGenHBTosl(Int_t n, Int_t pid):
129 AliGenerator(n),
130 fQCoarseBackground(0x0),
131 fQCoarseSignal(0x0),
132 fQSignal(0x0),
133 fQBackground(0x0),
134 fQSecondSignal(0x0),
135 fQSecondBackground(0x0),
136 fQRange(0.06),
137 fQNBins(60),
138 fGenerator(0x0),
139 fStackBuffer(0),
140 fBufferSize(5),
141 fNBinsToScale(Int_t(fQNBins*0.1)),
142 fDebug(0),
143 fSignalShapeCreated(kFALSE),
144 fMaxIterations(1000),
145 fMaxChiSquereChange(0.01),
146 fMaxChiSquerePerNDF(1.5),
147 fQRadius(8.0),
148 fPID(pid),
149 fSamplePhiMin(-0.01),
150 fSamplePhiMax(TMath::TwoPi()+0.01),
151 fSignalRegion(0.0),
152 fMinFill(1000),
153 fSwapped(0),
154 fLogFile(0x0)
155{
156//default constructor
157}
158
159AliGenHBTosl::AliGenHBTosl(const AliGenHBTosl & hbt):
160 AliGenerator(-1),
161 fQCoarseBackground(0x0),
162 fQCoarseSignal(0x0),
163 fQSignal(0x0),
164 fQBackground(0x0),
165 fQSecondSignal(0x0),
166 fQSecondBackground(0x0),
167 fQRange(0.06),
168 fQNBins(60),
169 fGenerator(0x0),
170 fStackBuffer(0),
171 fBufferSize(5),
172 fNBinsToScale(Int_t(fQNBins*0.1)),
173 fDebug(0),
174 fSignalShapeCreated(kFALSE),
175 fMaxIterations(1000),
176 fMaxChiSquereChange(0.01),
177 fMaxChiSquerePerNDF(1.5),
178 fQRadius(8.0),
179 fPID(kPiPlus),
180 fSamplePhiMin(-0.01),
181 fSamplePhiMax(TMath::TwoPi()+0.01),
182 fSignalRegion(0.0),
183 fMinFill(1000),
184 fSwapped(0),
185 fLogFile(0x0)
186{
187// Copy constructor
188 hbt.Copy(*this);
189}
190/***********************************************************/
191
192AliGenHBTosl::~AliGenHBTosl()
193{
194//destructor
195 delete fQCoarseSignal;
196 delete fQCoarseBackground;
197 delete fQSignal;
198 delete fQBackground;
199 delete fGenerator;
200 delete fQSecondSignal;
201 delete fQSecondBackground;
202 delete fLogFile;
203}
204/***********************************************************/
205
206void AliGenHBTosl::Init()
207{
208 //Initializes generator
209 if (fGenerator == 0x0)
210 {
211
212 AliGenHIJINGpara* bkggen = new AliGenHIJINGpara(fNpart*4);
213 fGenerator = bkggen;
214
215/*
216 AliGenGeVSim * gevsim = new AliGenGeVSim(0.0);
217 AliGeVSimParticle* kplus = new AliGeVSimParticle(fPID,1,fNpart, 0.17, 0.9);
218 gevsim->AddParticleType(kplus);
219
220 fGenerator = gevsim;
221*/
222
223/*
224
225 AliMevSimConfig *c = new AliMevSimConfig(1);
226 c->SetRectPlane(1); // reaction plane control, model 4
227 c->SetGrid(80,80);
228
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);
237 fGenerator = mevsim;
238*/
239
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);
246 fGenerator->Init();
247
248 }
249
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();
254
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);
257
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);
260
261 fQSignal->Sumw2();
262 fQBackground->Sumw2();
263 fQSecondSignal->Sumw2();
264 fQSecondBackground->Sumw2();
265
266 fLogFile = new ofstream("BadEvent",ios::out);
267
268}
269/***********************************************************/
270
271void AliGenHBTosl::Generate()
272{
273 //the main method
274
275 ofstream& logfile = *fLogFile;
276 logfile<<"Generate"<<"Attempts to generate "<<fNpart<<" particles.";
277
278
279 if (fStackBuffer == 0x0) fStackBuffer = new TList();
280 //Here is initialization level
281 if (fSignalShapeCreated == kFALSE)
282 {
283 TH3D *hs = 0x0, *hb = 0x0;
284 TFile* file;
285
286 file = TFile::Open("QTSignal.root");
287 if (file)
288 {
289 hs = (TH3D*)file->Get("fQSignal1");
290 if (hs) hs->SetDirectory(0x0);
291 }
292 delete file;
293
294 file = TFile::Open("QTBackground.root");
295 if (file)
296 {
297 hb = (TH3D*)file->Get("fQBackground1");
298 if (hb) hb->SetDirectory(0x0);
299 }
300 delete file;
301
302 if (hs && hb)
303 {
304 Info("Generate","**********************************");
305 Info("Generate","Found starting histograms in files");
306 Info("Generate","**********************************");
307 delete fQSignal;
308 delete fQBackground;
309 fQSignal = hs;
310 fQBackground = hb;
311 }
312 else
313 {
314 TH3D *cs = 0x0, *cb = 0x0;
315 file = TFile::Open("QTCoarseBackground.root");
316 if (file)
317 {
318 cb = (TH3D*)file->Get("fQCoarseBackground");
319 if (cb) cb->SetDirectory(0x0);
320 }
321 delete file;
322
323 file = TFile::Open("QTCoarseSignal.root");
324 if (file)
325 {
326 cs = (TH3D*)file->Get("fQCoarseSignal");
327 if (cs) cs->SetDirectory(0x0);
328 }
329 delete file;
330
331 if (cs && cb)
332 {
333
334 Info("Generate","Got Coarse signal and bkg from files");
335 delete fQCoarseBackground;
336 delete fQCoarseSignal;
337 fQCoarseSignal = cs;
338 fQCoarseBackground = cb;
339 }
340 else
341 {
342 if (cb)
343 {
344 Info("Generate","Got Coarse bkg from file");
345 delete fQCoarseBackground;
346 fQCoarseBackground = cb;
347 }
348 else
349 {
350 fQCoarseBackground = new TH3D("fQCoarseBackground","",fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange, fQNBins,-fQRange,fQRange);
351 fQCoarseBackground->Sumw2();
352
353 FillCoarse(); //create coarse background - just to know the spectrum
354 }
355
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
359 }
360
361 StartSignal(); //Initilizes the stack that is used for generation
362 }
363 fSignalShapeCreated = kTRUE;
364 }
365
366 AliStack* stack = RotateStack();
367
368 AliStack* genstack = fGenerator->GetStack();
369 if (genstack == 0x0)
370 {
371 genstack = new AliStack(fNpart);
372 fGenerator->SetStack(genstack);
373 }
374 else
375 {
376 genstack->Reset();
377 }
378
379 fGenerator->Generate();
380 Int_t ntr = 0;
381 if ( genstack->GetNtrack() < fNpart/2)
382 {
383 Warning("Generate","************************************************************");
384 Warning("Generate","Generator generated (%d) less particles then expected (%d).",
385 stack->GetNtrack(),fNpart/2);
386 Warning("Generate","************************************************************");
387 }
388
389 TH3D* work = new TH3D("work","work",fQNBins,-fQRange,fQRange,fQNBins,-fQRange,fQRange,fQNBins,-fQRange,fQRange);
390 work->SetDirectory(0x0);
391 work->Sumw2();
392
393 Double_t*** chiarray = new Double_t** [fQNBins+1];
394 Double_t*** sigarray = new Double_t** [fQNBins+1];
395
396 for (Int_t i = 1; i<=fQNBins; i++)
397 {
398 chiarray[i] = new Double_t* [fQNBins+1];
399 sigarray[i] = new Double_t* [fQNBins+1];
400
401 for (Int_t k = 1; k<=fQNBins; k++)
402 {
403 chiarray[i][k] = new Double_t [fQNBins+1];
404 sigarray[i][k] = new Double_t [fQNBins+1];
405 }
406 }
407
408
409 Double_t scale = Scale(fQSignal,fQBackground);
410 work->Divide(fQSignal,fQBackground,scale);
411
412 Double_t binwdh = work->GetBinWidth(1)/2.;
413
414 for (Int_t k = 1; k<=fQNBins; k++)
415 {
416 Double_t z = work->GetZaxis()->GetBinCenter(k);
417 for (Int_t j = 1; j<=fQNBins; j++)
418 {
419 Double_t y = work->GetYaxis()->GetBinCenter(j);
420 for (Int_t i = 1; i<=fQNBins; i++)
421 {
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
427 }
428 }
429 }
430
431 char msg[1000];
432 logfile<<endl;
433 snprintf(msg,1000, "\n");
434 Int_t middlebin = fQNBins/2;
435
436 for (Int_t k = middlebin-5; k < middlebin+5; k++)
437 {
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));
442 logfile<<msg;
443 }
444 logfile<<endl;
445
446 for (Int_t k = middlebin-5; k < middlebin+5; k++)
447 {
448 snprintf(msg,1000, "% 6.5f ",work->GetBinContent(30,30,k));
449 logfile<<msg;
450 }
451 logfile<<endl;
452
453 for (Int_t k = middlebin-5; k < middlebin+5; k++)
454 {
455 snprintf(msg, 1000, "% 6.5f ",chiarray[30][30][k]);
456 logfile<<msg;
457 }
458 logfile<<endl;
459
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;
462
463 Bool_t shortloop = kTRUE;
464 Int_t sc = 0;//security check against infinite loop
465
466 while ( (ntr+1) < fNpart)
467 {
468 Int_t xmax = 1;
469 Int_t ymax = 1;
470 Int_t zmax = 1;
471 Double_t qout;
472 Double_t qside;
473 Double_t qlong;
474
475
476 Int_t loopmin;
477 Int_t loopmax;
478
479 if (shortloop)
480 {
481 shortloop = kFALSE;
482 loopmax = fQNBins;
483 loopmin = 1;
484 }
485 else
486 {
487 shortloop = kTRUE;
488 loopmax = fQNBins/2+fQNBins/4;
489 loopmin = fQNBins/2-fQNBins/4;
490 }
491
492
493 for (Int_t k = loopmin; k <=loopmax; k++ )
494 {
495 qlong = work->GetZaxis()->GetBinCenter(k);
496 for (Int_t j = loopmin; j<=loopmax; j++)
497 {
498 qside = work->GetYaxis()->GetBinCenter(j);
499 for (Int_t i = loopmin; i<=loopmax; i++)
500 {
501 qout = work->GetXaxis()->GetBinCenter(i);
502 if (chiarray[xmax][ymax][zmax] < chiarray[i][j][k])
503 {
504 xmax = i;
505 ymax = j;
506 zmax = k;
507 }
508
509// Double_t qdist = TMath::Sqrt(qout*qout + qside*qside + qlong*qlong);
510
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
515// ymax = j;
516// zmax = k;
517// break;
518// }
519 }
520 }
521 }
522 Double_t qlongc = work->GetZaxis()->GetBinCenter(zmax);
523 Double_t qsidec = work->GetYaxis()->GetBinCenter(ymax);
524 Double_t qoutc = work->GetXaxis()->GetBinCenter(xmax);
525
526
527 snprintf(msg,1000, "Generate Fill bin chi2(%d,%d,%d)=%f",xmax,ymax,zmax,chiarray[xmax][ymax][zmax]);
528 logfile<<msg;
529
530 qout = gRandom->Uniform(qoutc -binwdh, qoutc +binwdh);
531 qside = gRandom->Uniform(qsidec-binwdh, qsidec+binwdh);
532 qlong = gRandom->Uniform(qlongc-binwdh, qlongc+binwdh);
533
534 TParticle* first = 0;
535 Int_t jj = 0;
536
537 while (jj < genstack->GetNtrack())
538 {
539 TParticle* tmpp = genstack->Particle(jj++);
540 if (tmpp->GetPdgCode() == fPID)
541 {
542 if (CheckParticle(tmpp,0x0,stack) == kFALSE)
543 {
544 first = tmpp;
545 break;
546 }
547 }
548 }
549
550 if (first == 0x0)
551 {
552 if ( fDebug > 2 ) Info("StartSignal","No more particles of that type");
553 break;
554 }
555
556 //Here put the check if this particle do not fall into signal region with other partticle
557
558 Int_t retval = GetThreeD(first,second,qout,qside,qlong);
559 if (retval)
560 {
561 //Info("StartSignal","Can not find momenta for this OSL and particle");
562 continue;
563 }
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) )
569 {
570 sc++;
571 continue;
572 }
573 sc = 0;
574
575 //Put on output stack
576 SetTrack(first,ntr);
577 SetTrack(second,ntr);
578
579 //Put on internal stack
580 Int_t etmp;
581 SetTrack(first,etmp,stack);
582 SetTrack(second,etmp,stack);
583
584 Double_t y = GetQOutQSideQLongCorrTheorValue(qoutc,qsidec,qlongc);
585
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]);
589
590 }
591
592 Mix(fStackBuffer,fQBackground,fQSecondSignal); //upgrate background
593 Mix(stack,fQSignal,fQSecondBackground); //upgrate signal
594
595 delete work;
596
597 for (Int_t i = 1; i<=fQNBins; i++)
598 {
599 for (Int_t k = 1; k<=fQNBins; k++)
600 {
601 delete [] chiarray[i][k];
602 delete [] sigarray[i][k];
603 }
604 delete [] chiarray[i];
605 delete [] sigarray[i];
606 }
607 delete [] chiarray;
608 delete [] sigarray;
609}
610/***********************************************************/
611
612void AliGenHBTosl::GetOneD(TParticle* first, TParticle* second,Double_t qinv)
613{
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
617
618
619 Double_t m = first->GetMass();
620 Double_t msqrd = m*m;
621 Double_t fourmassSquered = 4.*msqrd;
622
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);
626
627 Double_t r = gRandom->Uniform(qinv);
628 Double_t phi = gRandom->Uniform(TMath::TwoPi());
629
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 );
633 if (temp < 0.0)
634 {
635 Error("GetOneD","temp is less then 0: %f",temp);
636 return;
637 }
638 temp = temp*(msqrd+firstPx*firstPx);
639
640 px = (px - TMath::Sqrt(temp))/(2.*msqrd);
641
642 Double_t py = r*TMath::Sin(phi);
643 Double_t pz = r*TMath::Cos(phi);
644
645 TVector3 firstpvector(first->Px(),first->Py(),first->Pz());
646 TVector3 vector(px,py,pz);
647 Rotate(firstpvector,vector);
648
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);
654
655 AliDebug(1,Form("Randomized qinv = %f, obtained = %f",qinv,GetQInv(first,second)));
656
657}
658/***********************************************************/
659
660Int_t AliGenHBTosl::GetThreeD(TParticle* first,TParticle* second, Double_t qout, Double_t qside, Double_t qlong)
661{
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();
665 Double_t m2 = m*m;
666
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;
669
670
671 Double_t qout2 = qout*qout;
672 Double_t qside2 = qside*qside;
673 Double_t qlong2 = qlong*qlong;
674
675
676 Double_t util1 = 4.*px2 - qside2;//4*P1x^2 - Y^2
677 if (util1 < 0)
678 {
679 Info("GetThreeD","4.*px2* - qside2 is negative px: %f, qside: %f",px,qside);
680 return 1;
681 }
682 Double_t util2 = TMath::Sqrt(px2*qout2*util1);
683
684
685 Double_t p2x,p2y,p2z;
686
687// if ( (qside >= 0) && (qout >= 0) && (qlong >= 0))
688 if (qout >= 0)
689 {
690 //p2x
691 Double_t tmp = px*(2.*px2 - qside2);
692 tmp -= util2;
693 p2x = tmp/(2.*px2);
694
695 //p2y
696 tmp = qout - TMath::Sqrt(util1);
697 p2y = - (tmp*qside)/(2.*px);
698
699 //p2z
700 tmp = 4.*m2 + 2.*qout2+qlong2;
701 tmp *= px;
702 tmp -= 2.*util2;//!!!
703 tmp += 4.*px*px2;
704 tmp *= qlong2;
705
706 Double_t m2px2 = m2+px2;
707 Double_t tmp2 = m2px2*tmp;
708
709 tmp = 4.*(m2px2+qout2) + qlong2;
710 tmp *= px;
711 tmp -= 4.*util2;
712 tmp *= 4.*(m2px2) + qlong2;
713 tmp *= qlong2*qlong2;
714 tmp *= m2px2*m2px2;
715 tmp *= px;
716 if (tmp < 0)
717 {
718 Error("","Argument of sqrt is negative");
719 return 1;
720 }
721
722 tmp2 += TMath::Sqrt(tmp);
723
724 tmp = 8.0*px*m2px2*m2px2;
725 p2z = -TMath::Sqrt(tmp2/tmp);
726 if (qlong < 0) p2z = -p2z;
727 }
728 else
729 {
730 //p2x
731 Double_t tmp = px*(2.*px2 - qside2);
732 tmp += util2;
733 p2x = tmp/(2.*px2);
734
735 //p2y
736 tmp = qout - TMath::Sqrt(util1);
737 p2y = - (tmp*qside)/(2.*px);
738
739 //p2z
740 tmp = 4.*m2 + 2.*qout2+qlong2;
741 tmp *= px;
742 tmp += 2.*util2;//!!!
743 tmp += 4.*px*px2;
744 tmp *= qlong2;
745
746 Double_t m2px2 = m2+px2;
747 Double_t tmp2 = m2px2*tmp;
748
749 tmp = 4.*(m2px2+qout2) + qlong2;
750 tmp *= px;
751 tmp += 4.*util2;
752 tmp *= 4.*(m2px2) + qlong2;
753 tmp *= qlong2*qlong2;
754 tmp *= m2px2*m2px2;
755 tmp *= px;
756 if (tmp < 0)
757 {
758 Error("","Argument of sqrt is negative");
759 return 1;
760 }
761
762 tmp2 += TMath::Sqrt(tmp);
763
764 tmp = 8.0*px*m2px2*m2px2;
765 p2z = -TMath::Sqrt(tmp2/tmp);
766 if (qlong < 0) p2z = -p2z;
767 }
768
769// if ( (qside >= 0) && (qout >= 0) && (qlong >= 0)) p2z = -p2z;
770
771 TVector3 firstpvector(first->Px(),first->Py(),first->Pz());
772 TVector3 vector(p2x,p2y,p2z);
773 Rotate(firstpvector,vector);
774
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);
777
778////////////
779 if ( AliDebugLevel() > 3 )
780 {
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);
783
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);
786
787 Double_t qo, qs, ql;
788 GetQOutQSideQLong(f,s,qo, qs, ql);
789
790 Info("GetThreeD","TEST");
791 f->Print();
792 s->Print();
793 Info("GetThreeD","Required %f %f %f",qout,qside,qlong);
794 Info("GetThreeD","Got %f %f %f",qo,qs,ql);
795 if ( qout == qo)
796 if (qside == qs)
797 if (qlong == ql)
798 Info("GetThreeD","!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
799 }
800/////////////
801 return 0;
802}
803/***********************************************************/
804
805void AliGenHBTosl::StartSignal()
806{
807//Starts the signal histograms
808 ofstream& logfile = *fLogFile;
809 logfile<<"\n\n\n\n";
810 logfile<<"************************************************"<<endl;
811 logfile<<"************************************************"<<endl;
812 logfile<<" StartSignal "<<endl;
813 logfile<<"************************************************"<<endl;
814 logfile<<"************************************************"<<endl;
815
816 AliStack* stack;
817
818 fSwapped = kFALSE;
819
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;
822
823 TIter next(fStackBuffer);
824 while(( stack=(AliStack*)next() ))
825 {
826 stack->Reset();
827 }
828
829 AliStack* genstack = fGenerator->GetStack();
830 if (genstack == 0x0)
831 {
832 genstack = new AliStack(fNpart);
833 fGenerator->SetStack(genstack);
834 }
835 else
836 {
837 genstack->Reset();
838 }
839
840 StartSignalPass1();
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;
846
847
848 const Double_t kNDF = fQNBins*fQNBins*fQNBins;
849
850 TH3D* work = new TH3D("work","work",fQNBins,-fQRange,fQRange,fQNBins,-fQRange,fQRange,fQNBins,-fQRange,fQRange);
851 work->Sumw2();
852 work->SetDirectory(0x0);
853
854
855 Double_t binwdh = work->GetBinWidth(1)/2.;
856
857 Double_t*** chiarray = new Double_t** [fQNBins+1];
858 Double_t*** sigarray = new Double_t** [fQNBins+1];
859
860 for (Int_t i = 1; i<=fQNBins; i++)
861 {
862 chiarray[i] = new Double_t* [fQNBins+1];
863 sigarray[i] = new Double_t* [fQNBins+1];
864
865 for (Int_t k = 1; k<=fQNBins; k++)
866 {
867 chiarray[i][k] = new Double_t [fQNBins+1];
868 sigarray[i][k] = new Double_t [fQNBins+1];
869 }
870 }
871
872
873 Float_t chisqrchange = fMaxChiSquereChange + 1.;
874 Float_t chisqrPerDF = fMaxChiSquerePerNDF;
875 Float_t chisqrold = 0.0;
876
877 Int_t counter = 1;
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)
880
881 Bool_t flag = kTRUE;
882 Bool_t shortloop = kTRUE;
883 TCanvas* c1 = new TCanvas();
884
885
886 printf("\n");
887 Info("StartSignal","\n\n\n\nSecond Pass\n\n\n\n");
888
889 while ( ( (chisqrPerDF > fMaxChiSquereChange) || flag) && (niterations++ < fMaxIterations) )
890 {
891
892 logfile<<"StartSignal\n";
893 logfile<<" Row 1 Theory, 2 current value, 3 Chi2 \n";
894
895 Double_t chisqrnew = 0.0;
896 flag = kFALSE;
897
898 Double_t scale = Scale(fQSignal,fQBackground);
899 work->Divide(fQSignal,fQBackground,scale);
900
901 if ( (counter%100) == 0)
902 {
903 c1->cd();
904 char buff[50];
905 snprintf(buff,50, "QTWorkPass2.%3d.root",counter);
906 TFile* file = TFile::Open(buff,"update");
907 work->Write();
908 work->SetDirectory(0x0);
909 file->Close();
910 delete file;
911
912 snprintf(buff,50, "QTBackgroundPass2.%3d.root",counter);
913 file = TFile::Open(buff,"update");
914 fQBackground->Write();
915 fQBackground->SetDirectory(0x0);
916 file->Close();
917 delete file;
918
919 snprintf(buff,50, "QTSignalPass2.%3d.root",counter);
920 file = TFile::Open(buff,"update");
921 fQSignal->Write();
922 fQSignal->SetDirectory(0x0);
923 file->Close();
924 delete file;
925 }
926
927 counter++;
928 Int_t novertresh = 0;
929 for (Int_t k = 1; k<=fQNBins; k++)
930 {
931 Double_t z = work->GetZaxis()->GetBinCenter(k);
932 for (Int_t j = 1; j<=fQNBins; j++)
933 {
934 Double_t y = work->GetYaxis()->GetBinCenter(j);
935 for (Int_t i = 1; i<=fQNBins; i++)
936 {
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
944
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)
949 {
950 flag = kTRUE;
951 novertresh++;
952 }
953 }
954 }
955 }
956
957
958 char msg[1000];
959
960 printf("\n");
961
962 for (Int_t k = 25; k < 36; k++)
963 {
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));
968 logfile<<msg;
969 }
970 logfile<<endl;
971
972 for (Int_t k = 25; k < 36; k++)
973 {
974 snprintf(msg, 1000, "%6.5f ",work->GetBinContent(30,30,k));
975 logfile<<msg;
976 }
977 logfile<<endl;
978
979 for (Int_t k = 25; k < 36; k++)
980 {
981 snprintf(msg,1000, "% 6.5f ",chiarray[30][30][k]);
982 logfile<<msg;
983 }
984 logfile<<endl;
985
986 chisqrchange = TMath::Abs(chisqrnew - chisqrold)/chisqrnew;
987 chisqrold = chisqrnew;
988
989 chisqrPerDF = chisqrnew/kNDF;
990
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);
994
995
996 stack = RotateStack();
997 genstack->Reset();
998 fGenerator->Generate();
999 Int_t ninputparticle = 0, ntr = 0;
1000 if ( genstack->GetNtrack() < fNpart/2)
1001 {
1002 Warning("StartSignal","**********************************");
1003 Warning("StartSignal","Generator generated (%d) less particles then expected (%d).",
1004 genstack->GetNtrack(),fNpart/2);
1005 Warning("StartSignal","**********************************");
1006 }
1007
1008 Int_t sc = 0; //security check against infinite loop
1009 while ( (ntr+1) < fNpart)//ntr is number of track generated up to now
1010 {
1011 Int_t xmax = 1;
1012 Int_t ymax = 1;
1013 Int_t zmax = 1;
1014 Double_t qout;
1015 Double_t qside;
1016 Double_t qlong;
1017
1018 Int_t i,j,k;
1019
1020 Int_t* cx = 0x0;
1021 Int_t* cy = 0x0;
1022 Int_t* cz = 0x0;
1023
1024 switch (rotaxisorder)
1025 {
1026 case 1:
1027 cx = &i;
1028 cy = &j;
1029 cz = &k;
1030 break;
1031 case 2:
1032 cx = &j;
1033 cy = &k;
1034 cz = &i;
1035 break;
1036 case 3:
1037 cx = &k;
1038 cy = &i;
1039 cz = &j;
1040 break;
1041 }
1042 rotaxisorder++;
1043 if (rotaxisorder > 3) rotaxisorder = 1;
1044 Int_t nrange;
1045
1046 if (shortloop)
1047 {
1048 shortloop = kFALSE;
1049 nrange = fQNBins;
1050 }
1051 else
1052 {
1053 shortloop = kTRUE;
1054 nrange = fQNBins/4;
1055 }
1056
1057// Bool_t force = kFALSE;
1058 for ( k = 1; k <=nrange;k++ )
1059 {
1060 for ( j = 1; j<=nrange; j++)
1061 {
1062 for ( i = 1; i<=nrange; i++)
1063 {
1064 if ( (chiarray[*cx][*cy][*cz]) > (chiarray[xmax][ymax][zmax]) )
1065 {
1066 xmax = *cx;
1067 ymax = *cy;
1068 zmax = *cz;
1069 }
1070
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);
1078
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));
1082// force = kTRUE;
1083// break;
1084// }
1085
1086 }
1087// if (force) break;
1088 }
1089// if (force) break;
1090 }
1091
1092
1093 qout = work->GetXaxis()->GetBinCenter(xmax);
1094 qside = work->GetYaxis()->GetBinCenter(ymax);
1095 qlong = work->GetZaxis()->GetBinCenter(zmax);
1096
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));
1102
1103 qout = gRandom->Uniform(qout-binwdh,qout+binwdh);
1104 qside = gRandom->Uniform(qside-binwdh,qside+binwdh);
1105 qlong = gRandom->Uniform(qlong-binwdh,qlong+binwdh);
1106
1107 TParticle* first = 0;
1108 while (ninputparticle < genstack->GetNtrack())
1109 {
1110 TParticle* tmpp = genstack->Particle(ninputparticle++);
1111 if (tmpp->GetPdgCode() == fPID)
1112 {
1113 if (CheckParticle(tmpp,0x0,stack) == kFALSE)
1114 {
1115 first = tmpp;
1116 break;
1117 }
1118 }
1119 }
1120
1121 if (first == 0x0)
1122 {
1123 if ( fDebug > 2 ) Info("StartSignal","No more particles of that type");
1124 break;
1125 }
1126
1127 Int_t retval = GetThreeD(first,second,qout,qside,qlong);
1128 if (retval)
1129 {
1130 Info("StartSignal","Can not find momenta for this OSL and particle OSL = %f %f %f",qout,qside,qlong);
1131 first->Print();
1132 second->Print();
1133
1134 continue;
1135 }
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) )
1141 {
1142 sc++;
1143 continue;
1144 }
1145 sc = 0;
1146
1147 //Put on output stack
1148 SetTrack(first,ntr,stack);
1149 SetTrack(second,ntr,stack);
1150
1151 Double_t y = GetQOutQSideQLongCorrTheorValue(qout,qside,qlong);
1152
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]);
1156
1157 }
1158 Info("StartSignal","Mixing background...");
1159 Mix(fStackBuffer,fQBackground,fQSecondBackground); //upgrate background
1160 Info("StartSignal","Mixing signal...");
1161 Mix(stack,fQSignal,fQSecondSignal); //upgrate background
1162
1163
1164// if ( (chisqrPerDF < 2.0) && (fSwapped == kFALSE) )
1165// {
1166// SwapGeneratingHistograms();
1167// }
1168
1169 }
1170 TFile* filef = TFile::Open("QTBackground.root","recreate");
1171 fQBackground->Write();
1172 fQBackground->SetDirectory(0x0);
1173 filef->Close();
1174 delete filef;
1175
1176 filef = TFile::Open("QTSignal.root","recreate");
1177 fQSignal->Write();
1178 fQSignal->SetDirectory(0x0);
1179 filef->Close();
1180 delete filef;
1181
1182
1183 delete c1;
1184 delete work;
1185
1186 for (Int_t i = 1; i<=fQNBins; i++)
1187 {
1188 for (Int_t k = 1; k<=fQNBins; k++)
1189 {
1190 delete [] chiarray[i][k];
1191 delete [] sigarray[i][k];
1192 }
1193 delete [] chiarray[i];
1194 delete [] sigarray[i];
1195 }
1196 delete [] chiarray;
1197 delete [] sigarray;
1198
1199}
1200/***********************************************************/
1201
1202void AliGenHBTosl::StartSignalPass1()
1203{
1204 //This method makes first part of the initialization of working histograms
1205 //It randomizes qout, qside and qlong from the coarse signal histogram
1206
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;
1210 Double_t qout;
1211 Double_t qside;
1212 Double_t qlong;
1213
1214 Info("StartSignalPass1","\n\nFirst Pass\n\n");
1215
1216 while (flag)
1217 {
1218 Info("StartSignalPass1","NextEvent");
1219 AliStack* stack = RotateStack();
1220 AliStack* genstack = fGenerator->GetStack();
1221 genstack->Reset();
1222 fGenerator->Generate();
1223 Int_t j = 0, ntr = 0;
1224 if ( genstack->GetNtrack() < fNpart/2)
1225 {
1226 Warning("StartSignalPass1","**********************************");
1227 Warning("StartSignalPass1","Generator generated (%d) less particles then expected (%d).",
1228 genstack->GetNtrack(),fNpart/2);
1229 Warning("StartSignalPass1","**********************************");
1230 }
1231
1232 Int_t sc = 0;//security check against infinite loop
1233 while ((ntr+1)<fNpart)
1234 {
1235
1236// Info("StartSignal","Number of track on output stack: = %d", ntr);
1237// Info("StartSignal","Number of track on input stack: = %d\n", j);
1238
1239 TParticle* first = 0;
1240 while (j < genstack->GetNtrack())
1241 {
1242 TParticle* tmpp = genstack->Particle(j++);
1243 if (tmpp->GetPdgCode() == fPID)
1244 {
1245 if (CheckParticle(tmpp,0x0,stack) == kFALSE)
1246 {
1247 first = tmpp;
1248 break;
1249 }
1250 else
1251 {
1252 Info("StartSignalPass1","Particle did not pass the safety check 1");
1253 tmpp->Print();
1254 }
1255 }
1256 }
1257
1258 if (first == 0x0)
1259 {
1260 if ( fDebug > 2 ) Info("StartSignalPass1","No more particles of that type");
1261
1262 break;
1263 }
1264
1265 SetTrack(first,ntr,stack);
1266
1267 fQCoarseSignal->GetRandom3(qout,qside,qlong);
1268
1269 Int_t retval = GetThreeD(first,second,qout,qside,qlong);
1270 if (retval)
1271 {
1272 //Info("StartSignal","Can not find momenta for this OSL and particle");
1273 continue;
1274 }
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) )
1280 {
1281 sc++;
1282 Info("StartSignalPass1","Particle did not pass the safety check 2");
1283 second->Print();
1284 continue;
1285 }
1286
1287 sc = 0;
1288
1289 SetTrack(second,ntr,stack);
1290 }
1291
1292 Mix(stack,fQSignal,fQSecondSignal);
1293 Mix(fStackBuffer,fQBackground,fQSecondBackground);
1294
1295 flag = kFALSE;
1296
1297 for (Int_t k = 1; k<=fQNBins; k++)
1298 {
1299 for (j = 1; j<=fQNBins; j++)
1300 {
1301 for (Int_t i = 1; i<=fQNBins; i++)
1302 {
1303 if ( (fQBackground->GetBinContent(i,j,k) < fMinFill) )
1304 {
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
1310 }
1311 }
1312 if (flag == kTRUE) break;
1313 }
1314 if (flag == kTRUE) break;
1315 }
1316
1317 }//while (flag)
1318
1319
1320}
1321/***********************************************************/
1322
1323void AliGenHBTosl::FillCoarseSignal()
1324{
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++ )
1328 {
1329 Double_t z = fQCoarseBackground->GetZaxis()->GetBinCenter(k);
1330 for (Int_t j = 1; j <=fQNBins; j++)
1331 {
1332 Double_t y = fQCoarseBackground->GetYaxis()->GetBinCenter(j);
1333 for (Int_t i = 1; i <=fQNBins; i++)
1334 {
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));
1339 }
1340 }
1341 }
1342
1343 //if (AliDebugLevel())
1344 TestCoarseSignal();
1345
1346 Info("FillCoarseSignal","DONE");
1347}
1348/***********************************************************/
1349
1350void AliGenHBTosl::FillCoarse()
1351{
1352 //creates the statistical background histogram on the base of input from
1353 //fGenerator
1354 Info("FillCoarse","START");
1355
1356 AliStack* stack;
1357 Int_t niter = 0;
1358
1359 Bool_t cont;
1360 TH3D tmph("tmph","tmph",2,0,1,2,0,1,2,0,1);
1361 printf("\n");
1362
1363 do
1364 {
1365// if (niter > 20) break;
1366
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)
1372 <<"\n";
1373 fflush(0);
1374
1375 stack = RotateStack();
1376 fGenerator->SetStack(stack);
1377 fGenerator->Init();
1378 fGenerator->Generate();
1379
1380 Mix(fStackBuffer,fQCoarseBackground,&tmph);
1381
1382 cont = kFALSE;
1383
1384 Info("FillCoarse","fMinFill = %d",fMinFill);
1385 for (Int_t k = 1; k<=fQNBins; k++)
1386 {
1387 for (Int_t j = 1; j<=fQNBins; j++)
1388 {
1389 for (Int_t i = 1; i<=fQNBins; i++)
1390 {
1391 if ( fQCoarseBackground->GetBinContent(i,j,k) < fMinFill )
1392 {
1393 cont = kTRUE;
1394 Info("FillCoarse","bin (%d,%d,%d)=%f",i,j,k,fQCoarseBackground->GetBinContent(i,j,k));
1395 break;
1396 }
1397
1398 }
1399 if (cont) break;
1400 }
1401 if (cont) break;
1402 }
1403 }while(cont);
1404
1405 printf("\n");
1406 fGenerator->SetStack(0x0);
1407 Info("FillCoarse","DONE");
1408
1409}
1410/***********************************************************/
1411
1412void AliGenHBTosl::Mix(TList* eventbuffer,TH3D* denominator,TH3D* denominator2)
1413{
1414 //Fills denominators
1415 //Mixes events stored in the eventbuffer and fills the background histograms
1416 static TStopwatch stoper;
1417
1418 if (eventbuffer == 0x0)
1419 {
1420 Error("Mix","Buffer List is null.");
1421 return;
1422 }
1423
1424 if (denominator == 0x0)
1425 {
1426 Error("Mix","Denominator histogram is null.");
1427 return;
1428 }
1429
1430 if (denominator2 == 0x0)
1431 {
1432 Error("Mix","Denominator2 histogram is null.");
1433 return;
1434 }
1435
1436 Info("Mix","%s",denominator->GetName());
1437 stoper.Start();
1438
1439 TIter next(eventbuffer);
1440 AliStack* firstevent;
1441 AliStack* secondevent = 0x0;
1442
1443 while(( firstevent=(AliStack*)next() ))
1444 {
1445 if (secondevent == 0x0)
1446 {
1447 secondevent = firstevent;
1448 continue;
1449 }
1450// Info("Mix","Mixing %#x with %#x",firstevent,secondevent);
1451 for(Int_t j = 0; j < firstevent->GetNtrack(); j++ )
1452 {
1453 TParticle* firstpart = firstevent->Particle(j);
1454
1455 Float_t phi = firstpart->Phi();
1456 if ( (phi < fSamplePhiMin) || ( phi > fSamplePhiMax)) continue;
1457
1458// Info("Mix","Mixing %d phi %f min %f max %f",j,phi,fSamplePhiMin,fSamplePhiMax);
1459
1460 for(Int_t i = 0; i < secondevent->GetNtrack(); i++ )
1461 {
1462 TParticle* secondpart = secondevent->Particle(i);
1463 phi = secondpart->Phi();
1464 if ( (phi < fSamplePhiMin) || ( phi > fSamplePhiMax)) continue;
1465
1466 Double_t qout;
1467 Double_t qside;
1468 Double_t qlong;
1469 GetQOutQSideQLong(firstpart,secondpart,qout,qside,qlong);
1470 denominator->Fill(qout,qside,qlong);
1471 denominator2->Fill(qout,qside,qlong);
1472 }
1473 }
1474
1475 secondevent = firstevent;
1476 }
1477 stoper.Stop();
1478 stoper.Print();
1479
1480}
1481/***********************************************************/
1482
1483void AliGenHBTosl::Mix(AliStack* stack, TH3D* numerator, TH3D* numerator2)
1484{
1485//fils numerator with particles from stack
1486 static TStopwatch stoper;
1487 if (stack == 0x0)
1488 {
1489 Error("Mix","Stack is null.");
1490 return;
1491 }
1492
1493 if ( (numerator == 0x0) || (numerator2 == 0x0) )
1494 {
1495 Error("Mix","Numerator histogram is null.");
1496 return;
1497 }
1498
1499 Info("Mix","%s",numerator->GetName());
1500 stoper.Start();
1501
1502 for(Int_t j = 0; j < stack->GetNtrack(); j++ )
1503 {
1504 TParticle* firstpart = stack->Particle(j);
1505 Float_t phi = firstpart->Phi();
1506 if ( (phi < fSamplePhiMin) || ( phi > fSamplePhiMax)) continue;
1507
1508 for(Int_t i = j+1; i < stack->GetNtrack(); i++ )
1509 {
1510 TParticle* secondpart = stack->Particle(i);
1511 phi = secondpart->Phi();
1512 if ( (phi < fSamplePhiMin) || ( phi > fSamplePhiMax)) continue;
1513 Double_t qout;
1514 Double_t qside;
1515 Double_t qlong;
1516 GetQOutQSideQLong(firstpart,secondpart,qout,qside,qlong);
1517 numerator->Fill(qout,qside,qlong);
1518 numerator2->Fill(qout,qside,qlong);
1519 }
1520 }
1521 stoper.Stop();
1522 stoper.Print();
1523
1524}
1525/***********************************************************/
1526
1527Double_t AliGenHBTosl::GetQInv(TParticle* f, TParticle* s)
1528{
1529//calculates qinv
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();
1535
1536 Double_t qinvl = ediff*ediff - ( pxdiff*pxdiff + pydiff*pydiff + pzdiff*pzdiff );
1537 Double_t qinv = TMath::Sqrt(TMath::Abs(qinvl));
1538 return qinv;
1539}
1540/***********************************************************/
1541
1542void AliGenHBTosl::GetQOutQSideQLong(TParticle* f, TParticle* s,Double_t& out, Double_t& side, Double_t& lon)
1543{
1544 //returns qout,qside and qlong of the pair of particles
1545 out = side = lon = 10e5;
1546
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);
1556
1557 Double_t k2 = pxsum*pxdiff+pysum*pydiff;
1558
1559 if (kt == 0.0)
1560 {
1561 f->Print();
1562 s->Print();
1563 kt = 10e5;
1564 }
1565 else
1566 {
1567 out = 0.5*k2/kt;
1568 side = (f->Px()*s->Py()-s->Px()*f->Py())/kt;
1569 }
1570
1571 Double_t beta = pzsum/esum;
1572 Double_t gamma = 1.0/TMath::Sqrt((1.-beta)*(1.+beta));
1573
1574 lon = gamma * ( pzdiff - beta*ediff );
1575
1576// out = TMath::Abs(out);
1577// side = TMath::Abs(side);
1578// lon = TMath::Abs(lon);
1579}
1580
1581/***********************************************************/
1582
1583Double_t AliGenHBTosl::Scale(TH3D* num, TH3D* den)
1584{
1585 //Calculates the factor that should be used to scale
1586 //quatience of num and den to 1 at tail
1587
1588 AliDebug(1,"Entered");
1589 if(!num)
1590 {
1591 AliError("No numerator");
1592 return 0.0;
1593 }
1594 if(!den)
1595 {
1596 AliError("No denominator");
1597 return 0.0;
1598 }
1599
1600 if(fNBinsToScale < 1)
1601 {
1602 AliError("Number of bins for scaling is smaller than 1");
1603 return 0.0;
1604 }
1605 Int_t fNBinsToScaleX = fNBinsToScale;
1606 Int_t fNBinsToScaleY = fNBinsToScale;
1607 Int_t fNBinsToScaleZ = fNBinsToScale;
1608
1609 Int_t nbinsX = num->GetNbinsX();
1610 if (fNBinsToScaleX > nbinsX)
1611 {
1612 AliError("Number of X bins for scaling is bigger thnan number of bins in histograms");
1613 return 0.0;
1614 }
1615
1616 Int_t nbinsY = num->GetNbinsX();
1617 if (fNBinsToScaleY > nbinsY)
1618 {
1619 AliError("Number of Y bins for scaling is bigger thnan number of bins in histograms");
1620 return 0.0;
1621 }
1622
1623 Int_t nbinsZ = num->GetNbinsZ();
1624 if (fNBinsToScaleZ > nbinsZ)
1625 {
1626 AliError("Number of Z bins for scaling is bigger thnan number of bins in histograms");
1627 return 0.0;
1628 }
1629
1630 AliDebug(1,"No errors detected");
1631
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
1635
1636 Double_t densum = 0.0;
1637 Double_t numsum = 0.0;
1638
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++)
1642 {
1643 if ( num->GetBinContent(i,j,k) > 0.0 )
1644 {
1645
1646 densum += den->GetBinContent(i,j,k);
1647 numsum += num->GetBinContent(i,j,k);
1648 }
1649 }
1650
1651 AliDebug(1,Form("numsum=%f densum=%f fNBinsToScaleX=%d fNBinsToScaleY=%d fNBinsToScaleZ=%d",
1652 numsum,densum,fNBinsToScaleX,fNBinsToScaleY,fNBinsToScaleZ));
1653
1654 if (numsum == 0) return 0.0;
1655 Double_t ret = densum/numsum;
1656
1657 AliDebug(1,Form("returning %f",ret));
1658 return ret;
1659
1660}
1661/***********************************************************/
1662
1663void AliGenHBTosl::TestCoarseSignal()
1664{
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);
1667
1668// for (Int_t i = 0; i < fQCoarseBackground->GetEntries() ;i++)
1669// {
1670// Double_t x,y,z;
1671// fQCoarseSignal->GetRandom3(x,y,z);
1672// work->Fill(x,y,z);
1673// }
1674
1675 TCanvas* c1 = new TCanvas();
1676 c1->cd();
1677 work->Draw();
1678 c1->SaveAs("QTwork.root");
1679 TFile* file = TFile::Open("QTwork.root","update");
1680// work->Write();
1681 work->SetDirectory(0x0);
1682 file->Close();
1683
1684 fQCoarseSignal->Draw();
1685 c1->SaveAs("QTCoarseSignal.root");
1686 file = TFile::Open("QTCoarseSignal.root","update");
1687 fQCoarseSignal->Write();
1688 fQCoarseSignal->SetDirectory(0x0);
1689 file->Close();
1690
1691 fQCoarseBackground->Draw();
1692 c1->SaveAs("QTCoarseBackground.root");
1693 file = TFile::Open("QTCoarseBackground.root","update");
1694 fQCoarseBackground->Write();
1695 fQCoarseBackground->SetDirectory(0x0);
1696 file->Close();
1697
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
1702
1703
1704 c1->cd();
1705 result->Draw();
1706 c1->SaveAs("QTresult.root");
1707 file = TFile::Open("QTresult.root","update");
1708 result->Write();
1709 result->SetDirectory(0x0);
1710 file->Close();
1711
1712 delete work;
1713 delete c1;
1714}
1715/***********************************************************/
1716
1717void AliGenHBTosl::SetTrack(TParticle* p, Int_t& ntr)
1718{
1719//Shortcut to PushTrack(bla,bla,bla,bla.............)
1720 if (p->P() == 0.0)
1721 {
1722 Error("SetTrack(TParticle*,Int_t&)","Particle has zero momentum");
1723 return;
1724 }
1725
1726
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();
1736
1737 TVector3 pol;
1738 p->GetPolarisation(pol);
1739
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();
1745
1746 AliGenerator::PushTrack(fTrackIt, -1, pdg, px, py, pz, e, vx, vy, vz, tof,polx, poly, polz, mech, ntr, weight);
1747}
1748/***********************************************************/
1749
1750void AliGenHBTosl::SetTrack(TParticle* p, Int_t& ntr, AliStack* stack) const
1751{
1752//Shortcut to SetTrack(bla,bla,bla,bla.............)
1753 if (p->P() == 0.0)
1754 {
1755 Error("SetTrack(TParticle*,Int_t&,AliStack*)","Particle has zero momentum");
1756 return;
1757 }
1758
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();
1764
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);
1766}
1767/***********************************************************/
1768
1769void AliGenHBTosl::Rotate(TVector3& relvector, TVector3& vector)
1770{
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
1774
1775 static TVector3 first;
1776 if (AliDebugLevel()>=1)
1777 {
1778 first.SetXYZ(relvector.x(),relvector.y(),relvector.z());
1779 }
1780
1781 Double_t firstPx = TMath::Sqrt( relvector.x()*relvector.x() +
1782 relvector.y()*relvector.y() +
1783 relvector.z()*relvector.z() );
1784
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());
1789
1790 vector.RotateY(rotAngleY);
1791 vector.RotateZ(rotAngleZ);
1792
1793 if (AliDebugLevel()>5)
1794 {
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()));
1801 }
1802}
1803/***********************************************************/
1804
1805Double_t AliGenHBTosl::Rotate(Double_t x,Double_t y,Double_t z)
1806{
1807//Rotates vector to base where only x - coordinate is no-zero, and returns that
1808
1809 Double_t xylength = TMath::Hypot(x,y);
1810 Double_t sinphi = -y/xylength;
1811 Double_t cosphi = x/xylength;
1812
1813 Double_t xprime = cosphi*x - sinphi*y;
1814 Double_t yprime = sinphi*x + cosphi*y;
1815
1816 TVector3 v(x,y,z);
1817 Double_t a1 = -TMath::ATan2(v.Y(),v.X());
1818
1819 if (AliDebugLevel()>5)
1820 {
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)));
1824 }
1825
1826 Double_t xprimezlength = TMath::Hypot(xprime,z);
1827
1828 Double_t sintheta = z/xprimezlength;
1829 Double_t costheta = xprime/xprimezlength;
1830
1831
1832 Double_t xbis = sintheta*z + costheta*(cosphi*x - sinphi*y);
1833
1834 AliInfo(Form("Calculated rot %f, modulus %f",xbis,TMath::Sqrt(x*x+y*y+z*z)));
1835 return xbis;
1836}
1837/***********************************************************/
1838
1839AliStack* AliGenHBTosl::RotateStack()
1840{
1841//swaps to next stack last goes to first and is reseted
1842
1843 AliStack* stack;
1844 if ( fStackBuffer->GetSize() >= fBufferSize )
1845 {
1846 stack = (AliStack*)fStackBuffer->Remove(fStackBuffer->Last());
1847 }
1848 else
1849 {
1850 stack = new AliStack(fNpart);
1851 }
1852
1853 fStackBuffer->AddFirst(stack);
1854 stack->Reset();
1855 return stack;
1856}
1857/***********************************************************/
1858
1859Double_t AliGenHBTosl::GetQInvCorrTheorValue(Double_t qinv) const
1860{
1861//Function (deprecated)
1862 static const Double_t kFactorsqrd = 0.197*0.197;//squared conversion factor SI<->eV
1863
1864 return 1.0 + 0.5*TMath::Exp(-qinv*qinv*fQRadius*fQRadius/kFactorsqrd);
1865}
1866/***********************************************************/
1867
1868Double_t AliGenHBTosl::GetQOutQSideQLongCorrTheorValue(Double_t& out, Double_t& side, Double_t& lon) const
1869{
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);
1873}
1874/***********************************************************/
1875
1876Bool_t AliGenHBTosl::CheckParticle(TParticle* p, TParticle* aupair ,AliStack* stack)
1877{
1878 //Checks if a given particle is falling into signal region with any other particle
1879 //already existing on stack
1880 //PH return kFALSE;
1881
1882 if (fSignalRegion <=0) return kFALSE;
1883
1884 for (Int_t i = 0; i < stack->GetNtrack(); i++)
1885 {
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);
1892
1893 if (TMath::Abs(qout) < fSignalRegion)
1894 if (TMath::Abs(qside) < fSignalRegion)
1895 if (TMath::Abs(qlong) < fSignalRegion)
1896 return kTRUE;
1897 }
1898 return kFALSE;
1899}
1900/***********************************************************/
1901
1902void AliGenHBTosl::SwapGeneratingHistograms()
1903{
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++)
1908 {
1909 for (Int_t j = 1; j<=fQNBins; j++)
1910 {
1911 for (Int_t i = 1; i<=fQNBins; i++)
1912 {
1913 if ( fQSecondBackground->GetBinContent(i,j,k) < threshold) return;
1914 }
1915 }
1916
1917 }
1918
1919
1920 Info("SwapGeneratingHistograms","*******************************************");
1921 Info("SwapGeneratingHistograms","*******************************************");
1922 Info("SwapGeneratingHistograms","*******************************************");
1923 Info("SwapGeneratingHistograms","**** SWAPPING HISTOGRAMS ****");
1924 Info("SwapGeneratingHistograms","*******************************************");
1925 Info("SwapGeneratingHistograms","*******************************************");
1926 Info("SwapGeneratingHistograms","*******************************************");
1927
1928
1929 TH3D* h = fQSignal;
1930 fQSignal = fQSecondSignal;
1931 fQSecondSignal = h;
1932 fQSecondSignal->Reset();
1933 fQSecondSignal->SetDirectory(0x0);
1934
1935 h = fQBackground;
1936 fQBackground = fQSecondBackground;
1937 fQSecondBackground = h;
1938 fQSecondBackground->Reset();
1939 fQSecondBackground->SetDirectory(0x0);
1940
1941 fSwapped = kTRUE;
1942
1943}
1944
1945AliGenHBTosl& AliGenHBTosl::operator=(const AliGenHBTosl& rhs)
1946{
1947// Assignment operator
1948 rhs.Copy(*this);
1949 return *this;
1950}
1951
1952void AliGenHBTosl::Copy(TObject&) const
1953{
1954 //
1955 // Copy
1956 //
1957 Fatal("Copy","Not implemented!\n");
1958}
1959
1960