BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
run_sim_bmn.C
Go to the documentation of this file.
1// BM@N simulation: primary particles from an event generator are transported through the setup, and
2// then the MC points are converted to detector digits. Output: MC tracks, points and digits in simFile
3// genFile - input file with generator data, if needed
4// simFile - output file with MC data, default: bmnsim.root
5// nStartEvent - start event in the input generator file to begin transporting, default: 0
6// nEvents - number of events to transport
7// generatorName - generator name for the input file (enumeration above)
8// geometryTag - geometry tag from Geometry Database, "run9:" means Run 9 latest geometry (by creation date).
9// The tag can be followed by ';' and a path to an XML file with a local customization of the setup
10// e.g. "run9:;$VMCWORKDIR/my_setup.xml" (see database/geo_db/examples/README.md)
11// saveGeoInfo - whether save 'GeoTracks' for Event Display and create "full_geometry.root" with setup geometry
12// useRealEffects - whether we use realistic effects at simulation (Lorentz, misalignment)
13enum enumGenerators // enumeration of generator names corresponding input files
14{
24};
25
26void run_sim_bmn(TString genFile = "",
27 TString simFile = "$VMCWORKDIR/macro/run/bmnsim.root",
28 Int_t nStartEvent = 0,
29 Int_t nEvents = 10,
30 enumGenerators generatorName = BOX,
31 TString geometryTag = "run9:",
32 Bool_t saveGeoInfo = kFALSE,
33 Bool_t useRealEffects = kTRUE)
34{
35 gDebug = 0; // ROOT debug option
36 // if (gEnv) gEnv->SetValue("Root.Stacktrace", 0);
37 // Verbosity level (0 = summary only, 1 = event-level, 2 = track-level, 3 = full debug)
38 Int_t iVerbose = 0;
39 // LLog level for LOG(severity): "fatal", "error", "alarm", "important", "warn", "state", "info", "detail",
40 // "debug", "debug[1-4]", "trace", "nolog"
41 FairLogger::GetLogger()->SetLogScreenLevel("info");
42 gRandom->SetSeed(0); // set seed for PRNG
43
44 TStopwatch timer;
45 timer.Start();
46
47 // ----- Create simulation run ----------------------------------------
48 FairRunSim* fRun = new FairRunSim();
49 fRun->SetUseFairLinks(kTRUE);
50
51 // Choose the Geant Navigation System
52 fRun->SetName("TGeant4"); // or "TGeant3"
53
54 // The geometry tag can carry a path to an XML file with a local customization of the setup
55 // (see database/geo_db/examples/README.md) after the ';' separator, e.g.:
56 // "run9:;my_setup.xml" - the latest Run 9 geometry customized by the file
57 TString geoLocalSettings = "";
58 if (BmnFunctionSet::ParseGeometryTag(geometryTag, geoLocalSettings) != 0)
59 exit(-1);
60
61 // Get period from the given geometry tag and set FaiRun::RunId
62 UInt_t run_period = 9;
63 TPRegexp re_run_number("(run(\\d+))");
64 TString run_tag = geometryTag;
65 if (re_run_number.MatchB(run_tag)) {
66 re_run_number.Substitute(run_tag, "$2");
67 run_period = run_tag.Atoi();
68 fRun->SetRunId(run_period);
69 }
70 // Load the BM@N setup geometry from the Geometry Database
71 GeoSetup gSetup;
72 if (TString(geometryTag.Strip(TString::kBoth)).EndsWith(":")) {
73 geometryTag = TString(geometryTag.Strip(TString::kBoth)).Chop(); // remove trailing ":" if latest geometry
74 geometryTag = gSetup.GetLastApprovedSetupTag(geometryTag.Data()).c_str();
75 }
76 Int_t errStatus =
77 gSetup.LoadSetupToFairRunSim(geometryTag.Data(), geoLocalSettings.IsNull() ? nullptr : geoLocalSettings.Data());
78 if (errStatus != 0) {
79 cout << "ERROR: Geometry not loaded. Error status " << errStatus << endl;
80 exit(-1);
81 }
82
83 // Use the experiment specific MC Event header instead of the default one
84 // This one stores additional information about the reaction plane
85 // MpdMCEventHeader* mcHeader = new MpdMCEventHeader();
86 // fRun->SetMCEventHeader(mcHeader);
87
88 // Create and Set Event Generator
89 FairPrimaryGenerator* primGen = new FairPrimaryGenerator();
90 fRun->SetGenerator(primGen);
91
92 // Smearing of beam interaction point, if needed, and primary vertex position
93 // DO NOT do it in corresponding gen. sections to avoid incorrect summation!!!
94 // parameters for period 8
95 primGen->SetBeam(0.4376, 0.1239 - 0.3, 0.4537, 0.6925); // (beamX0, beamY0, beamSigmaX, beamSigmaY)
96 primGen->SetBeamAngle(0.011, 0.0, 0.0, 0.0); // (beamAngleX0, beamAngleY0, beamAngleSigmaX, beamAngleSigmaY)
97 primGen->SetTarget(-0.01942, 0.175); // (targetZ, targetDz)
98 primGen->SmearVertexZ(kTRUE);
99 primGen->SmearGausVertexXY(kTRUE);
100
101 switch (generatorName) {
102 case UNIGEN: {
103 if (!BmnFunctionSet::CheckFileExist(genFile, 1))
104 exit(-1);
105
106 auto* unigen = new MpdUnigenGenerator(genFile);
107 unigen->RegisterIons();
108 primGen->AddGenerator(unigen);
109 unigen->SetEventPlane(-M_PI, M_PI);
110 auto n_events_in_tree = unigen->GetNEntries();
111 if (nStartEvent >= n_events_in_tree) {
112 cout << "You are trying to specify the event out reach of current tree" << generatorName << endl;
113 exit(-3);
114 }
115 auto n_avail_events = n_events_in_tree - nStartEvent - 1;
116 if (nEvents <= 0)
117 nEvents = n_avail_events;
118 else
119 nEvents = std::min<int>(n_avail_events, nEvents);
120 cout << nEvents << " are availiable and will be processed" << endl;
121 if (nStartEvent > 0)
122 unigen->SkipEvents(nStartEvent);
123 break;
124 }
125 // ------- UrQMD Generator
126 case URQMD: {
127 if (!BmnFunctionSet::CheckFileExist(genFile, 1))
128 exit(-1);
129
130 MpdUrqmdGenerator* urqmdGen = new MpdUrqmdGenerator(genFile);
131 // urqmdGen->SetEventPlane(0., 360.);
132 primGen->AddGenerator(urqmdGen);
133 if (nStartEvent > 0)
134 urqmdGen->SkipEvents(nStartEvent);
135
136 // if nEvents is equal 0 then all events (start with nStartEvent) of the given file should be processed
137 if (nEvents == 0)
138 nEvents = MpdGetNumEvents::GetNumURQMDEvents(genFile.Data()) - nStartEvent;
139 break;
140 }
141
142 // ------- Particle Generator
143 case PART: {
144 // FairParticleGenerator generates a single particle type (PDG, mult, [GeV] px, py, pz, [cm] vx, vy, vz)
145 FairParticleGenerator* partGen = new FairParticleGenerator(211, 10, 1, 0, 3, 1, 0, 0);
146 primGen->AddGenerator(partGen);
147 break;
148 }
149
150 // ------- Ion Generator
151 case ION: {
152 // Start beam from a far point to check mom. reconstruction procedure (Z, A, q, mult, [GeV] px, py, pz, [cm]
153 // vx, vy, vz)
154 FairIonGenerator* fIongen = new FairIonGenerator(54, 124, 54, 1, 0., 0., 4.65, 0., 0., 0.); // Xe
155 primGen->AddGenerator(fIongen);
156 break;
157 }
158
159 // ------- Box Generator
160 case BOX: {
161 FairBoxGenerator* boxGen = new FairBoxGenerator(2212, 1); //(PDG code, multiplicity)
162 boxGen->SetPRange(0.2, 5.0); // GeV/c, setPRange vs setPtRange
163 boxGen->SetPhiRange(0, 360); // Azimuth angle range [degree]
164 boxGen->SetThetaRange(0, 40.0); // Polar angle in lab system range [degree]
165 primGen->AddGenerator(boxGen);
166 break;
167 }
168
169 // ------- HSD/PHSD Generator
170 case HSD: {
171 if (!BmnFunctionSet::CheckFileExist(genFile, 1))
172 exit(-1);
173
174 MpdPHSDGenerator* hsdGen = new MpdPHSDGenerator(genFile.Data());
175 // hsdGen->SetPsiRP(0.); // set fixed Reaction Plane angle instead of random
176 primGen->AddGenerator(hsdGen);
177 if (nStartEvent > 0)
178 hsdGen->SkipEvents(nStartEvent);
179
180 // if nEvents is equal 0 then all events (start with nStartEvent) of the given file should be processed
181 if (nEvents == 0)
182 nEvents = MpdGetNumEvents::GetNumPHSDEvents(genFile.Data()) - nStartEvent;
183 break;
184 }
185
186 // ------- LAQGSM/DCM-QGSM Generator
187 case QGSM:
188 case DCMQGSM: {
189
190 if (!BmnFunctionSet::CheckFileExist(genFile, 1))
191 exit(-1);
192
193 MpdLAQGSMGenerator* guGen = new MpdLAQGSMGenerator(genFile.Data(), kFALSE);
194 primGen->AddGenerator(guGen);
195 if (nStartEvent > 0)
196 guGen->SkipEvents(nStartEvent);
197
198 // if nEvents is equal 0 then all events (start with nStartEvent) of the given file should be processed
199 if (nEvents == 0)
200 nEvents = MpdGetNumEvents::GetNumQGSMEvents(genFile.Data()) - nStartEvent;
201 break;
202 }
203 case DCMSMM: {
204
205 if (!BmnFunctionSet::CheckFileExist(genFile, 1))
206 exit(-1);
207
208 MpdDCMSMMGenerator* smmGen = new MpdDCMSMMGenerator(genFile.Data());
209 primGen->AddGenerator(smmGen);
210 if (nStartEvent > 0)
211 smmGen->SkipEvents(nStartEvent);
212
213 // if nEvents is equal 0 then all events (start with nStartEvent) of the given file should be processed
214 if (nEvents == 0)
215 nEvents = MpdGetNumEvents::GetNumDCMSMMEvents(genFile.Data()) - nStartEvent;
216 break;
217 }
218
219 default: {
220 cout << "ERROR: Generator name was not pre-defined: " << generatorName << endl;
221 exit(-3);
222 }
223 } // end of switch (generatorName)
224
225 if (simFile == "")
226 simFile = "$VMCWORKDIR/macro/run/bmnsim.root";
227 // if directory for the output file does not exist, then create
228 if (BmnFunctionSet::CreateDirectoryTree(simFile, 1) < 0)
229 exit(-2);
230 fRun->SetSink(new FairRootFileSink(simFile.Data()));
231 fRun->SetIsMT(false);
232
233 // ----- Define beam, target and energy by the generator filename -----------
234 TString beamParticle = "", targetParticle = "";
235 Double_t beamEnergy = -1; // beam energy (GeV)
236 BmnFunctionSet::ParseFileName(gSystem->BaseName(genFile), beamParticle, targetParticle, beamEnergy);
237
238 // the parsed values are written to the FairBaseParSet container of the simulation file: the beam energy - to the
239 // beam momentum field, the beam and target names - to the container description as 'beam;target'.
240 // At the reconstruction stage BmnFillDstTask takes them from there to fill the run header of the DST file
241 if (beamEnergy > 0)
242 fRun->SetBeamMom(beamEnergy); // FairRunSim writes it to FairBaseParSet during the initialization
243 fRun->GetRuntimeDb()
244 ->getContainer("FairBaseParSet")
245 ->setDescription(TString::Format("%s;%s", beamParticle.Data(), targetParticle.Data()));
246
247 // ----- Create magnetic field ----------------------------------------
248 Double_t fieldScale = 0.929; // default for 3.8 GeV: 0.929 for 1900 A map (112.0 mV);
249 // trying to define magnetic field by the beam energy
250 if (beamEnergy > 0) {
251 double fieldValue = BmnFunctionSet::GetMagneticFieldByEnergy(beamParticle, beamEnergy);
252 if (fieldValue > 0)
253 fieldScale = fieldValue / 111.75; //? 112.0 gives 0.926 for 3.8 GeV, not 0.929
254 }
255 BmnFieldMap* magField = nullptr;
256 // if GetMagneticField(-1) -> get default value from the Geometry Database
257 magField = dynamic_cast<BmnFieldMap*>(gSetup.GetMagneticField(fieldScale));
258 // magField = new BmnNewFieldMap("FieldMap_1900_extrap_noPed.root");
259 // magField->SetScale(fieldScale);
260 fRun->SetField(magField);
261
262 fRun->SetStoreTraj(kTRUE);
263 fRun->SetRadLenRegister(kFALSE); // radiation length manager
264
265 // ----- Digitizers: converting MC points to detector digits -----------
266
267 // SiBT-Digitizer
268 BmnSiBTDigitizer* sibtDigit = new BmnSiBTDigitizer(run_period);
269 fRun->AddTask(sibtDigit);
270
271 // SiProf-Digitizer
272 BmnSiProfDigitizer* siprofDigit = new BmnSiProfDigitizer(run_period);
273 fRun->AddTask(siprofDigit);
274
275 // BD-Digitizer
276 BmnBdDigitizer* bdDigit = new BmnBdDigitizer();
277 fRun->AddTask(bdDigit);
278
279 // SiMD-Digitizer
280 BmnSiMDDigitizer* simdDigit = new BmnSiMDDigitizer();
281 fRun->AddTask(simdDigit);
282
283 // VSP-Digitizer
284 BmnVSPDigitizer* vspDigit = new BmnVSPDigitizer(run_period);
285 vspDigit->SetUseRealEffects(useRealEffects);
286 vspDigit->SetNoise(45.0, 150.0);
287 fRun->AddTask(vspDigit);
288
289 // SI-Digitizer
290 BmnSiliconDigitizer* siliconDigit = new BmnSiliconDigitizer(run_period);
291 siliconDigit->SetUseRealEffects(useRealEffects);
292 siliconDigit->SetNoise(45.0, 150.0); // AZ-150224
293 fRun->AddTask(siliconDigit);
294
295 // GEM-Digitizer
296 BmnGemStripDigitizer* gemDigit = new BmnGemStripDigitizer(run_period);
297 if (useRealEffects) {
299 // BmnGemStripMediumConfiguration::ARC4H10_80_20_E_1720_2240_3230_3730_B_0_7T); // 3.8 AGeV
300 // BmnGemStripMediumConfiguration::ARC4H10_80_20_E_1720_2240_3230_3730_B_0_3T); // 1.6 AGeV
301 // BmnGemStripMediumConfiguration::ARC4H10_80_20_E_1720_2240_3230_3730_B_0_4T); // 2.2 AGeV
303 gemDigit->SetUseRealEffects(useRealEffects);
304 }
305 gemDigit->SetNoise(10.0, 25.0); // AZ-150224
307 // BmnGemStripModule::SetANNModelPath("$VMCWORKDIR/parameters/gem/ANNModels/model_21.bmnmlp");
308 fRun->AddTask(gemDigit);
309
310 // CSC-Digitizer
311 BmnCSCDigitizer* cscDigit = new BmnCSCDigitizer(run_period);
312 fRun->AddTask(cscDigit);
313
314 // // ZDC-Digitizer (for period < 8)
315 // BmnZdcDigitizer* zdcDigit = new BmnZdcDigitizer();
316 // zdcDigit->SetScale(39e3);
317 // zdcDigit->SetThreshold(500.);
318 // fRun->AddTask(zdcDigit);
319
320 // FHCal-Digitizer (for period >= 8)
321 BmnFHCalDigitizer* fhcalDigit = new BmnFHCalDigitizer(run_period);
322 fRun->AddTask(fhcalDigit);
323
324 // ScWall-Digitizer
325 BmnScWallDigitizer* fScWallDigit = new BmnScWallDigitizer(run_period);
326 fRun->AddTask(fScWallDigit);
327
328 // Hodo-Digitizer
329 BmnHodoDigitizer* fHodoDigit = new BmnHodoDigitizer(run_period);
330 fRun->AddTask(fHodoDigit);
331
332 // Ndet-Digitizer
333 BmnNdetDigitizer* fNdetDigit = new BmnNdetDigitizer(run_period);
334 fRun->AddTask(fNdetDigit);
335
336 // // ECAL-Digitizer (for period < 8)
337 // BmnEcalDigitizer* ecalDigit = new BmnEcalDigitizer();
338 // fRun->AddTask(ecalDigit);
339
340 fRun->SetStoreTraj(saveGeoInfo);
341 fRun->Init();
342 magField->Print("");
343
344 // Cuts for Trajectories Visualization (TGeoManager only)
345 if (saveGeoInfo) {
346 FairTrajFilter* trajFilter = FairTrajFilter::Instance();
347 // Set cuts for storing the trajectories
348 trajFilter->SetStepSizeCut(0.1); // [cm]
349 trajFilter->SetVertexCut(-200., -200., -200., 200., 200.,
350 1100.); // (vxMin, vyMin, vzMin, vxMax, vyMax, vzMax)
351 trajFilter->SetMomentumCutP(50e-3); // p_lab > 50 MeV
352 // trajFilter->SetEnergyCut(0., 60.); // 0 < Etot < 60 GeV
353 trajFilter->SetStorePrimaries(kTRUE);
354 trajFilter->SetStoreSecondaries(kTRUE); // kFALSE
355 }
356
357 // Fill the Parameter containers for this run
358 FairRuntimeDb* rtdb = fRun->GetRuntimeDb();
359 Bool_t kParameterMerged = kTRUE;
360 FairParRootFileIo* output = new FairParRootFileIo(kParameterMerged);
361 // AZ output->open(parFile.Data());
362 output->open(gFile);
363 rtdb->setOutput(output);
364
365 // the description keeps the full geometry tag: the setup tag and the XML customization file (if any) after ';'
366 TString geoDescription = geometryTag;
367 if (!geoLocalSettings.IsNull())
368 geoDescription += ";" + geoLocalSettings;
369 rtdb->getContainer("FairGeoParSet")->setDescription(geoDescription.Data());
370 rtdb->saveOutput();
371 rtdb->print();
372
373 // Transport nEvents
374 fRun->Run(nEvents);
375
376 // gGeoManager->CheckOverlaps(0.0001);
377 // gGeoManager->PrintOverlaps();
378 if (saveGeoInfo) {
379 fRun->CreateGeometryFile("full_geometry.root"); // save the full setup geometry to the additional file
380 }
381
382 if ((generatorName == QGSM) || (generatorName == DCMQGSM)) {
383 TString Pdg_table_name = TString::Format("%s%s%c%s", gSystem->BaseName(genFile.Data()), ".g",
384 (fRun->GetName())[6], ".pdg_table.dat");
385 (TDatabasePDG::Instance())->WritePDGTable(Pdg_table_name.Data());
386 }
387 delete fRun;
388 delete magField;
389
390 timer.Stop();
391 Double_t rtime = timer.RealTime(), ctime = timer.CpuTime();
392 printf("RealTime=%f seconds, CpuTime=%f seconds\n", rtime, ctime);
393 cout << "Macro finished successfully." << endl; // marker of successfully execution for software testing systems
394}
#define M_PI
bool Bool_t
int Int_t
Int_t gDebug
unsigned int UInt_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
#define gFile
R__EXTERN TRandom * gRandom
R__EXTERN TSystem * gSystem
virtual void Print(Option_t *) const
Screen output.
static double GetMagneticFieldByEnergy(const TString &beam, double energy)
static int CreateDirectoryTree(TString &fileName, int iVerbose=0, EAccessMode mode=kWritePermission)
static Int_t ParseGeometryTag(TString &geometry_tag, TString &local_settings)
static Int_t ParseFileName(const TString &file_name, TString &beam, TString &target, Double_t &energy)
static int CheckFileExist(TString &fileName, int iVerbose=0, EAccessMode mode=kFileExists)
void SetNoise(Double_t sigma, Double_t thresh)
void SetUseRealEffects(Bool_t opt=kTRUE)
static BmnGemStripMedium & GetInstance()
Bool_t SetCurrentConfiguration(BmnGemStripMediumConfiguration::MEDIUM medium)
static void SetUseANNGeneration(Bool_t use)
void SetNoise(Double_t sigma, Double_t thresh)
void SetUseRealEffects(Bool_t opt=kTRUE)
void SetUseRealEffects(Bool_t opt=kTRUE)
void SetNoise(Double_t sigma, Double_t thresh)
GeoSetup class.
Definition GeoSetup.h:40
FairField * GetMagneticField(double scale=-1)
Get magnetic field of the current setup geometry.
Definition GeoSetup.cxx:877
string GetLastApprovedSetupTag(string_view tag_prefix)
Get tag for the last approved setup corresponding to the pattern.
Definition GeoSetup.cxx:122
int LoadSetupToFairRunSim(string_view setupTag, const char *localSettings=nullptr)
Load selected geometry setup from the Local or Central (defined by url) Geometry Database and add it ...
Definition GeoSetup.cxx:643
Bool_t SkipEvents(Int_t count)
static Int_t GetNumPHSDEvents(const char *filename, int iVerbose=2)
static Int_t GetNumQGSMEvents(const char *fileName, int iVerbose=2)
static Int_t GetNumURQMDEvents(const char *fileName, int iVerbose=2)
static Int_t GetNumDCMSMMEvents(const char *fileName, int iVerbose=2)
Bool_t SkipEvents(Int_t nSkip)
Bool_t SkipEvents(Int_t n)
Skip n events, return kTRUE if successful.
Bool_t SkipEvents(Int_t count)
static TDatabasePDG * Instance()
Bool_t MatchB(const TString &s, const TString &mods="", Int_t start=0, Int_t nMaxMatch=10)
Int_t Substitute(TString &s, const TString &replace, const TString &mods="", Int_t start=0, Int_t nMatchMax=10)
Double_t RealTime()
void Start(Bool_t reset=kTRUE)
Double_t CpuTime()
void Stop()
Int_t Atoi() const
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
const char * Data() const
TString & Chop()
Bool_t IsNull() const
static TString Format(const char *fmt,...)
enumGenerators
@ PART
@ QGSM
@ UNIGEN
@ HSD
@ URQMD
@ ION
@ DCMSMM
Definition run_sim_bmn.C:13
@ DCMQGSM