BmnRoot
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
91#include "../../gconfig/g4Config.C"
92// #include "../../gconfig/g3Config.C"
93#include "../../gconfig/SetCuts.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}
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)
Definition BmnFieldMap.h:55
virtual void Print(Option_t *) const
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)
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)
Bool_t SkipEvents(Int_t count)
STL namespace.
enumGenerators
int main()
void geant4_setup()
void geant3_setup()
@ PART
@ BOX
@ QGSM
@ UNIGEN
@ HSD
@ URQMD
@ ION
@ DCMSMM
@ DCMQGSM
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)