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.
1R__ADD_INCLUDE_PATH($VMCWORKDIR)
2#include "macro/detectors/fullHGND/geometry_run.C"
3
4#define GEANT4 // Choose: GEANT3 GEANT4
5// enumeration of generator names corresponding input files
18
19// inFile - input file with generator data, if needed
20// outFile - output file with MC data, default: bmnsim.root
21// nStartEvent - start event in the input generator file to begin transporting, default: 0
22// nEvents - number of events to transport
23// generatorName - generator name for the input file (enumeration above)
24// useRealEffects - whether we use realistic effects at simulation (Lorentz, misalignment)
25// saveGeoInfo - whether add 'GeoTracks' to outFile for Event Display and create "full_geometry.root" with full setup
26// geometry
27void run_sim_bmn(TString inFile = "DCMSMM_XeCsI_3.9AGeV_mb_10k_142.r12",
28 TString outFile = "$VMCWORKDIR/macro/run/bmnsim.root",
29 Int_t nStartEvent = 0,
30 Int_t nEvents = 10,
31 enumGenerators generatorName = BOX,
32 Bool_t useRealEffects = kTRUE,
33 Bool_t saveGeoInfo = kFALSE)
34{
35 gDebug = 0;
36 TStopwatch timer;
37 timer.Start();
38
39 // ----- Create simulation run ----------------------------------------
40 FairRunSim* fRun = new FairRunSim();
41
42 // Choose the Geant Navigation System
43#ifdef GEANT4
44 fRun->SetName("TGeant4");
45#else
46 fRun->SetName("TGeant3");
47#endif
48
49 geometry(fRun); // load BM@N geometry
50
51 // Use the experiment specific MC Event header instead of the default one
52 // This one stores additional information about the reaction plane
53 // MpdMCEventHeader* mcHeader = new MpdMCEventHeader();
54 // fRun->SetMCEventHeader(mcHeader);
55
56 // Create and Set Event Generator
57 FairPrimaryGenerator* primGen = new FairPrimaryGenerator();
58 fRun->SetGenerator(primGen);
59
60 // Smearing of beam interaction point, if needed, and primary vertex position
61 // DO NOT do it in corresponding gen. sections to avoid incorrect summation!!!
62 // parameters for period 8
63 primGen->SetBeam(0.73, -0.23, 0.4, 0.4); // (beamX0, beamY0, beamSigmaX, beamSigmaY)
64 primGen->SetBeamAngle(0.011, 0.0, 0.0, 0.0); // (beamAngleX0, beamAngleY0, beamAngleSigmaX, beamAngleSigmaY)
65 primGen->SetTarget(0.0875, 0.175); // (targetZ, targetDz)
66 primGen->SmearVertexZ(kTRUE);
67 primGen->SmearGausVertexXY(kTRUE);
68 gRandom->SetSeed(0);
69
70 switch (generatorName) {
71 case UNIGEN: {
72 if (!BmnFunctionSet::CheckFileExist(inFile, 1))
73 exit(-1);
74
75 auto* unigen = new MpdUnigenGenerator(inFile);
76 unigen->RegisterIons();
77 primGen->AddGenerator(unigen);
78 unigen->SetEventPlane(-M_PI, M_PI);
79 auto n_events_in_tree = unigen->GetNEntries();
80 if (nStartEvent >= n_events_in_tree) {
81 cout << "You are trying to specify the event out reach of current tree" << generatorName << endl;
82 exit(-3);
83 }
84 // auto n_avail_events = n_events_in_tree - nStartEvent - 1;
85 auto n_avail_events = n_events_in_tree - nStartEvent;
86 if (nEvents <= 0)
87 nEvents = n_avail_events;
88 else
89 nEvents = std::min<int>(n_avail_events, nEvents);
90 cout << nEvents << " are availiable and will be processed" << endl;
91 if (nStartEvent > 0)
92 unigen->SkipEvents(nStartEvent);
93 break;
94 }
95 // ------- UrQMD Generator
96 case URQMD: {
97 if (!BmnFunctionSet::CheckFileExist(inFile, 1))
98 exit(-1);
99
100 MpdUrqmdGenerator* urqmdGen = new MpdUrqmdGenerator(inFile);
101 // urqmdGen->SetEventPlane(0., 360.);
102 primGen->AddGenerator(urqmdGen);
103 if (nStartEvent > 0)
104 urqmdGen->SkipEvents(nStartEvent);
105
106 // if nEvents is equal 0 then all events (start with nStartEvent) of the given file should be processed
107 if (nEvents == 0)
108 nEvents = MpdGetNumEvents::GetNumURQMDEvents(inFile.Data()) - nStartEvent;
109 break;
110 }
111
112 // ------- Particle Generator
113 case PART: {
114 // FairParticleGenerator generates a single particle type (PDG, mult, [GeV] px, py, pz, [cm] vx, vy, vz)
115 FairParticleGenerator* partGen = new FairParticleGenerator(211, 10, 1, 0, 3, 1, 0, 0);
116 primGen->AddGenerator(partGen);
117 break;
118 }
119
120 // ------- Ion Generator
121 case ION: {
122 // Start beam from a far point to check mom. reconstruction procedure (Z, A, q, mult, [GeV] px, py, pz, [cm]
123 // vx, vy, vz)
124 FairIonGenerator* fIongen = new FairIonGenerator(54, 124, 54, 1, 0., 0., 4.65, 0., 0., 0.); // Xe
125 primGen->AddGenerator(fIongen);
126 break;
127 }
128
129 // ------- Box Generator
130 case BOX: {
131 gRandom->SetSeed(0);
132 FairBoxGenerator* boxGen = new FairBoxGenerator(2212, 1); //(PDG code, multiplicity)
133 boxGen->SetPRange(0.2, 5.0); // GeV/c, setPRange vs setPtRange
134 boxGen->SetPhiRange(0, 360); // Azimuth angle range [degree]
135 boxGen->SetThetaRange(0, 40.0); // Polar angle in lab system range [degree]
136 primGen->AddGenerator(boxGen);
137 break;
138 }
139
140 // ------- HSD/PHSD Generator
141 case HSD: {
142 if (!BmnFunctionSet::CheckFileExist(inFile, 1))
143 exit(-1);
144
145 MpdPHSDGenerator* hsdGen = new MpdPHSDGenerator(inFile.Data());
146 // hsdGen->SetPsiRP(0.); // set fixed Reaction Plane angle instead of random
147 primGen->AddGenerator(hsdGen);
148 if (nStartEvent > 0)
149 hsdGen->SkipEvents(nStartEvent);
150
151 // if nEvents is equal 0 then all events (start with nStartEvent) of the given file should be processed
152 if (nEvents == 0)
153 nEvents = MpdGetNumEvents::GetNumPHSDEvents(inFile.Data()) - nStartEvent;
154 break;
155 }
156
157 // ------- LAQGSM/DCM-QGSM Generator
158 case QGSM:
159 case DCMQGSM: {
160
161 if (!BmnFunctionSet::CheckFileExist(inFile, 1))
162 exit(-1);
163
164 MpdLAQGSMGenerator* guGen = new MpdLAQGSMGenerator(inFile.Data(), kFALSE);
165 primGen->AddGenerator(guGen);
166 if (nStartEvent > 0)
167 guGen->SkipEvents(nStartEvent);
168
169 // if nEvents is equal 0 then all events (start with nStartEvent) of the given file should be processed
170 if (nEvents == 0)
171 nEvents = MpdGetNumEvents::GetNumQGSMEvents(inFile.Data()) - nStartEvent;
172 break;
173 }
174 case DCMSMM: {
175
176 if (!BmnFunctionSet::CheckFileExist(inFile, 1))
177 exit(-1);
178
179 MpdDCMSMMGenerator* smmGen = new MpdDCMSMMGenerator(inFile.Data());
180 primGen->AddGenerator(smmGen);
181 if (nStartEvent > 0)
182 smmGen->SkipEvents(nStartEvent);
183
184 // if nEvents is equal 0 then all events (start with nStartEvent) of the given file should be processed
185 if (nEvents == 0)
186 nEvents = MpdGetNumEvents::GetNumDCMSMMEvents(inFile.Data()) - nStartEvent;
187 break;
188 }
189
190 default: {
191 cout << "ERROR: Generator name was not pre-defined: " << generatorName << endl;
192 exit(-3);
193 }
194 } // end of switch (generatorName)
195
196 // if directory for the output file does not exist, then create
197 if (BmnFunctionSet::CreateDirectoryTree(outFile, 1) < 0)
198 exit(-2);
199 fRun->SetSink(new FairRootFileSink(outFile.Data()));
200 fRun->SetIsMT(false);
201
202 // ----- Create magnetic field ----------------------------------------
203 // To work with old map use the next line:
204 BmnFieldMap* magField = new BmnNewFieldMap("FieldMap_1900_extrap_noPed.root");
205 Double_t fieldScale = 0.929; // 1.861 for 900 A, 0.929 for 1900 A;
206 magField->SetScale(fieldScale);
207 fRun->SetField(magField);
208
209 fRun->SetStoreTraj(kTRUE);
210 fRun->SetRadLenRegister(kFALSE); // radiation length manager
211
212 // ----- Digitizers: converting MC points to detector digits -----------
213
214 // SiBT-Digitizer
216 BmnSiBTDigitizer* sibtDigit = new BmnSiBTDigitizer();
217 sibtDigit->SetCurrentConfig(sibt_config);
218 fRun->AddTask(sibtDigit);
219
220 // SiProf-Digitizer
222 BmnSiProfDigitizer* siprofDigit = new BmnSiProfDigitizer();
223 siprofDigit->SetCurrentConfig(siprof_config);
224 fRun->AddTask(siprofDigit);
225
226 // BD-Digitizer
227 BmnBdDigitizer* bdDigit = new BmnBdDigitizer();
228 fRun->AddTask(bdDigit);
229
230 // SiMD-Digitizer
231 BmnSiMDDigitizer* simdDigit = new BmnSiMDDigitizer();
232 fRun->AddTask(simdDigit);
233
234 // SI-Digitizer
236 BmnSiliconDigitizer* siliconDigit = new BmnSiliconDigitizer();
237 siliconDigit->SetCurrentConfig(si_config);
238 siliconDigit->SetUseRealEffects(useRealEffects);
239 siliconDigit->SetNoise(45.0, 150.0); // AZ-150224
240 fRun->AddTask(siliconDigit);
241
242 // GEM-Digitizer
244 if (useRealEffects)
245 // AZ-150224
246 // BmnGemStripMedium::GetInstance().SetCurrentConfiguration(BmnGemStripMediumConfiguration::ARC4H10_80_20_E_1720_2240_3230_3730_B_0_8T);
250 gemDigit->SetCurrentConfig(gem_config);
251 gemDigit->SetUseRealEffects(useRealEffects);
252 gemDigit->SetNoise(10.0, 25.0); // AZ-150224
253 fRun->AddTask(gemDigit);
254
255 // CSC-Digitizer
257 BmnCSCDigitizer* cscDigit = new BmnCSCDigitizer();
258 cscDigit->SetCurrentConfig(csc_config);
259 fRun->AddTask(cscDigit);
260
261 // // ZDC-Digitizer (for period < 8)
262 // BmnZdcDigitizer* zdcDigit = new BmnZdcDigitizer();
263 // zdcDigit->SetScale(39e3);
264 // zdcDigit->SetThreshold(500.);
265 // fRun->AddTask(zdcDigit);
266
267 // FHCal-Digitizer (for period >= 8)
268 BmnFHCalDigitizer* fhcalDigit = new BmnFHCalDigitizer();
269 fhcalDigit->SetGeV2MIP(0.005); // 5 MeV from 1 MIP in FHCal section
270 fhcalDigit->SetMIP2Pix(15); // 15 pix for 1 MIP in SiPM
271 fhcalDigit->SetScale(1.0); // scale to convert visible to full energy
272 fhcalDigit->SetMIPNoise(0.2); // electronic noise in MIP scale
273 fhcalDigit->SetThreshold(0.5 * 0.005 * 1.0); // 0.5 MIP noise cut
274 fRun->AddTask(fhcalDigit);
275
276 // ScWall-Digitizer
277 BmnScWallDigitizer* fScWallDigit = new BmnScWallDigitizer();
278 fScWallDigit->SetScale(1.);
279 fScWallDigit->SetThreshold(0.);
280 fScWallDigit->SetGeV2MIP(0.0021); // 2.1 MeV from 1 MIP in 1cm plastic
281 // fScWallDigit->SetMIP2Pix(15); // 15 pix for 1 MIP in SiPM
282 fScWallDigit->SetMIP2Pix(55); // 55 pix for 1 MIP in SiPM
283 fScWallDigit->SetMIPNoise(0.1); // electronic noise in MIP scale
284 fRun->AddTask(fScWallDigit);
285
286 // Hodo-Digitizer
287 BmnHodoDigitizer* fHodoDigit = new BmnHodoDigitizer();
288 fHodoDigit->SetScale(1.);
289 fHodoDigit->SetThreshold(0.);
290 fHodoDigit->SetGeV2MIP(0.00083); // 0.83 MeV from 1 MIP in 4mm plastic
291 fHodoDigit->SetMIP2Pix(15); // 15 pix for 1 MIP in SiPM
292 fHodoDigit->SetMIPNoise(0.1); // electronic noise in MIP scale
293 fRun->AddTask(fHodoDigit);
294
295 // Ndet-Digitizer
296 BmnNdetDigitizer* fNdetDigit = new BmnNdetDigitizer();
297 fNdetDigit->SetTofCut(100.); // [ns] cut to remove parasitic late tracks
298 fNdetDigit->SetThreshold(0.0025); // [GeV] 0.5 MIP * 5 MeV for 25 mm plastic scint
299 fNdetDigit->SetSiPM(165, // [N] MIP to N SiPM pixels (by LPI test march 2024)
300 0.3, // [MIP] noise level
301 0.005); // [GeV] MIP to GeV conversion factor = 5 MeV for 25 mm plastic scint
302 fRun->AddTask(fNdetDigit);
303
304 // VacuumWall-Digitizer
305 BmnVacuumWallDigitizer* fVacWallDigit = new BmnVacuumWallDigitizer();
306 fRun->AddTask(fVacWallDigit);
307
308 // // ECAL-Digitizer (for period < 8)
309 // BmnEcalDigitizer* ecalDigit = new BmnEcalDigitizer();
310 // fRun->AddTask(ecalDigit);
311
312 fRun->SetStoreTraj(saveGeoInfo);
313 fRun->Init();
314 magField->Print("");
315
316 // Cuts for Trajectories Visualization (TGeoManager only)
317 if (saveGeoInfo) {
318 FairTrajFilter* trajFilter = FairTrajFilter::Instance();
319 // Set cuts for storing the trajectories
320 trajFilter->SetStepSizeCut(0.1); // [cm]
321 trajFilter->SetVertexCut(-200., -200., -200., 200., 200.,
322 1100.); // (vxMin, vyMin, vzMin, vxMax, vyMax, vzMax)
323 trajFilter->SetMomentumCutP(50e-3); // p_lab > 50 MeV
324 // trajFilter->SetEnergyCut(0., 60.); // 0 < Etot < 60 GeV
325 trajFilter->SetStorePrimaries(kTRUE);
326 trajFilter->SetStoreSecondaries(kTRUE); // kFALSE
327 }
328
329 // Fill the Parameter containers for this run
330 FairRuntimeDb* rtdb = fRun->GetRuntimeDb();
331 Bool_t kParameterMerged = kTRUE;
332 FairParRootFileIo* output = new FairParRootFileIo(kParameterMerged);
333 // AZ output->open(parFile.Data());
334 output->open(gFile);
335 rtdb->setOutput(output);
336
337 rtdb->saveOutput();
338 rtdb->print();
339
340 // Transport nEvents
341 fRun->Run(nEvents);
342
343 fRun->CreateGeometryFile("full_geometry.root"); // save the full setup geometry to the additional file
344 if (saveGeoInfo) {
345 gGeoManager->CheckOverlaps(0.0001);
346 gGeoManager->PrintOverlaps();
347 // fRun->CreateGeometryFile("full_geometry.root"); // save the full setup geometry to the additional file
348 }
349
350 if ((generatorName == QGSM) || (generatorName == DCMQGSM)) {
351 TString Pdg_table_name =
352 TString::Format("%s%s%c%s", gSystem->BaseName(inFile.Data()), ".g", (fRun->GetName())[6], ".pdg_table.dat");
353 (TDatabasePDG::Instance())->WritePDGTable(Pdg_table_name.Data());
354 }
355 delete fRun;
356 delete magField;
357
358 timer.Stop();
359 Double_t rtime = timer.RealTime(), ctime = timer.CpuTime();
360 printf("RealTime=%f seconds, CpuTime=%f seconds\n", rtime, ctime);
361 cout << "Macro finished successfully." << endl; // marker of successfully execution for software testing systems
362}
#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 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,...)
enumGenerators
@ PART
@ QGSM
@ UNIGEN
@ HSD
@ URQMD
@ ION
@ DCMSMM
Definition run_sim_bmn.C:6
@ DCMQGSM
void run_sim_bmn(TString inFile="DCMSMM_XeCsI_3.9AGeV_mb_10k_142.r12", TString outFile="$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 run_sim_bmn.C:27