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)";
71 }
72
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
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
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.
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char e
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone proc
char error[CURL_ERROR_SIZE]
ClassImp(o2::eventgen::PrimaryGenerator)
uint32_t stack
Definition RawData.h:1
void SmearGausVertexXY(Bool_t flag)
FairGenericStack * fStack
void SetBeam(Double_t beamX0, Double_t beamY0, Double_t beamSigmaX, Double_t beamSigmaY)
FairMCEventHeader * fEvent
void SmearGausVertexZ(Bool_t flag)
virtual Bool_t GenerateEvent(FairGenericStack *pStack)
void SmearVertexXY(Bool_t flag)
void SetTarget(Double_t targetZ, Double_t targetDz)
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:116
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"