AliPhysics  3bba2fe (3bba2fe)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliFlowOnTheFlyEventGenerator.cxx
Go to the documentation of this file.
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 /*****************************************************************
17  AliFlowOnTheFlyEventGenerator
18 
19  Create events with realstic spectra and v_n values
20  store as AliFlowEventSimple
21 
22  usage: see $ALICE_PHYSICS/PWGCF/FLOW/macros/GenerateOnTheFlyEvents.C
23 
24  origin: Redmer Alexander Bertens, rbertens@cern.ch, rbertens@nikhef.nl, rbertens@uu.nl
25  Carlos Eugenio Perez Lara
26  Andrea Dubla
27 ******************************************************************/
28 
29 #include "Riostream.h"
30 #include "TObjArray.h"
31 #include "TClonesArray.h"
32 #include "TFile.h"
33 #include "TList.h"
34 #include "TTree.h"
35 #include "TParticle.h"
36 #include "TMath.h"
37 #include "TH1.h"
38 #include "TH1F.h"
39 #include "TH1D.h"
40 #include "TF1.h"
41 #include "TString.h"
42 #include "TProfile.h"
43 #include "TParameter.h"
44 #include "TBrowser.h"
45 #include "AliFlowTrackSimple.h"
46 #include "AliFlowEventSimple.h"
47 #include "TRandom.h"
48 #include "TVirtualMCDecayer.h"
50 
51 using std::endl;
52 using std::cout;
53 
55 
57 //_____________________________________________________________________________
58 AliFlowOnTheFlyEventGenerator::AliFlowOnTheFlyEventGenerator() : fGenerators(0), fEmbedMe(0), fFlowEvent(0), fDecayer(0), fAddV2Mothers(0), fAddV3Mothers(0), fAddV2Daughters(0), fAddV3Daughters(0), fPsi2(0), fPsi3(0), fPrecisionPhi(.001), fMaxNumberOfIterations(100), fQA(0), fFF(0) {/* constructor used for IO by root */}
59 //_____________________________________________________________________________
60 AliFlowOnTheFlyEventGenerator::AliFlowOnTheFlyEventGenerator(Bool_t qa, Int_t ff, Int_t mult, TVirtualMCDecayer* decayer, Bool_t a, Bool_t b, Bool_t c, Bool_t d) : fGenerators(0), fEmbedMe(0), fFlowEvent(0), fDecayer(0), fAddV2Mothers(0), fAddV3Mothers(0), fAddV2Daughters(0), fAddV3Daughters(0), fPsi2(0), fPsi3(0), fPrecisionPhi(.001), fMaxNumberOfIterations(100), fQA(qa), fFF(ff) {
61  // contructor
62  if(!fFlowEvent) fFlowEvent = new AliFlowEventSimple(mult, (AliFlowEventSimple::ConstructionMethod)0, 0x0, 0, TMath::TwoPi(), -.9, .9);
63  if(!fGenerators) {
64  fGenerators = new TObjArray();
65  fGenerators->SetOwner(kTRUE);
67  }
68  fDecayer = decayer; // decayer: user has ownership of decayer (see dtor)
69  if(fDecayer) fDecayer->Init();
70  fAddV2Mothers = a;
71  fAddV3Mothers = b;
72  fAddV2Daughters = c;
73  fAddV3Daughters = d;
74  if(fAddV3Mothers||fAddV3Daughters) printf(" > WARNING - v3 is not impelmented yet ! \n <");
75 }
76 //_____________________________________________________________________________
78 {
79  // destructor
80  if(fGenerators) delete fGenerators;
81  if(fFlowEvent) delete fFlowEvent;
82 }
83 //_____________________________________________________________________________
85 {
86  // return instance of generator class for given fPDG value
87  for(int i(0); i < fGenerators->GetEntriesFast(); i++) {
88  if(((NaiveFlowAndSpectrumGenerator*)fGenerators->At(i))->GetPDGCode()==pdg) {
90  }
91  }
92  if(make) {
94  fGenerators->Add(_tmp);
95  return _tmp;
96  }
97  return 0x0;
98 }
99 //_____________________________________________________________________________
101 {
102  // set pt spectrum for species, override default
103  NaiveFlowAndSpectrumGenerator* gen = Find(species, kTRUE);
104  TF1* spectrum = gen->GetPtSpectrum();
105  TString name = "";
106  if(spectrum) {
107  name = spectrum->GetName();
108  delete spectrum;
109  }
110  else name = Form("pt_%i", (int)species);
111  gen->SetPtSpectrum(new TF1(name.Data(), func, 0., 20));
112 }
113 //_____________________________________________________________________________
115 {
116  // set pt dependent v2 for species, override default
117  NaiveFlowAndSpectrumGenerator* gen = Find(species, kTRUE);
118  TF1* v2 = gen->GetDifferentialV2();
119  TString name = "";
120  if(v2) { // if v2 is already present, get its name and release its memory
121  name = v2->GetName();
122  delete v2;
123  }
124  else name = Form("v2_%i", (int)species);
125  gen->SetDifferentialV2(new TF1(name.Data(),func, 0., 20));
126 }
127 //_____________________________________________________________________________
129 {
130  // set pt dependent v2 for species, override default
131  NaiveFlowAndSpectrumGenerator* gen = Find(species, kTRUE);
132  TF1* v3 = gen->GetDifferentialV3();
133  TString name = "";
134  if(v3) { // if v3 is already present, get its name and release its memory
135  name = v3->GetName();
136  delete v3;
137  }
138  else name = Form("v3_%i", (int)species);
139  gen->SetDifferentialV3(new TF1(name.Data(), func, 0., 20));
140 }
141 //_____________________________________________________________________________
142 AliFlowEventSimple* AliFlowOnTheFlyEventGenerator::GenerateOnTheFlyEvent(TClonesArray* event, Int_t nSpecies, Int_t species[], Int_t mult[], Int_t bg, Bool_t fluc)
143 {
144  // generate a flow event according to settings provided in GENERATOR INTERFACE
145  fPsi2 = gRandom->Uniform(-TMath::Pi(), TMath::Pi());
146  // generate a random number which will be used for flow fuctuations (if requested)
147  Double_t fluc_poi(-1), fluc_rp(-1);
148  if(fFF == 1 || fFF == 3 ) fluc_poi = gRandom->Uniform();
149  if(fFF == 2) fluc_rp = gRandom->Uniform();
150  if(fFF == 3) fluc_rp = fluc_poi; // poi and rp fluctuations are fully correlated
151  // calculate the total multiplicity for the event
152  Int_t multPiKPr[] = {(int)(.7*bg/2.), (int)(.2*bg/2.), (int)(.1*bg/2.)};
153  Int_t fPDGPiKPr[] = {211, 321, 2212};
154  Int_t totalRPMultiplicity(0), totalPOIMultiplicity(0);
155  for(int i(0); i < nSpecies; i++) totalPOIMultiplicity+=mult[i];
156  for(int i(0); i < 3; i++) totalRPMultiplicity+=multPiKPr[i];
157  Int_t totalMultiplicity(totalRPMultiplicity+totalPOIMultiplicity);
158  // generate the particles of interest. if requested, a vn boost is given to the primary particles
159  for(int i(0); i < nSpecies; i++) {
160  if(fluc) GenerateOnTheFlyTracks((Int_t)(gRandom->Uniform(mult[i]-TMath::Sqrt(mult[i]), mult[i]+TMath::Sqrt(mult[i]))), species[i], event, fluc_poi);
161  else GenerateOnTheFlyTracks(mult[i], species[i], event, fluc_poi);
162  }
163  // generate reference particles. if requested, a vn boost is given to the primary particles
164  for(int i(0); i < 3; i++) {
165  if(fluc) {
166  GenerateOnTheFlyTracks((Int_t)(gRandom->Uniform(multPiKPr[i]-TMath::Sqrt(multPiKPr[i]), multPiKPr[i]+TMath::Sqrt(mult[i]))), fPDGPiKPr[i], event, fluc_rp);
167  GenerateOnTheFlyTracks((Int_t)(gRandom->Uniform(multPiKPr[i]-TMath::Sqrt(multPiKPr[i]), multPiKPr[i]+TMath::Sqrt(mult[i]))), -1*fPDGPiKPr[i], event, fluc_rp);
168  }
169  else {
170  GenerateOnTheFlyTracks(multPiKPr[i], fPDGPiKPr[i], event, fluc_rp);
171  GenerateOnTheFlyTracks(multPiKPr[i], -1*fPDGPiKPr[i], event, fluc_rp);
172  }
173  }
174  // if requested, decay the event
175  if(fDecayer) DecayOnTheFlyTracks(event);
176  // if an embedded event is given to the generator at this point, embed it
177  if(fEmbedMe) {
178  event->AbsorbObjects(fEmbedMe); // event has ownership of embedded event
179  fEmbedMe = 0x0; // reset to aviod embeddding more than once
180  }
181  // if requested, the secondaries are given a vn boost
182  if(fAddV2Daughters) AddV2(event);
183  // convert the event to an aliflowsimple event
184  // the tagging (rp) is done in this step, all tracks are tagged as rp's.
185  // daughters are made orphans (i.e. primaries with secondaries are rejected from the sample)
186  // converting clears the event tclones array
187  return ConvertTClonesToFlowEvent(event, totalMultiplicity);
188 }
189 //_____________________________________________________________________________
191 {
192  // convert the content of a tclones array to an aliflowevent simple for output and tag particles as poi's and rp's
193  // first step, see if there's already a flow event available in memory. if not create one
194  if(!fFlowEvent) fFlowEvent = new AliFlowEventSimple(totalMultiplicity, (AliFlowEventSimple::ConstructionMethod)0, 0x0, 0, TMath::TwoPi(), -.9, .9);
195  // if there is a flow event, clear the members without releasing the allocated memory
196  else fFlowEvent->ClearFast();
198  // prepare a track
199  TParticle* pParticle = 0x0;
200  Int_t iSelParticlesRP(0);
201  for (Int_t i(0); i < event->GetEntries(); i++) { // begin the loop over the input tracks
202  pParticle = (TParticle*)event->At(i); // get the particle
203  if (!pParticle) continue; // skip if empty slot (no particle)
204  if (pParticle->GetNDaughters()!=0) continue; // see if the particle has daughters (if so, reject it)
205  AliFlowTrackSimple* pTrack = new AliFlowTrackSimple(pParticle); // allocate space for the new flow track
206  pTrack->SetWeight(pParticle->Pz()); // ugly hack: store pz here ...
207  pTrack->SetID(pParticle->GetPdgCode()); // set pid code as id
208  pTrack->SetForRPSelection(kTRUE); // tag ALL particles as RP's,
209  // ugly hack 2: set charge to -1 for primaries and 1 for secondaries
210  if(pParticle->GetFirstMother()==-1) pTrack->SetCharge(-1);
211  else pTrack->SetCharge(1);
212  iSelParticlesRP++;
213  fFlowEvent->AddTrack(pTrack);
214  }
215  fFlowEvent->SetNumberOfRPs(iSelParticlesRP);
216  // all trakcs have safely been copied so we can clear the event
217  event->Clear();
219  return fFlowEvent;
220 }
221 //_____________________________________________________________________________
223 {
224  // afterburner, adds v2, uses Newton-Raphson iteration
225  Double_t phi = part->Phi();
226  Double_t phi0=phi;
227  Double_t f=0.;
228  Double_t fp=0.;
229  Double_t phiprev=0.;
230  // introduce flow fluctuations (gaussian)
231  if(fluc > -.5) {
232  v2+=TMath::Sqrt(2*(v2*.25)*(v2*.25))*TMath::ErfInverse(2*fluc-1);
233  if(fQA) Find(part->GetPdgCode(), kTRUE)->FillV2(part->Pt(), v2);
234  }
235  for (Int_t i=0; i!=fMaxNumberOfIterations; ++i) {
236  phiprev=phi; //store last value for comparison
237  f = phi-phi0+v2*TMath::Sin(2.*(phi-fPsi2));
238  fp = 1.0+2.0*v2*TMath::Cos(2.*(phi-fPsi2)); //first derivative
239  phi -= f/fp;
240  if (TMath::AreEqualAbs(phiprev,phi,fPrecisionPhi)) break;
241  }
242  part->SetMomentum( part->Pt()*TMath::Cos(phi), part->Pt()*TMath::Sin(phi), part->Pz(), part->Energy() );
243 }
244 //_____________________________________________________________________________
245 void AliFlowOnTheFlyEventGenerator::AddV2(TClonesArray* event)
246 {
247  // afterburner, adds v2 for different species to all tracks in an event
248  Double_t fluc(gRandom->Uniform()); // get a random number in case of fluctuations
249  // FIXME at the moment no distincition between mothers and daughters
250  TParticle *part;
251  for(Int_t nTrack=0; nTrack!=event->GetEntriesFast(); ++nTrack) {
252  part = (TParticle*) event->At(nTrack);
253  // for each track, call overloaded addv2 function with the correct generator
254  // create a generator in the case where the decayer has introduced a new particle species
255  if(part)
256  AddV2(part, Find(part->GetPdgCode(), kTRUE)->GetV2(part->Pt()), fluc);
257  }
258 }
259 //_____________________________________________________________________________
261 {
262  // generate tracks for the event. the tracks that are generated here are the mothers
263  Double_t ph, et, pt, mm, px, py, pz, ee;
264  // access the descired generator through the static find method. if the particle species is unknown, we add it to the generator
265  NaiveFlowAndSpectrumGenerator* generator = Find(pid, kTRUE);
266  Int_t _tempCounter = OnTheFlyEventGeneratorCounter;
267  for(int i=_tempCounter; i<=mult+_tempCounter; ++i) {
269  TParticle* part = (TParticle*)event->ConstructedAt(i);
270  part->SetStatusCode(1);
271  part->SetFirstMother(-1);
272  part->SetLastMother(-1);
273  part->SetFirstDaughter(-1);
274  part->SetLastDaughter(-1);
275  ph = gRandom->Uniform(0,TMath::TwoPi());
276  et = gRandom->Uniform(-1.0,+1.0);
277  pt = generator->GetPt();
278  part->SetPdgCode( pid );
279  mm = part->GetMass();
280  px = pt*TMath::Cos(ph);
281  py = pt*TMath::Sin(ph);
282  pz = pt*TMath::SinH(et);
283  ee = TMath::Sqrt( mm*mm + pt*pt+pz*pz );
284  part->SetMomentum( px, py, pz, ee );
285  // if requested add v2 to the sample of mothers
286  if(fAddV2Mothers) AddV2(part, generator->GetV2(pt), fluc);
287  }
288 }
289 //_____________________________________________________________________________
291 {
292  // decay the tracks using a decayer that is set in the GenerateEventsOnTheFly.C macro
293  if(!fDecayer) return; // shouldn't happen ...
294  Int_t kf;
295  TClonesArray* arr = new TClonesArray("TParticle",10);
296  Int_t secondaries=0;
297  Int_t nStart=0;
298  Int_t nTracks = event->GetEntriesFast();
299  TParticle *part, *part1;
300  TClonesArray &in = *event;
301  for(Int_t loop=0; loop!=3; ++loop) {
302  secondaries=0;
303  for(Int_t nTrack=nStart; nTrack!=nTracks; ++nTrack) {
304  arr->Clear();
305  part = (TParticle*) event->At( nTrack );
306  if(!part) continue;
307  kf = TMath::Abs(part->GetPdgCode());
308  if(kf==22 ) ForceGammaDecay(arr, part); // if gamma, we decay it by hand
309  else { // else we let pythia do it
310  TLorentzVector pmom( part->Px(), part->Py(), part->Pz(), part->Energy() );
311  fDecayer->Decay(kf,&pmom);
312  fDecayer->ImportParticles(arr);
313  }
314  Int_t nDaughters = arr->GetEntries();
315  if(nDaughters<2) continue;
316  for(Int_t nDaughter=1; nDaughter!=nDaughters; ++nDaughter) {
317  part1 = (TParticle*) (arr->At(nDaughter));
318  if(!part1) continue; // was part1, mistake?
319  new(in[nTracks+secondaries]) TParticle( part1->GetPdgCode(),
320  part1->GetStatusCode(),
321  part1->GetFirstMother(),
322  part1->GetSecondMother(),
323  part1->GetFirstDaughter(),
324  part1->GetLastDaughter(),
325  part1->Px(),
326  part1->Py(),
327  part1->Pz(),
328  part1->Energy(),
329  part1->Vx(),
330  part1->Vy(),
331  part1->Vz(),
332  part1->T());
333  secondaries++;
334  if(nDaughter==1) part->SetFirstDaughter(nTracks+secondaries);
335  else if ((nDaughters-1)==nDaughter) part->SetLastDaughter(nTracks+secondaries);
336  //else part->SetDaughter(nDaughter,nTracks+secondaries);
337  }
338  }
339  nStart = nTracks;
340  nTracks = event->GetEntries();
341  }
342  delete arr;
343  return;
344 }
345 //_____________________________________________________________________________
346 void AliFlowOnTheFlyEventGenerator::ForceGammaDecay(TClonesArray* arr, TParticle* part)
347 {
348  // force gama decay
349  const Float_t mass1(gRandom->Uniform(0.0000001, .1)); // FIXME randomly sample photon 'mass'
350  const Float_t mass_d1(.000511); // daughter mass (electron)
351  const Float_t mass_d2(.000511);
352  Double_t p_dec1=sqrt((TMath::Abs(mass1*mass1-(mass_d1+mass_d2)*(mass_d1+mass_d2))*(mass1*mass1-(mass_d1-mass_d2)*(mass_d1-mass_d2))))/2/mass1; // energy
353  TLorentzVector *p_d1=new TLorentzVector(); // lorentz vectors for daughters
354  TLorentzVector *p_d2=new TLorentzVector();
355  Double_t yy_m=part->Y(); // pseudo rapidity of mother
356  Double_t pt_m=part->Pt(); // pt of mother
357  Double_t mt_m=sqrt(mass1*mass1+pt_m*pt_m); // transverse mass of mother
358  Double_t pz_m=mt_m*TMath::SinH(yy_m); // MAGIC
359  Double_t phi_m=gRandom->Rndm()*2*TMath::Pi();
360  Double_t px_m=pt_m*TMath::Cos(phi_m);
361  Double_t py_m=pt_m*TMath::Sin(phi_m);
362  Double_t costh_d=2*gRandom->Rndm()-1;
363  Double_t phi_d=gRandom->Rndm()*2*TMath::Pi();
364  Double_t pz_d=p_dec1*costh_d;
365  Double_t pt_d=p_dec1*sqrt(1-costh_d*costh_d);
366  Double_t px_d=pt_d*TMath::Cos(phi_d);
367  Double_t py_d=pt_d*TMath::Sin(phi_d);
368  p_d1->SetPxPyPzE(px_d,py_d,pz_d,sqrt(mass_d1*mass_d1+p_dec1*p_dec1));
369  p_d2->SetPxPyPzE(-px_d,-py_d,-pz_d,sqrt(mass_d2*mass_d2+p_dec1*p_dec1));
370  Double_t gamma_b=sqrt(mass1*mass1+pz_m*pz_m+pt_m*pt_m)/mass1;
371  Double_t bx=px_m/gamma_b/mass1;
372  Double_t by=py_m/gamma_b/mass1;
373  Double_t bz=pz_m/gamma_b/mass1;
374  p_d1->Boost(bx,by,bz);
375  p_d2->Boost(bx,by,bz);
376  TParticle* daughter_1 = (TParticle*)arr->ConstructedAt(0);
377  TParticle* daughter_2 = (TParticle*)arr->ConstructedAt(1);
378  daughter_1->SetStatusCode(1);
379  daughter_1->SetFirstMother(-1);
380  daughter_1->SetLastMother(-1);
381  daughter_1->SetFirstDaughter(-1);
382  daughter_1->SetLastDaughter(-1);
383  daughter_1->SetPdgCode(11);
384  TLorentzVector& ref_p_d1 = *p_d1;
385  daughter_1->SetMomentum(ref_p_d1);
386  daughter_2->SetStatusCode(1);
387  daughter_2->SetFirstMother(-1);
388  daughter_2->SetLastMother(-1);
389  daughter_2->SetFirstDaughter(-1);
390  daughter_2->SetLastDaughter(-1);
391  daughter_2->SetPdgCode(-11);
392  TLorentzVector& pp = *p_d2;
393  daughter_2->SetMomentum(pp);
394 }
395 //_____________________________________________________________________________
397 {
398  // initializes generators for a list of common particles
399  // new generators will be created 'on the fly' if they are encountered
400  // if a generator is requested for a non-existent pdg value, things will get unstable ...
401  Short_t PDGcode[] = {11, -11, // e-
402  12, // v_e
403  13, -13, // mu-
404  14, // v_mu
405  15, -15, // t-
406  16, // v_t
407  21, // g
408  22, // gamma
409  111, // pi0
410  211, -211, // pi+
411  113, // rho0
412  213, -213, // rho+
413  221, // eta
414  331, // eta prime
415  130, // k0l
416  310, // k0s
417  311, // k0
418  313, // k*
419  321, -321, // k+
420  323, -323, // k*+
421  223, // omega
422  411, -411, // d+
423  413, -413, // d*+
424  421, // d0
425  423, // d*0
426  333, // phi
427  443, // jpsi
428  2112, // neutron
429  2212, -2212, // proton
430  3122, // lambda0
431  3312, -3312, // xi- (cascade)
432  3314, -3314, // xi*-
433  3322, // xi0
434  3324, // xi*0
435  3334}; // Omeg
436  for(int i(0); i < 47; i++) fGenerators->Add(new NaiveFlowAndSpectrumGenerator(PDGcode[i], fQA, fFF));
437 }
438 //_____________________________________________________________________________
440 {
441  // make sure all went ok
442  if(!fGenerators) {
443  printf(" > PANIC <\n");
444  return;
445  }
446  printf(" > %i species available in generator\n", fGenerators->GetEntriesFast());
447  for(int i(0); i < fGenerators->GetEntriesFast(); i++)
448  printf(" - PDG: %i \n", ((NaiveFlowAndSpectrumGenerator*)fGenerators->At(i))->GetPDGCode());
449  printf(" more can be created 'on the fly', but beware of non-existent pdg values !");
450 }
451 //_____________________________________________________________________________
453 {
454  // this function loops over all the species that are available in the fGenerators, which are
455  // a) created by the user (in the event generator) as mother particles or
456  // b) introduced by pythia (the decayer) as daughter particles
457  // c) made by the InitGenerators() function
458  // 'empty species' (i.e. species for which a generator exists but which were not actually sampled) are omitted
459  // the output histograms are written to a file named "GeneratorfQA.root"
460  if(!fQA) {
461  printf(" > Request has been made for QA plots but QA histograms have been disabled !\n");
462  return;
463  }
464  TFile *QAfile = new TFile("GeneratorfQA.root","RECREATE");
465  for(int i(0); i < fGenerators->GetEntriesFast(); i++) {
467  if(!gen) continue; // skip if we failed to get a generator
468  TH1F* QApt = (TH1F*)gen->GetQAType(0);
469  TH2F* QAv2 = (TH2F*)gen->GetQAType(1);
470  TH2F* QAv3 = (TH2F*)gen->GetQAType(2);
471  if((!QApt)||(!QAv2)||(!QAv3)) {
472  printf(" > couldn't read qa histogrmas for species %i <\n", gen->GetPDGCode());
473  continue;
474  }
475  if(QApt->GetEntries()==0&&QAv2->GetEntries()==0&&QAv3->GetEntries()==0) continue; // skip if no tracks of this species have been sampled
476  printf(" > saving QA histograms for sampled species %i <\n", gen->GetPDGCode());
477  QAfile->mkdir(Form("fPDG_%i", gen->GetPDGCode())); // create a directory in the output file
478  QAfile->cd(Form("fPDG_%i", gen->GetPDGCode())); // cd into this directory
479  if(QApt->GetEntries() != 0) { // only plot the pt fSpectrum if this guy was generated
480  if(gen->GetPtSpectrum()->Integral(0,20) != 0) {
481  QApt->Scale(gen->GetPtSpectrum()->Integral(0,20)/QApt->Integral(),"width");
482  QApt->Write();
483  }
484  }
485  gen->GetPtSpectrum()->SetNpx(10000); // otherwise tf1 plot is very ugly
486  gen->GetPtSpectrum()->Draw();
487  gen->GetPtSpectrum()->Write();
488  if(v2) {
489  QAv2->Draw();
490  gen->GetDifferentialV2()->SetNpx(10000);
491  gen->GetDifferentialV2()->Draw();
492  gen->GetDifferentialV2()->Write();
493  QAv2->Write();
494  }
495  if(v3) {
496  QAv3->Draw();
497  gen->GetDifferentialV3()->Draw();
498  gen->GetDifferentialV3()->SetNpx(10000);
499  gen->GetDifferentialV3()->Write();
500  QAv3->Write();
501  }
502  }
503  QAfile->Close();
504 }
505 //_____________________________________________________________________________
506 
void SetCharge(Int_t charge)
NaiveFlowAndSpectrumGenerator * Find(Short_t pdg, Bool_t make)
Int_t pdg
double Double_t
Definition: External.C:58
TVirtualMCDecayer * fDecayer
flow event simple for output
Definition: External.C:236
AliFlowEventSimple * GenerateOnTheFlyEvent(TClonesArray *event, Int_t nSpecies, Int_t species[], Int_t mult[], Int_t bg, Bool_t fluc)
TCanvas * c
Definition: TestFitELoss.C:172
void SetPtDependentV2(const char *func, Short_t pdg)
AliFlowEventSimple * ConvertTClonesToFlowEvent(TClonesArray *event, Int_t totalMultiplicity)
void AddTrack(AliFlowTrackSimple *track)
static Int_t OnTheFlyEventGeneratorCounter
void SetPtDependentV3(const char *func, Short_t pdg)
TRandom * gRandom
void SetForRPSelection(Bool_t b=kTRUE)
void SetNumberOfRPs(Int_t nr)
void ForceGammaDecay(TClonesArray *arr, TParticle *part)
int Int_t
Definition: External.C:63
float Float_t
Definition: External.C:68
ClassImp(AliFlowOnTheFlyEventGenerator) AliFlowOnTheFlyEventGenerator
void SetPtSpectrum(const char *func, Short_t pdg)
void GenerateOnTheFlyTracks(Int_t mult, Int_t pid, TClonesArray *event, Double_t fluc)
short Short_t
Definition: External.C:23
void SetWeight(Double_t weight)
void AddV2(TParticle *particle, Double_t v2, Double_t fluc)
void SetMCReactionPlaneAngle(Double_t fPhiRP)
bool Bool_t
Definition: External.C:53