FairRoot
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FairPrimaryGenerator.cxx
Go to the documentation of this file.
1 /********************************************************************************
2  * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
3  * *
4  * This software is distributed under the terms of the *
5  * GNU Lesser General Public Licence (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
8 
9 #include "FairPrimaryGenerator.h"
10 
11 #include "FairGenerator.h" // for FairGenerator
12 #include "FairGenericStack.h" // for FairGenericStack
13 #include "FairLogger.h" // for FairLogger, MESSAGE_ORIGIN
14 #include "FairMCEventHeader.h" // for FairMCEventHeader
15 
16 #include <TDatabasePDG.h> // for TDatabasePDG
17 #include <TIterator.h> // for TIterator
18 #include <TMath.h> // for Sqrt
19 #include <TObject.h> // for TObject
20 #include <TParticlePDG.h> // for TParticlePDG
21 #include <TRandom.h> // for TRandom, gRandom
22 #include <iostream> // for operator<<, basic_ostream, etc
23 
24 using std::cerr;
25 using std::cout;
26 using std::endl;
27 
29 
31  : TNamed()
32  , fBeamX0(0.)
33  , fBeamY0(0.)
34  , fBeamSigmaX(0.)
35  , fBeamSigmaY(0.)
36  , fBeamAngleX0(0.)
37  , fBeamAngleY0(0.)
38  , fBeamAngleX(0.)
39  , fBeamAngleY(0.)
40  , fBeamAngleSigmaX(0.)
41  , fBeamAngleSigmaY(0.)
42  , fBeamDirection(TVector3(0., 0., 1.))
43  , fPhiMin(0.)
44  , fPhiMax(0.)
45  , fPhi(0.)
46  , fTargetZ(new Double_t[1])
47  , fNrTargets(1)
48  , fTargetDz(0)
49  , fVertex(TVector3(0., 0., 0.))
50  , fNTracks(0)
51  , fSmearVertexZ(kFALSE)
52  , fSmearGausVertexZ(kFALSE)
53  , fSmearVertexXY(kFALSE)
54  , fSmearGausVertexXY(kFALSE)
55  , fBeamAngle(kFALSE)
56  , fEventPlane(kFALSE)
57  , fStack(nullptr)
58  , fGenList(new TObjArray())
59  , fListIter(fGenList->MakeIterator())
60  , fEvent(nullptr)
61  , fdoTracking(kTRUE)
62  , fMCIndexOffset(0)
63  , fEventNr(0)
64 {
65  fTargetZ[0] = 0.;
66 }
67 
68 FairPrimaryGenerator::FairPrimaryGenerator(const char *name, const char *title)
69  : TNamed(name, title)
70  , fBeamX0(0)
71  , fBeamY0(0)
72  , fBeamSigmaX(0)
73  , fBeamSigmaY(0)
74  , fBeamAngleX0(0)
75  , fBeamAngleY0(0)
76  , fBeamAngleX(0)
77  , fBeamAngleY(0)
78  , fBeamAngleSigmaX(0)
79  , fBeamAngleSigmaY(0)
80  , fBeamDirection(TVector3(0., 0., 1.))
81  , fPhiMin(0.)
82  , fPhiMax(0.)
83  , fPhi(0.)
84  , fTargetZ(new Double_t[1])
85  , fNrTargets(1)
86  , fTargetDz(0)
87  , fVertex(TVector3(0., 0., 0.))
88  , fNTracks(0)
89  , fSmearVertexZ(kFALSE)
90  , fSmearGausVertexZ(kFALSE)
91  , fSmearVertexXY(kFALSE)
92  , fSmearGausVertexXY(kFALSE)
93  , fBeamAngle(kFALSE)
94  , fEventPlane(kFALSE)
95  , fStack(nullptr)
96  , fGenList(new TObjArray())
97  , fListIter(fGenList->MakeIterator())
98  , fEvent(nullptr)
99  , fdoTracking(kTRUE)
100  , fMCIndexOffset(0)
101  , fEventNr(0)
102 {
103  fTargetZ[0] = 0.;
104 }
105 
107  : TNamed(rhs)
108  , fBeamX0(rhs.fBeamX0)
109  , fBeamY0(rhs.fBeamY0)
110  , fBeamSigmaX(rhs.fBeamSigmaX)
111  , fBeamSigmaY(rhs.fBeamSigmaY)
112  , fBeamAngleX0(rhs.fBeamAngleX0)
113  , fBeamAngleY0(rhs.fBeamAngleY0)
114  , fBeamAngleX(rhs.fBeamAngleX)
115  , fBeamAngleY(rhs.fBeamAngleY)
116  , fBeamAngleSigmaX(rhs.fBeamAngleSigmaX)
117  , fBeamAngleSigmaY(rhs.fBeamAngleSigmaY)
118  , fBeamDirection(rhs.fBeamDirection)
119  , fPhiMin(rhs.fPhiMin)
120  , fPhiMax(rhs.fPhiMax)
121  , fPhi(rhs.fPhi)
122  , fTargetZ(new Double_t[1])
123  , fNrTargets(rhs.fNrTargets)
124  , fTargetDz(rhs.fTargetDz)
125  , fVertex(rhs.fVertex)
126  , fNTracks(rhs.fNTracks)
127  , fSmearVertexZ(rhs.fSmearVertexZ)
128  , fSmearGausVertexZ(rhs.fSmearGausVertexZ)
129  , fSmearVertexXY(rhs.fSmearVertexXY)
130  , fSmearGausVertexXY(rhs.fSmearGausVertexXY)
131  , fBeamAngle(rhs.fBeamAngle)
132  , fEventPlane(rhs.fEventPlane)
133  , fStack(nullptr)
134  , fGenList(new TObjArray())
135  , fListIter(fGenList->MakeIterator())
136  , fEvent(nullptr)
137  , fdoTracking(rhs.fdoTracking)
138  , fMCIndexOffset(rhs.fMCIndexOffset)
139  , fEventNr(rhs.fEventNr)
140 {
141  fTargetZ[0] = rhs.fTargetZ[0];
142 }
143 
145 {
147  for (Int_t i = 0; i < fGenList->GetEntries(); i++) {
148  FairGenerator *gen = static_cast<FairGenerator *>(fGenList->At(i));
149  if (gen) {
150  gen->Init();
151  }
152  }
153  return kTRUE;
154 }
155 
157 {
158 
159  delete[] fTargetZ;
160  fGenList->Delete();
161  delete fGenList;
162  delete fListIter;
163 }
164 
166 {
167  // check assignment to self
168  if (this != &rhs) {
169 
170  // base class assignment
171  TNamed::operator=(rhs);
172 
173  // assignment operator
174  fBeamX0 = rhs.fBeamX0;
175  fBeamY0 = rhs.fBeamY0;
176  fBeamSigmaX = rhs.fBeamSigmaX;
177  fBeamSigmaY = rhs.fBeamSigmaY;
180  fBeamAngleX = rhs.fBeamAngleX;
181  fBeamAngleY = rhs.fBeamAngleY;
185  fPhiMin = rhs.fPhiMin;
186  fPhiMax = rhs.fPhiMax;
187  fPhi = rhs.fPhi;
188  fTargetZ = new Double_t[1];
189  fNrTargets = rhs.fNrTargets;
190  fTargetDz = rhs.fTargetDz;
191  fVertex = rhs.fVertex;
192  fNTracks = rhs.fNTracks;
197  fBeamAngle = rhs.fBeamAngle;
198  fEventPlane = rhs.fEventPlane;
199  fStack = nullptr;
200  fGenList = new TObjArray();
201  fListIter = fGenList->MakeIterator();
202  fEvent = nullptr;
203  fdoTracking = rhs.fdoTracking;
205  fEventNr = rhs.fEventNr;
206  fTargetZ[0] = rhs.fTargetZ[0];
207  }
208 
209  return *this;
210 }
211 
213 {
214  // Check for MCEventHeader
215  if (!fEvent) {
216  LOG(fatal) << "No MCEventHeader branch!";
217  return kFALSE;
218  } else {
219  // Initialise
220  fStack = pStack;
221  fNTracks = 0;
222  fEvent->Reset();
223 
224  // Create beam angle
225  // Here we only randomly generate two angles (anglex, angley)
226  // for the event and later on (in AddTrack())
227  // all our particles will be rotated accordingly.
228  if (fBeamAngle) {
229  MakeBeamAngle();
230  }
231 
232  // Create event vertex
233  MakeVertex();
235 
236  // Create event plane
237  // Randomly generate an angle by which each track added (in AddTrack())
238  // to the event is rotated around the z-axis
239  if (fEventPlane) {
240  MakeEventPlane();
241  }
242 
243  // Call the ReadEvent methods from all registered generators
244  fListIter->Reset();
245  TObject *obj = 0;
246  FairGenerator *gen = 0;
247  while ((obj = fListIter->Next())) {
248  gen = dynamic_cast<FairGenerator *>(obj);
249  if (!gen) {
250  return kFALSE;
251  }
252  const char *genName = gen->GetName();
253  fMCIndexOffset = fNTracks; // number tracks before generator is called
254  Bool_t test = gen->ReadEvent(this);
255  if (!test) {
256  LOG(error) << "ReadEvent failed for generator " << genName;
257  return kFALSE;
258  }
259  }
260 
261  fTotPrim += fNTracks;
262  // Screen output
263 
264  // Set the event number if not set already by one of the dedicated generators
265  if (-1 == fEvent->GetEventID()) {
266  fEventNr++;
268  }
269  LOG(debug) << "(Event " << fEvent->GetEventID() << ") " << fNTracks << " primary tracks from vertex ("
270  << fVertex.X() << ", " << fVertex.Y() << ", " << fVertex.Z() << ") with beam angle (" << fBeamAngleX
271  << ", " << fBeamAngleY << ") ";
272 
274 
275  return kTRUE;
276  }
277 }
278 
280  Double_t px_raw,
281  Double_t py_raw,
282  Double_t pz_raw,
283  Double_t vx,
284  Double_t vy,
285  Double_t vz,
286  Int_t parent,
287  Bool_t wanttracking,
288  Double_t e,
289  Double_t tof,
290  Double_t weight,
291  TMCProcess proc)
292 {
293  // ---> Add event vertex to track vertex
294  vx += fVertex.X();
295  vy += fVertex.Y();
296  vz += fVertex.Z();
297 
298  // cout << "FairPrimaryGenerator::AddTrack +Z" << fVertex.Z() << " pdgid " <<
299  // pdgid << "?"<< wanttracking << endl;
300 
301  TVector3 mom(px_raw, py_raw, pz_raw);
302 
303  if (fEventPlane) {
304  // Rotate the track (event) by the randomly generated angle which is fixed
305  // for the complete event.
306  // The coordinate system is not changed by this rotation.
307  mom.RotateZ(fPhi);
308  }
309 
310  if (fBeamAngle) {
311  // Rotate the track (event) from the rotated beam direction system into
312  // the fixed global experiment coordinate system
313  mom.RotateUz(fBeamDirection.Unit());
314  }
315 
316  // ---> Convert K0 and AntiK0 into K0s and K0L
317  if (pdgid == 311 || pdgid == -311) {
318  Double_t test = gRandom->Uniform(0., 1.);
319  if (test >= 0.5) {
320  pdgid = 310;
321  } // K0S
322  else {
323  pdgid = 130;
324  } // K0L
325  }
326 
327  // ---> Check whether particle type is in PDG Database
328  TDatabasePDG *pdgBase = TDatabasePDG::Instance();
329  if (!pdgBase) {
330  Fatal("FairPrimaryGenerator", "No TDatabasePDG instantiated");
331  } else {
332  TParticlePDG *pdgPart = pdgBase->GetParticle(pdgid);
333  if (!pdgPart) {
334  if (e < 0) {
335  cerr << "\033[5m\033[31m -E FairPrimaryGenerator: PDG code " << pdgid
336  << " not found in database.\033[0m " << endl;
337  cerr << "\033[5m\033[31m -E FairPrimaryGenerator: Discarding particle "
338  "\033[0m "
339  << endl;
340  cerr << "\033[5m\033[31m -E FairPrimaryGenerator: now MC Index is "
341  "corrupted \033[0m "
342  << endl;
343  return;
344  } else {
345  cout << "\033[5m\033[31m -W FairPrimaryGenerator: PDG code " << pdgid
346  << " not found in database. This warning can be savely "
347  "ignored.\033[0m "
348  << endl;
349  }
350  }
351  }
352  // ---> Get mass and calculate energy of particle
353  if (e < 0) {
354  Double_t mass = pdgBase->GetParticle(pdgid)->Mass();
355  e = TMath::Sqrt(mom.Mag2() + mass * mass);
356  } // else, use the value of e given to the function
357 
358  // ---> Set all other parameters required by PushTrack
359  Int_t doTracking = 0; // Go to tracking
360  if (fdoTracking && wanttracking) {
361  doTracking = 1;
362  }
363  Int_t dummyparent = -1; // Primary particle (now the value is -1 by default)
364  Double_t polx = 0.; // Polarisation
365  Double_t poly = 0.;
366  Double_t polz = 0.;
367  Int_t ntr = 0; // Track number; to be filled by the stack
368  Int_t status = 0; // Generation status
369 
370  if (parent != -1) {
371  parent += fMCIndexOffset;
372  } // correct for tracks which are in list before generator is called
373  // Add track to stack
374  fStack->PushTrack(doTracking,
375  dummyparent,
376  pdgid,
377  mom.X(),
378  mom.Y(),
379  mom.Z(),
380  e,
381  vx,
382  vy,
383  vz,
384  tof,
385  polx,
386  poly,
387  polz,
388  proc,
389  ntr,
390  weight,
391  status,
392  parent);
393  fNTracks++;
394 }
395 
397 {
398  FairPrimaryGenerator *newPrimaryGenerator = new FairPrimaryGenerator(*this);
399 
401  for (Int_t i = 0; i < fGenList->GetEntries(); i++) {
402  FairGenerator *gen = static_cast<FairGenerator *>(fGenList->At(i));
403  if (gen) {
404  newPrimaryGenerator->AddGenerator(gen->CloneGenerator());
405  }
406  }
407 
408  return newPrimaryGenerator;
409 }
410 
411 void FairPrimaryGenerator::SetBeam(Double_t x0, Double_t y0, Double_t sigmaX, Double_t sigmaY)
412 {
413  fBeamX0 = x0;
414  fBeamY0 = y0;
415  fBeamSigmaX = sigmaX;
416  fBeamSigmaY = sigmaY;
417 }
418 
419 void FairPrimaryGenerator::SetBeamAngle(Double_t beamAngleX0,
420  Double_t beamAngleY0,
421  Double_t beamAngleSigmaX,
422  Double_t beamAngleSigmaY)
423 {
424  fBeamAngleX0 = beamAngleX0;
425  fBeamAngleY0 = beamAngleY0;
426  fBeamAngleSigmaX = beamAngleSigmaX;
427  fBeamAngleSigmaY = beamAngleSigmaY;
428  fBeamAngle = kTRUE;
429 }
430 
431 void FairPrimaryGenerator::SetEventPlane(Double_t phiMin, Double_t phiMax)
432 {
433  fPhiMin = phiMin;
434  fPhiMax = phiMax;
435  fEventPlane = kTRUE;
436 }
437 
438 void FairPrimaryGenerator::SetTarget(Double_t z, Double_t dz)
439 {
440 
441  fTargetZ[0] = z;
442  fTargetDz = dz;
443 }
444 
445 void FairPrimaryGenerator::SetMultTarget(Int_t nroftargets, Double_t *targetpos, Double_t dz)
446 {
447 
448  delete[] fTargetZ;
449 
450  fNrTargets = nroftargets;
451 
452  fTargetZ = new Double_t[nroftargets];
453  for (Int_t i = 0; i < nroftargets; i++) {
454  fTargetZ[i] = targetpos[i];
455  }
456  fTargetDz = dz;
457 }
458 
460 {
461  Double_t vx = fBeamX0;
462  Double_t vy = fBeamY0;
463  Double_t vz;
464  if (1 == fNrTargets) {
465  vz = fTargetZ[0];
466  } else {
467  Int_t Target = static_cast<Int_t>(gRandom->Uniform(fNrTargets));
468  vz = fTargetZ[Target];
469  }
470 
471  if (fSmearVertexZ)
472  vz = gRandom->Uniform(vz - fTargetDz / 2., vz + fTargetDz / 2.);
473 
474  if (fSmearGausVertexZ) {
475  vz = gRandom->Gaus(vz, fTargetDz);
476  }
477 
478  if (fSmearGausVertexXY) {
479  if (fBeamSigmaX != 0.) {
480  vx = gRandom->Gaus(fBeamX0, fBeamSigmaX);
481  }
482  if (fBeamSigmaY != 0.) {
483  vy = gRandom->Gaus(fBeamY0, fBeamSigmaY);
484  }
485  }
486 
487  if (fSmearVertexXY) {
488  if (fBeamSigmaX != 0.) {
489  vx = gRandom->Uniform(vx - fBeamSigmaX / 2., vx + fBeamSigmaX / 2.);
490  }
491  if (fBeamSigmaY != 0.) {
492  vy = gRandom->Uniform(vy - fBeamSigmaY / 2., vy + fBeamSigmaY / 2.);
493  }
494  }
495 
496  fVertex = TVector3(vx, vy, vz);
497 }
498 
500 {
501  fBeamAngleX = gRandom->Gaus(fBeamAngleX0, fBeamAngleSigmaX);
502  fBeamAngleY = gRandom->Gaus(fBeamAngleY0, fBeamAngleSigmaY);
503  fBeamDirection.SetXYZ(TMath::Tan(fBeamAngleX), TMath::Tan(fBeamAngleY), 1.);
506 }
507 
509 {
510  fPhi = gRandom->Uniform(fPhiMin, fPhiMax);
511  fEvent->SetRotZ(fPhi);
512 }
513 
515 {
516  fSmearVertexZ = flag;
518  fSmearGausVertexZ = kFALSE;
519  }
520 }
521 
523 {
524  fSmearGausVertexZ = flag;
526  fSmearVertexZ = kFALSE;
527  }
528 }
530 {
531  fSmearVertexXY = flag;
533  fSmearGausVertexXY = kFALSE;
534  }
535 }
537 {
538  fSmearGausVertexXY = flag;
540  fSmearVertexXY = kFALSE;
541  }
542 }
543 
void SmearVertexXY(Bool_t flag)
virtual FairGenerator * CloneGenerator() const
void AddGenerator(FairGenerator *generator)
ClassImp(FairEventBuilder)
virtual void PushTrack(Int_t toBeDone, Int_t parentID, Int_t pdgCode, Double_t px, Double_t py, Double_t pz, Double_t e, Double_t vx, Double_t vy, Double_t vz, Double_t time, Double_t polx, Double_t poly, Double_t polz, TMCProcess proc, Int_t &ntr, Double_t weight, Int_t is, Int_t secondparentID)=0
void SetTarget(Double_t targetZ, Double_t targetDz)
void SetRotY(Double_t roty)
virtual FairPrimaryGenerator * ClonePrimaryGenerator() const
void SetEventPlane(Double_t phiMin, Double_t phiMax)
void SetRotX(Double_t rotx)
void SmearGausVertexZ(Bool_t flag)
FairPrimaryGenerator & operator=(const FairPrimaryGenerator &)
void SetNPrim(Int_t nPrim)
void SetBeamAngle(Double_t beamAngleX0, Double_t beamAngleY0, Double_t beamAngleSigmaX, Double_t beamAngleSigmaY)
void SetRotZ(Double_t rotz)
virtual void AddTrack(Int_t pdgid, Double_t px, Double_t py, Double_t pz, Double_t vx, Double_t vy, Double_t vz, Int_t parent=-1, Bool_t wanttracking=true, Double_t e=-9e9, Double_t tof=0., Double_t weight=0., TMCProcess proc=kPPrimary)
void SetVertex(Double_t x, Double_t y, Double_t z)
void SetBeam(Double_t beamX0, Double_t beamY0, Double_t beamSigmaX, Double_t beamSigmaY)
virtual Bool_t GenerateEvent(FairGenericStack *pStack)
void SmearVertexZ(Bool_t flag)
void SetEventID(UInt_t eventId)
virtual Bool_t ReadEvent(FairPrimaryGenerator *primGen)=0
FairGenericStack * fStack
FairMCEventHeader * fEvent
void SetMultTarget(Int_t nroftargets, Double_t *targetZ, Double_t targetDz)
void SmearGausVertexXY(Bool_t flag)
UInt_t GetEventID() const
run identifier
virtual Bool_t Init()
Definition: FairGenerator.h:53