BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
run_sim_bmn.cxx
Go to the documentation of this file.
1#if !defined(__CLING__) || defined(__MAKECLING__)
2// ROOT includes
3#include "TApplication.h"
4#include "TDatabasePDG.h"
5#include "TGeoManager.h"
6#include "TKey.h"
7#include "TPRegexp.h"
8#include "TROOT.h"
9#include "TRandom.h"
10#include "TStopwatch.h"
11#include "TString.h"
12#include "TSystem.h"
13#include "TVirtualMC.h"
14
15// FairRoot includes
16#include "FairBoxGenerator.h"
17#include "FairCave.h"
18#include "FairDetector.h"
19#include "FairIonGenerator.h"
20#include "FairMagnet.h"
21#include "FairModule.h"
22#include "FairParRootFileIo.h"
23#include "FairParticleGenerator.h"
24#include "FairPipe.h"
25#include "FairPrimaryGenerator.h"
26#include "FairRootFileSink.h"
27#include "FairRunSim.h"
28#include "FairRuntimeDb.h"
29#include "FairTarget.h"
30#include "FairTrajFilter.h"
31
32// BmnRoot includes
33#include "BmnBd.h"
34#include "BmnBdDigitizer.h"
35#include "BmnCSC.h"
36#include "BmnCSCConfiguration.h"
37#include "BmnCSCDigitizer.h"
38#include "BmnDch.h"
39#include "BmnEcal.h"
40#include "BmnEcalDigitizer.h"
41#include "BmnFD.h"
42#include "BmnFHCal.h"
43#include "BmnFHCalDigitizer.h"
44#include "BmnFieldConst.h"
45#include "BmnFieldMap.h"
46#include "BmnFieldPar.h"
47#include "BmnFunctionSet.h"
48#include "BmnGemStripDigitizer.h"
49#include "BmnGemStripMedium.h"
50#include "BmnHodo.h"
51#include "BmnHodoDigitizer.h"
52#include "BmnMwpc.h"
53#include "BmnNdet.h"
54#include "BmnNdetDigitizer.h"
55#include "BmnNewFieldMap.h"
56#include "BmnScWall.h"
57#include "BmnScWallDigitizer.h"
58// #include "BmnVacuumWallDigitizer.h"
59#include "BmnSiBT.h"
60#include "BmnSiBTConfiguration.h"
61#include "BmnSiBTDigitizer.h"
62#include "BmnSiMD.h"
63#include "BmnSiMDDigitizer.h"
64#include "BmnSiProfDigitizer.h"
65#include "BmnSilicon.h"
66#include "BmnSiliconDigitizer.h"
67#include "BmnTOF.h"
68#include "BmnTOF1.h"
69#include "BmnTOF701.h"
70#include "BmnVacWall.h"
71#include "BmnZdc.h"
72#include "BmnZdcDigitizer.h"
73#include "CbmStack.h"
74#include "CbmSts.h"
75#include "MpdDCMSMMGenerator.h"
76#include "MpdGetNumEvents.h"
77#include "MpdLAQGSMGenerator.h"
78#include "MpdPHSDGenerator.h"
79#include "MpdUnigenGenerator.h"
80#include "MpdUrqmdGenerator.h"
81#include "UniRun.h"
82
83// GEANT3 and 4 includes
84#include "TG4RunConfiguration.h"
85#include "TGeant4.h"
86#include "TPythia6Decayer.h"
87#include "TVirtualMC.h"
88// #include "TGeant3.h"
89// #include "TGeant3TGeo.h"
90
92// #include "../../gconfig/g3Config.C"
94
95// C++ includes
96#include <iostream>
97using namespace std;
98#endif
99
100R__ADD_INCLUDE_PATH($VMCWORKDIR)
101#include "../run/geometry_run/geometry_run8.C"
102
104{
105 Config();
106 SetCuts();
107}
109{
110 Config();
111}
112
113#define GEANT4 // Choose: GEANT3 GEANT4
114// enumeration of generator names corresponding input files
127
128// genFile - input file with generator data, if needed
129// simFile - output file with MC data, default: bmnsim.root
130// nStartEvent - start event in the input generator file to begin transporting, default: 0
131// nEvents - number of events to transport
132// generatorName - generator name for the input file (enumeration above)
133// useRealEffects - whether we use realistic effects at simulation (Lorentz, misalignment)
134// saveGeoInfo - whether add 'GeoTracks' to simFile for Event Display and create "full_geometry.root" with full setup
135// geometry
136void run_sim_bmn(TString genFile = "DCMSMM_XeCsI_3.9AGeV_mb_10k_142.r12",
137 TString simFile = "$VMCWORKDIR/macro/run/bmnsim.root",
138 Int_t nStartEvent = 0,
139 Int_t nEvents = 10,
140 enumGenerators generatorName = BOX,
141 Bool_t useRealEffects = kTRUE,
142 Bool_t saveGeoInfo = kFALSE)
143{
144 gDebug = 0; // ROOT debug option
145 // Verbosity level (0 = summary only, 1 = event-level, 2 = track-level, 3 = full debug)
146 Int_t iVerbose = 0;
147 // Log level for LOG(severity): "fatal", "error", "alarm", "important", "warn", "state", "info", "detail", "debug",
148 // "debug[1-4]", "trace", "nolog"
149 FairLogger::GetLogger()->SetLogScreenLevel("info");
150
151 TStopwatch timer;
152 timer.Start();
153
154 // ----- Create simulation run ----------------------------------------
155 FairRunSim* fRun = new FairRunSim();
156 fRun->SetUseFairLinks(kTRUE);
157
158 // Choose the Geant Navigation System
159#ifdef GEANT4
160 fRun->SetName("TGeant4");
161#else
162 fRun->SetName("TGeant3");
163#endif
164
165 geometry(fRun); // load BM@N geometry
166
167 // Use the experiment specific MC Event header instead of the default one
168 // This one stores additional information about the reaction plane
169 // MpdMCEventHeader* mcHeader = new MpdMCEventHeader();
170 // fRun->SetMCEventHeader(mcHeader);
171
172 // Create and Set Event Generator
173 FairPrimaryGenerator* primGen = new FairPrimaryGenerator();
174 fRun->SetGenerator(primGen);
175
176 // Smearing of beam interaction point, if needed, and primary vertex position
177 // DO NOT do it in corresponding gen. sections to avoid incorrect summation!!!
178 // parameters for period 8
179 primGen->SetBeam(0.4376, 0.1239, 0.4537, 0.6925); // (beamX0, beamY0, beamSigmaX, beamSigmaY)
180 primGen->SetBeamAngle(0.011, 0.0, 0.0, 0.0); // (beamAngleX0, beamAngleY0, beamAngleSigmaX, beamAngleSigmaY)
181 primGen->SetTarget(-0.01942, 0.175); // (targetZ, targetDz)
182 primGen->SmearVertexZ(kTRUE);
183 primGen->SmearGausVertexXY(kTRUE);
184 gRandom->SetSeed(0);
185
186 switch (generatorName) {
187 case UNIGEN: {
188 if (!BmnFunctionSet::CheckFileExist(genFile, 1))
189 exit(-1);
190
191 auto* unigen = new MpdUnigenGenerator(genFile);
192 unigen->RegisterIons();
193 primGen->AddGenerator(unigen);
194 unigen->SetEventPlane(-M_PI, M_PI);
195 auto n_events_in_tree = unigen->GetNEntries();
196 if (nStartEvent >= n_events_in_tree) {
197 cout << "You are trying to specify the event out reach of current tree" << generatorName << endl;
198 exit(-3);
199 }
200 auto n_avail_events = n_events_in_tree - nStartEvent - 1;
201 if (nEvents <= 0)
202 nEvents = n_avail_events;
203 else
204 nEvents = std::min<int>(n_avail_events, nEvents);
205 cout << nEvents << " are availiable and will be processed" << endl;
206 if (nStartEvent > 0)
207 unigen->SkipEvents(nStartEvent);
208 break;
209 }
210 // ------- UrQMD Generator
211 case URQMD: {
212 if (!BmnFunctionSet::CheckFileExist(genFile, 1))
213 exit(-1);
214
215 MpdUrqmdGenerator* urqmdGen = new MpdUrqmdGenerator(genFile);
216 // urqmdGen->SetEventPlane(0., 360.);
217 primGen->AddGenerator(urqmdGen);
218 if (nStartEvent > 0)
219 urqmdGen->SkipEvents(nStartEvent);
220
221 // if nEvents is equal 0 then all events (start with nStartEvent) of the given file should be processed
222 if (nEvents == 0)
223 nEvents = MpdGetNumEvents::GetNumURQMDEvents(genFile.Data()) - nStartEvent;
224 break;
225 }
226
227 // ------- Particle Generator
228 case PART: {
229 // FairParticleGenerator generates a single particle type (PDG, mult, [GeV] px, py, pz, [cm] vx, vy, vz)
230 FairParticleGenerator* partGen = new FairParticleGenerator(211, 10, 1, 0, 3, 1, 0, 0);
231 primGen->AddGenerator(partGen);
232 break;
233 }
234
235 // ------- Ion Generator
236 case ION: {
237 // Start beam from a far point to check mom. reconstruction procedure (Z, A, q, mult, [GeV] px, py, pz, [cm]
238 // vx, vy, vz)
239 FairIonGenerator* fIongen = new FairIonGenerator(54, 124, 54, 1, 0., 0., 4.65, 0., 0., 0.); // Xe
240 primGen->AddGenerator(fIongen);
241 break;
242 }
243
244 // ------- Box Generator
245 case BOX: {
246 gRandom->SetSeed(0);
247 FairBoxGenerator* boxGen = new FairBoxGenerator(2212, 1); //(PDG code, multiplicity)
248 boxGen->SetPRange(0.2, 5.0); // GeV/c, setPRange vs setPtRange
249 boxGen->SetPhiRange(0, 360); // Azimuth angle range [degree]
250 boxGen->SetThetaRange(0, 40.0); // Polar angle in lab system range [degree]
251 primGen->AddGenerator(boxGen);
252 break;
253 }
254
255 // ------- HSD/PHSD Generator
256 case HSD: {
257 if (!BmnFunctionSet::CheckFileExist(genFile, 1))
258 exit(-1);
259
260 MpdPHSDGenerator* hsdGen = new MpdPHSDGenerator(genFile.Data());
261 // hsdGen->SetPsiRP(0.); // set fixed Reaction Plane angle instead of random
262 primGen->AddGenerator(hsdGen);
263 if (nStartEvent > 0)
264 hsdGen->SkipEvents(nStartEvent);
265
266 // if nEvents is equal 0 then all events (start with nStartEvent) of the given file should be processed
267 if (nEvents == 0)
268 nEvents = MpdGetNumEvents::GetNumPHSDEvents(genFile.Data()) - nStartEvent;
269 break;
270 }
271
272 // ------- LAQGSM/DCM-QGSM Generator
273 case QGSM:
274 case DCMQGSM: {
275
276 if (!BmnFunctionSet::CheckFileExist(genFile, 1))
277 exit(-1);
278
279 MpdLAQGSMGenerator* guGen = new MpdLAQGSMGenerator(genFile.Data(), kFALSE);
280 primGen->AddGenerator(guGen);
281 if (nStartEvent > 0)
282 guGen->SkipEvents(nStartEvent);
283
284 // if nEvents is equal 0 then all events (start with nStartEvent) of the given file should be processed
285 if (nEvents == 0)
286 nEvents = MpdGetNumEvents::GetNumQGSMEvents(genFile.Data()) - nStartEvent;
287 break;
288 }
289 case DCMSMM: {
290
291 if (!BmnFunctionSet::CheckFileExist(genFile, 1))
292 exit(-1);
293
294 MpdDCMSMMGenerator* smmGen = new MpdDCMSMMGenerator(genFile.Data());
295 primGen->AddGenerator(smmGen);
296 if (nStartEvent > 0)
297 smmGen->SkipEvents(nStartEvent);
298
299 // if nEvents is equal 0 then all events (start with nStartEvent) of the given file should be processed
300 if (nEvents == 0)
301 nEvents = MpdGetNumEvents::GetNumDCMSMMEvents(genFile.Data()) - nStartEvent;
302 break;
303 }
304
305 default: {
306 cout << "ERROR: Generator name was not pre-defined: " << generatorName << endl;
307 exit(-3);
308 }
309 } // end of switch (generatorName)
310
311 if (simFile == "")
312 simFile = "$VMCWORKDIR/macro/run/bmnsim.root";
313 // if directory for the output file does not exist, then create
314 if (BmnFunctionSet::CreateDirectoryTree(simFile, 1) < 0)
315 exit(-2);
316 fRun->SetSink(new FairRootFileSink(simFile.Data()));
317 fRun->SetIsMT(false);
318
319 // ----- Create magnetic field ----------------------------------------
320 // To work with old map use the next line:
321 BmnFieldMap* magField = new BmnNewFieldMap("FieldMap_1900_extrap_noPed.root");
322 Double_t fieldScale = 0.929; // 1.861 for 900 A, 0.929 for 1900 A;
323 magField->SetScale(fieldScale);
324 fRun->SetField(magField);
325
326 fRun->SetStoreTraj(kTRUE);
327 fRun->SetRadLenRegister(kFALSE); // radiation length manager
328
329 // ----- Digitizers: converting MC points to detector digits -----------
330
331 // SiBT-Digitizer
333 BmnSiBTDigitizer* sibtDigit = new BmnSiBTDigitizer();
334 sibtDigit->SetCurrentConfig(sibt_config);
335 fRun->AddTask(sibtDigit);
336
337 // SiProf-Digitizer
339 BmnSiProfDigitizer* siprofDigit = new BmnSiProfDigitizer();
340 siprofDigit->SetCurrentConfig(siprof_config);
341 fRun->AddTask(siprofDigit);
342
343 // BD-Digitizer
344 BmnBdDigitizer* bdDigit = new BmnBdDigitizer();
345 fRun->AddTask(bdDigit);
346
347 // SiMD-Digitizer
348 BmnSiMDDigitizer* simdDigit = new BmnSiMDDigitizer();
349 fRun->AddTask(simdDigit);
350
351 // SI-Digitizer
353 BmnSiliconDigitizer* siliconDigit = new BmnSiliconDigitizer();
354 siliconDigit->SetCurrentConfig(si_config);
355 siliconDigit->SetUseRealEffects(useRealEffects);
356 siliconDigit->SetNoise(45.0, 150.0); // AZ-150224
357 fRun->AddTask(siliconDigit);
358
359 // GEM-Digitizer
361 if (useRealEffects)
362 // AZ-150224
363 // BmnGemStripMedium::GetInstance().SetCurrentConfiguration(BmnGemStripMediumConfiguration::ARC4H10_80_20_E_1720_2240_3230_3730_B_0_8T);
367 gemDigit->SetCurrentConfig(gem_config);
368 gemDigit->SetUseRealEffects(useRealEffects);
369 gemDigit->SetNoise(10.0, 25.0); // AZ-150224
370 fRun->AddTask(gemDigit);
371
372 // CSC-Digitizer
374 BmnCSCDigitizer* cscDigit = new BmnCSCDigitizer();
375 cscDigit->SetCurrentConfig(csc_config);
376 fRun->AddTask(cscDigit);
377
378 // // ZDC-Digitizer (for period < 8)
379 // BmnZdcDigitizer* zdcDigit = new BmnZdcDigitizer();
380 // zdcDigit->SetScale(39e3);
381 // zdcDigit->SetThreshold(500.);
382 // fRun->AddTask(zdcDigit);
383
384 // FHCal-Digitizer (for period >= 8)
385 BmnFHCalDigitizer* fhcalDigit = new BmnFHCalDigitizer();
386 fhcalDigit->SetScale(1.0 / 0.0048); // scale. Convert Geant GeV to MIPs
387 fhcalDigit->SetThreshold(0.);
388 fhcalDigit->SetTimeCut(1000.);
389 fhcalDigit->SetSiPM(90000, // [N] N pixels in SiPM
390 40, // [N] MIP to N SiPM pixels
391 0.3, // [MIP] noise level
392 0.0048); // [GeV] energy deposited by 1 MIP in FHCal section
393 fRun->AddTask(fhcalDigit);
394
395 // ScWall-Digitizer
396 BmnScWallDigitizer* fScWallDigit = new BmnScWallDigitizer();
397 fScWallDigit->SetScale(1.);
398 fScWallDigit->SetThreshold(0.);
399 fScWallDigit->SetGeV2MIP(0.0021); // 2.1 MeV from 1 MIP in 1cm plastic
400 fScWallDigit->SetMIP2Pix(55); // 15 pix for 1 MIP in SiPM
401 fScWallDigit->SetMIPNoise(0.1); // electronic noise in MIP scale
402 fRun->AddTask(fScWallDigit);
403
404 // Hodo-Digitizer
405 BmnHodoDigitizer* fHodoDigit = new BmnHodoDigitizer();
406 fHodoDigit->SetScale(1256); // [Z^2/GeV] set Xe peak to 54*54
407 fHodoDigit->SetThreshold(16.); // [Z^2] we see noise below this in data
408 fHodoDigit->SetEnergyResolutionTerms(0.085, 0.0); // stochastic [sqrt(GeV)] and constant [] terms
409 fRun->AddTask(fHodoDigit);
410
411 // Ndet-Digitizer
412 BmnNdetDigitizer* fNdetDigit = new BmnNdetDigitizer();
413 fNdetDigit->SetTofCut(100.); // [ns] cut to remove parasitic late tracks
414 fNdetDigit->SetThreshold(0.0025); // [GeV] 0.5 MIP * 5 MeV for 25 mm plastic scint
415 fNdetDigit->SetSiPM(165, // [N] MIP to N SiPM pixels (by LPI test march 2024)
416 0.3, // [MIP] noise level
417 0.005); // [GeV] MIP to GeV conversion factor = 5 MeV for 25 mm plastic scint
418 fRun->AddTask(fNdetDigit);
419
420 // // ECAL-Digitizer (for period < 8)
421 // BmnEcalDigitizer* ecalDigit = new BmnEcalDigitizer();
422 // fRun->AddTask(ecalDigit);
423
424 fRun->SetStoreTraj(saveGeoInfo);
425 fRun->Init();
426 magField->Print("");
427
428 // Cuts for Trajectories Visualization (TGeoManager only)
429 if (saveGeoInfo) {
430 FairTrajFilter* trajFilter = FairTrajFilter::Instance();
431 // Set cuts for storing the trajectories
432 trajFilter->SetStepSizeCut(0.1); // [cm]
433 trajFilter->SetVertexCut(-200., -200., -200., 200., 200.,
434 1100.); // (vxMin, vyMin, vzMin, vxMax, vyMax, vzMax)
435 trajFilter->SetMomentumCutP(50e-3); // p_lab > 50 MeV
436 // trajFilter->SetEnergyCut(0., 60.); // 0 < Etot < 60 GeV
437 trajFilter->SetStorePrimaries(kTRUE);
438 trajFilter->SetStoreSecondaries(kTRUE); // kFALSE
439 }
440
441 // Fill the Parameter containers for this run
442 FairRuntimeDb* rtdb = fRun->GetRuntimeDb();
443 Bool_t kParameterMerged = kTRUE;
444 FairParRootFileIo* output = new FairParRootFileIo(kParameterMerged);
445 // AZ output->open(parFile.Data());
446 output->open(gFile);
447 rtdb->setOutput(output);
448
449 rtdb->saveOutput();
450 rtdb->print();
451
452 // Transport nEvents
453 fRun->Run(nEvents);
454
455 gGeoManager->CheckOverlaps(0.0001);
456 gGeoManager->PrintOverlaps();
457 if (saveGeoInfo) {
458 fRun->CreateGeometryFile("full_geometry.root"); // save the full setup geometry to the additional file
459 }
460
461 if ((generatorName == QGSM) || (generatorName == DCMQGSM)) {
462 TString Pdg_table_name = TString::Format("%s%s%c%s", gSystem->BaseName(genFile.Data()), ".g",
463 (fRun->GetName())[6], ".pdg_table.dat");
464 (TDatabasePDG::Instance())->WritePDGTable(Pdg_table_name.Data());
465 }
466 delete fRun;
467 delete magField;
468
469 timer.Stop();
470 Double_t rtime = timer.RealTime(), ctime = timer.CpuTime();
471 printf("RealTime=%f seconds, CpuTime=%f seconds\n", rtime, ctime);
472 cout << "Macro finished successfully." << endl; // marker of successfully execution for software testing systems
473}
474
475int main(int argc, char** arg)
476{
477 run_sim_bmn();
478}
#define M_PI
bool Bool_t
int Int_t
Int_t gDebug
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
#define R__ADD_INCLUDE_PATH(PATH)
#define gFile
R__EXTERN TGeoManager * gGeoManager
R__EXTERN TRandom * gRandom
R__EXTERN TSystem * gSystem
void SetCurrentConfig(BmnCSCConfiguration::CSC_CONFIG config)
void SetThreshold(double setValue)
void SetSiPM(int Npixels, int pixPerMIP, double noiseMIP, double gevPerMIP)
void SetTimeCut(double setValue)
void SetScale(double scale)
void SetScale(Double_t factor)
Set a global field scaling factor.
Definition BmnFieldMap.h:55
virtual void Print(Option_t *) const
Screen output.
static int CreateDirectoryTree(TString &fileName, int iVerbose=0, EAccessMode mode=kWritePermission)
static int CheckFileExist(TString &fileName, int iVerbose=0, EAccessMode mode=kFileExists)
void SetCurrentConfig(BmnGemStripConfiguration::GEM_CONFIG config)
void SetNoise(Double_t sigma, Double_t thresh)
void SetUseRealEffects(Bool_t opt=kTRUE)
static BmnGemStripMedium & GetInstance()
Bool_t SetCurrentConfiguration(BmnGemStripMediumConfiguration::MEDIUM medium)
void SetThreshold(double threshold)
void SetScale(double scale)
void SetSiPM(int Npixels, int pixPerMIP, double noiseMIP, double gevPerMIP)
void SetThreshold(double setValue)
Field Map does not have any symmetries w.r.t coordinate axises.
void SetThreshold(double setValue)
void SetScale(double scale)
void SetCurrentConfig(BmnSiBTConfiguration::SiBT_CONFIG config)
void SetCurrentConfig(BmnSiProfConfiguration::SiProf_CONFIG config)
void SetCurrentConfig(BmnSiliconConfiguration::SILICON_CONFIG config)
void SetNoise(Double_t sigma, Double_t thresh)
void SetUseRealEffects(Bool_t opt=kTRUE)
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()
Double_t RealTime()
void Start(Bool_t reset=kTRUE)
Double_t CpuTime()
void Stop()
const char * Data() const
static TString Format(const char *fmt,...)
void SetCuts()
Configuration macro for setting common cuts and processes for G3, G4 and Fluka specific cuts and proc...
Definition SetCuts.C:6
enumGenerators
@ PART
@ QGSM
@ UNIGEN
@ HSD
@ URQMD
@ ION
@ DCMSMM
@ DCMQGSM
void geant4_setup()
void geant3_setup()
void run_sim_bmn(TString genFile="DCMSMM_XeCsI_3.9AGeV_mb_10k_142.r12", TString simFile="$VMCWORKDIR/macro/run/bmnsim.root", Int_t nStartEvent=0, Int_t nEvents=10, enumGenerators generatorName=BOX, Bool_t useRealEffects=kTRUE, Bool_t saveGeoInfo=kFALSE)
Definition json.hpp:4446
int main(void)
Definition test_FC.cpp:33