Project
Loading...
Searching...
No Matches
PrimaryGenerator.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
13
21#include "DetectorsBase/Stack.h"
22#include <fairlogger/Logger.h>
23
24#include "FairGenericStack.h"
25#include "TFile.h"
26#include "TTree.h"
27
28#include "TDatabasePDG.h"
29#include "TVirtualMC.h"
30
32
33namespace o2
34{
35namespace eventgen
36{
37
38/*****************************************************************/
39
41{
43 LOG(info) << "Destructing PrimaryGenerator";
44 if (mEmbedFile && mEmbedFile->IsOpen()) {
45 mEmbedFile->Close();
46 delete mEmbedFile;
47 }
48 if (mEmbedEvent) {
49 delete mEmbedEvent;
50 }
51}
52
53/*****************************************************************/
54
56{
59 LOG(info) << "Initialising primary generator";
60
61 // set generator ID and description
65
67 if (mEmbedTree) {
68 LOG(info) << "Embedding into: " << mEmbedFile->GetName()
69 << " (" << mEmbedEntries << " events)";
70 return FairPrimaryGenerator::Init();
71 }
72
74 return FairPrimaryGenerator::Init();
75}
76
77/*****************************************************************/
78
80{
84 if (!mEmbedTree || mEmbedIndex < 0) {
85 fixInteractionVertex(); // <-- always fixes vertex outside of FairROOT
86 auto ret = FairPrimaryGenerator::GenerateEvent(pStack);
87 if (ret) {
88 setGeneratorInformation();
89 }
90 return ret;
91 }
92
94 if (mEmbedIndex >= 0) {
96 mEmbedTree->GetEntry(mEmbedIndex);
98
100 auto genList = GetListOfGenerators();
101 for (int igen = 0; igen < genList->GetEntries(); ++igen) {
102 auto o2gen = dynamic_cast<Generator*>(genList->At(igen));
103 if (o2gen) {
105 }
106 }
107 }
108
110 if (!FairPrimaryGenerator::GenerateEvent(pStack)) {
111 return kFALSE;
112 }
113
115 auto o2event = dynamic_cast<MCEventHeader*>(fEvent);
116 if (o2event) {
117 o2event->setEmbeddingFileName(mEmbedFile->GetName());
118 o2event->setEmbeddingEventIndex(mEmbedIndex);
119 }
120 setGeneratorInformation();
121
123 mEmbedIndex++;
125
127 return kTRUE;
128}
129
130/*****************************************************************/
131
132void PrimaryGenerator::AddTrack(Int_t pdgid, Double_t px, Double_t py, Double_t pz,
133 Double_t vx, Double_t vy, Double_t vz,
134 Int_t mother1, Int_t mother2,
135 Int_t daughter1, Int_t daughter2,
136 Bool_t wanttracking,
137 Double_t e, Double_t tof,
138 Double_t weight, TMCProcess proc, Int_t generatorStatus)
139{
142 // check the status encoding
143 if (!mcgenstatus::isEncoded(generatorStatus) && proc == TMCProcess::kPPrimary) {
144 LOG(fatal) << "Generator status " << generatorStatus << " of particle is not encoded properly.";
145 }
146
148 vx += fVertex.X();
149 vy += fVertex.Y();
150 vz += fVertex.Z();
151
153 auto particlePDG = TDatabasePDG::Instance()->GetParticle(pdgid);
154 if (wanttracking && !particlePDG) {
155 LOG(warn) << "Particle to be tracked is not defined in PDG: pdg = " << pdgid << " (disabling tracking)";
156 wanttracking = false;
157 }
158
160 Int_t doTracking = 0; // Go to tracking
161 if (fdoTracking && wanttracking) {
162 doTracking = 1;
163 }
164 Int_t dummyparent = -1; // Primary particle (now the value is -1 by default)
165 Double_t polx = 0.; // Polarisation
166 Double_t poly = 0.;
167 Double_t polz = 0.;
168 Int_t ntr = 0; // Track number; to be filled by the stack
169 Int_t status = generatorStatus; // Generation status
170
171 // correct for tracks which are in list before generator is called
172 if (mother1 != -1) {
173 mother1 += fMCIndexOffset;
174 }
175 if (mother2 != -1) {
176 mother2 += fMCIndexOffset;
177 }
178 if (daughter1 != -1) {
179 daughter1 += fMCIndexOffset;
180 }
181 if (daughter2 != -1) {
182 daughter2 += fMCIndexOffset;
183 }
184
193 if (abs(pdgid) == 311 && doTracking) {
194 LOG(warn) << "K0/antiK0 requested for tracking: converting into K0s/K0L";
195 pdgid = gRandom->Uniform() < 0.5 ? 310 : 130;
196 }
197
199 if (e < 0) {
200 double mass = particlePDG ? particlePDG->Mass() : 0.;
201 e = std::sqrt(mass * mass + px * px + py * py + pz * pz);
202 }
203
205 auto stack = dynamic_cast<o2::data::Stack*>(fStack);
206 if (!stack) {
207 LOG(fatal) << "Stack must be an o2::data:Stack";
208 return; // must be the o2 stack
209 }
210 stack->PushTrack(doTracking, mother1, pdgid, px, py, pz,
211 e, vx, vy, vz, tof, polx, poly, polz, TMCProcess::kPPrimary, ntr,
212 weight, status, mother2, daughter1, daughter2, proc);
213
214 fNTracks++;
215}
216
217/*****************************************************************/
218
219void PrimaryGenerator::AddTrack(Int_t pdgid, Double_t px, Double_t py,
220 Double_t pz, Double_t vx, Double_t vy,
221 Double_t vz, Int_t parent, Bool_t wanttracking,
222 Double_t e, Double_t tof, Double_t weight, TMCProcess proc)
223{
224 // Do this to encode status code correctly. In FairRoot's PrimaryGenerator, this is simply one number that is set to 0.
225 // So we basically do the same.
226 // Assuming that this is treated as the HepMC status code down the line (as it used to be).
227 AddTrack(pdgid, px, py, pz, vx, vy, vz, parent, -1, -1, -1, wanttracking,
228 e, tof, weight, proc, mcgenstatus::MCGenStatusEncoding(0, 0).fullEncoding);
229}
230
231/*****************************************************************/
232
234{
235 if (!mApplyVertex) {
236 return;
237 }
240 Double_t xyz[3] = {event->GetX(), event->GetY(), event->GetZ()};
241 SetBeam(xyz[0], xyz[1], 0., 0.);
242 SetTarget(xyz[2], 0.);
243 SmearVertexXY(false);
244 SmearVertexZ(false);
245 SmearGausVertexXY(false);
246 SmearGausVertexZ(false);
247}
248
249/*****************************************************************/
251{
252 if (!mApplyVertex) {
253 return;
254 }
258 mHaveExternalVertex = true;
259}
260
261/*****************************************************************/
262
264{
267 if (!v) {
268 LOG(fatal) << "A valid MeanVertexObject needs to be passed with option o2::conf::VertexMode::kCCDB";
269 }
270 mMeanVertex = std::move(std::unique_ptr<o2::dataformats::MeanVertexObject>(new o2::dataformats::MeanVertexObject(*v)));
271 LOG(info) << "The mean vertex is set to :";
272 mMeanVertex->print();
273 }
275 setApplyVertex(false);
276 LOG(info) << "Disabling vertexing";
277 mMeanVertex = std::move(std::unique_ptr<o2::dataformats::MeanVertexObject>(new o2::dataformats::MeanVertexObject(0, 0, 0, 0, 0, 0, 0, 0)));
278 LOG(info) << "The mean vertex is set to :";
279 mMeanVertex->print();
280 }
281}
282
283/*****************************************************************/
284
286{
287 if (!mApplyVertex) {
288 SetBeam(0., 0., 0., 0.);
289 SetTarget(0., 0.);
290 return;
291 }
292
293 // if someone gave vertex from outside; we will take it
295 SetBeam(mExternalVertexX, mExternalVertexY, 0., 0.);
296 SetTarget(mExternalVertexZ, 0.);
297 mHaveExternalVertex = false; // the vertex is now consumed
298 return;
299 }
300
301 // sampling a vertex and fixing for next event; no smearing will be done
302 // inside FairPrimaryGenerator;
303 SmearVertexXY(false);
304 SmearVertexZ(false);
305 SmearGausVertexXY(false);
306 SmearGausVertexZ(false);
307
308 // we use the mMeanVertexObject if initialized (initialize first)
309 if (mMeanVertex.get() == nullptr) {
312 const auto& xyz = param.position;
313 const auto& sigma = param.width;
314 mMeanVertex = std::move(std::unique_ptr<o2::dataformats::MeanVertexObject>(new o2::dataformats::MeanVertexObject(xyz[0], xyz[1], xyz[2], sigma[0], sigma[1], sigma[2], param.slopeX, param.slopeY)));
315 }
317 mMeanVertex = std::move(std::unique_ptr<o2::dataformats::MeanVertexObject>(new o2::dataformats::MeanVertexObject(0, 0, 0, 0, 0, 0, 0, 0)));
318 }
320 // fatal.. then the object should have been passed with setting
321 LOG(fatal) << "MeanVertexObject is null ... but mode is kCCDB. Please inject the valid CCDB object via setVertexMode";
322 }
323 }
324 auto sampledvertex = mMeanVertex->sample();
325
326 if (PrimaryGeneratorParam::Instance().verbose) {
327 LOG(info) << "Sampled interacting vertex " << sampledvertex;
328 }
329 SetBeam(sampledvertex.X(), sampledvertex.Y(), 0., 0.);
330 SetTarget(sampledvertex.Z(), 0.);
331}
332
333/*****************************************************************/
334
335Bool_t PrimaryGenerator::embedInto(TString fname)
336{
340 if (mEmbedFile && mEmbedFile->IsOpen()) {
341 LOG(error) << "Another embedding file is currently open";
342 return kFALSE;
343 }
344
346 mEmbedFile = TFile::Open(fname);
347 if (!mEmbedFile || !mEmbedFile->IsOpen()) {
348 LOG(error) << "Cannot open file for embedding: " << fname;
349 return kFALSE;
350 }
351
353 mEmbedTree = (TTree*)mEmbedFile->Get("o2sim");
354 if (!mEmbedTree) {
355 LOG(error) << R"(Cannot find "o2sim" tree for embedding in )" << fname;
356 return kFALSE;
357 }
358
360 mEmbedEntries = mEmbedTree->GetEntries();
361 if (mEmbedEntries <= 0) {
362 LOG(error) << "Invalid number of entries found in tree for embedding: " << mEmbedEntries;
363 return kFALSE;
364 }
365
368 mEmbedTree->SetBranchAddress("MCEventHeader.", &mEmbedEvent);
369
371 return kTRUE;
372}
373
374/*****************************************************************/
375
376void PrimaryGenerator::setGeneratorInformation()
377{
378 auto o2event = dynamic_cast<MCEventHeader*>(fEvent);
379 if (o2event) {
380 o2event->putInfo<int>(o2::mcgenid::GeneratorProperty::GENERATORID, mGeneratorId);
381 o2event->putInfo<std::string>(o2::mcgenid::GeneratorProperty::GENERATORDESCRIPTION, mGeneratorDescription);
382 }
383}
384
385/*****************************************************************/
386/*****************************************************************/
387
388} /* namespace eventgen */
389} /* namespace o2 */
390
Definition of the Stack class.
ClassImp(o2::eventgen::PrimaryGenerator)
uint32_t stack
Definition RawData.h:1
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) override
Definition Stack.cxx:176
void setEmbeddingFileName(std::string const &value)
void putInfo(std::string const &key, T const &value)
virtual void notifyEmbedding(const o2::dataformats::MCEventHeader *eventHeader)
Definition Generator.h:103
void setGeneratorDescription(std::string const &desc)
Bool_t GenerateEvent(FairGenericStack *pStack) override
void setVertexMode(o2::conf::VertexMode const &mode, o2::dataformats::MeanVertexObject const *obj=nullptr)
void setInteractionVertex(const o2::dataformats::MCEventHeader *event)
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 mother1=-1, Int_t mother2=-1, Int_t daughter1=-1, Int_t daughter2=-1, Bool_t wanttracking=true, Double_t e=-9e9, Double_t tof=0., Double_t weight=0., TMCProcess proc=kPPrimary, Int_t generatorStatus=0)
void setExternalVertexForNextEvent(double x, double y, double z)
o2::dataformats::MCEventHeader * mEmbedEvent
std::unique_ptr< o2::dataformats::MeanVertexObject > mMeanVertex
static constexpr Property GENERATORID
static constexpr Property GENERATORDESCRIPTION
struct _cl_event * event
Definition glcorearb.h:2982
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum mode
Definition glcorearb.h:266
const GLdouble * v
Definition glcorearb.h:832
GLuint GLuint GLfloat weight
Definition glcorearb.h:5477
GLint y
Definition glcorearb.h:270
GLenum const GLfloat * params
Definition glcorearb.h:272
GLenum GLfloat param
Definition glcorearb.h:271
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
bool isEncoded(MCGenStatusEncoding statusCode)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"