CbmRoot
Loading...
Searching...
No Matches
CbmTransportConfig.cxx
Go to the documentation of this file.
1/* Copyright (C) 2021 National Research Nuclear University MEPhI (Moscow Engineering Physics Institute), Moscow
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Oleg Golosov [committer] */
4
6
7#include "CbmBeamGenerator.h"
8#include "CbmGeant4Settings.h"
9#include "CbmPlutoGenerator.h"
10#include "CbmTransport.h"
11
12using namespace std;
13
14string CbmTransportConfig::GetModuleTag() { return "transport"; }
15
17{
18 return {"logScreenLevel",
19 "logVerbosityLevel",
20 "input.file",
21 "input.generator",
22 "input.plutoPdg",
23 "input.beamA",
24 "input.beamZ",
25 "input.beamQ",
26 "input.beamP",
27 "input.beamStartZ",
28 "output.path",
29 "output.overwrite",
30 "target.material",
31 "target.thickness",
32 "target.diameter",
33 "target.position.x",
34 "target.position.y",
35 "target.position.z",
36 "target.rotation.y",
37 "target.density",
38 "beam.position.x",
39 "beam.position.y",
40 "beam.position.zFocus",
41 "beam.position.sigmaX",
42 "beam.position.sigmaY",
43 "beam.angle.x",
44 "beam.angle.y",
45 "beam.angle.sigmaX",
46 "beam.angle.sigmaY",
47 "geantVersion",
48 "geant4vmcSettings.physicsLists",
49 "geant4vmcSettings.specialProcesses",
50 "geant4vmcSettings.maxNsteps",
51 "geant4vmcSettings.geant4commands",
52 "randomRP",
53 "geometry.magneticField.position.x",
54 "geometry.magneticField.position.y",
55 "geometry.magneticField.position.z",
56 "geometry.magneticField.scale",
57 "geometry.magneticField.tag",
58 "geometry.baseSetup",
59 "geometry.subsystems",
60 "geometry.subsystems.cave",
61 "geometry.subsystems.magnet",
62 "geometry.subsystems.pipe",
63 "geometry.subsystems.target",
64 "geometry.subsystems.mvd",
65 "geometry.subsystems.sts",
66 "geometry.subsystems.rich",
67 "geometry.subsystems.much",
68 "geometry.subsystems.trd",
69 "geometry.subsystems.tof",
70 "geometry.subsystems.psd",
71 "geometry.subsystems.fsd",
72 "geometry.subsystems.hodo",
73 "geometry.subsystems.shield",
74 "geometry.subsystems.platform",
75 "stackFilter.storeAllPrimaries",
76 "stackFilter.storeAllMothers",
77 "stackFilter.storeAllDecays"};
78}
79
81
82bool CbmTransportConfig::SetIO(CbmTransport& obj, const pt::ptree& moduleTree)
83{
84 auto inputs = moduleTree.get_child("input");
85 int inputCounter = 0;
86 for (auto& input : inputs) {
87 pt::ptree pt_input = input.second;
88
89 string inputGenerator = pt_input.get<string>("generator", "");
90 if (inputGenerator == "") continue; // allow commenting out inputs
91
92 string inputFile = GetStringValue(pt_input, "file", "");
93 if (inputFile == "") { LOG(error) << "CbmTransportConfig: no path specified for input #" << inputCounter; }
94
95 if (inputGenerator == "unigen") obj.AddInput(inputFile.c_str(), kUnigen);
96 else if (inputGenerator == "pluto") {
97 auto plutoGen = new CbmPlutoGenerator(inputFile.c_str());
98 auto manualPdg = pt_input.get_optional<int>("plutoPdg");
99 if (manualPdg) plutoGen->SetManualPDG(manualPdg.get());
100 obj.AddInput(plutoGen);
101 }
102 else if (inputGenerator == "beam") {
103 auto confBeamA = pt_input.get_optional<int>("beamA");
104 auto confBeamZ = pt_input.get_optional<int>("beamZ");
105 auto confBeamQ = pt_input.get_optional<int>("beamQ");
106 auto confBeamP = pt_input.get_optional<float>("beamP");
107 auto confBeamStartZ = pt_input.get_optional<float>("beamStartZ");
108 auto targetZ = moduleTree.get_optional<float>("target.position.z");
109 int beamA, beamZ, beamQ;
110 float beamP, beamStartZ;
111 if (confBeamA && confBeamZ && confBeamP) {
112 beamA = confBeamA.get();
113 beamZ = confBeamZ.get();
114 beamP = confBeamP.get();
115 if (confBeamQ) beamQ = confBeamQ.get();
116 else
117 beamQ = confBeamA.get();
118 if (confBeamStartZ) {
119 beamStartZ = confBeamStartZ.get();
120 if (targetZ && beamStartZ > targetZ.get()) {
121 LOG(error) << "CbmTransportConfig: beam starts after the target: \n target.position.z = " << targetZ.get()
122 << " cm\n beamStartZ = " << beamStartZ << " cm";
123 return false;
124 }
125 }
126 else if (targetZ) {
127 beamStartZ = targetZ.get() - 1.;
128 LOG(warning) << "CbmTransportConfig: beamStartZ=targetZ-1. cm";
129 }
130 else {
131 LOG(error) << "CbmTransportConfig: beam start Z not set!";
132 return false;
133 }
134 obj.AddInput(new CbmBeamGenerator(beamZ, beamA, beamQ, beamP, beamStartZ));
135 LOG(info) << Form("CbmTransportConfig: add beam generator: Z = %d, A = %d, Q = %d, P = %f, startZ = %f", beamZ,
136 beamA, beamQ, beamP, beamStartZ);
137 }
138 else {
139 LOG(error) << "CbmTransportConfig: Incomplete beam generator configuration: A, Z and P required!";
140 return false;
141 }
142 }
143 else {
144 LOG(error) << "CbmTransportConfig: Unknown generator type " << inputGenerator << endl
145 << "Accepted generator types:";
146 for (auto& gen : GetAcceptedGenerators())
147 cout << gen << ", ";
148 cout << endl;
149 return false;
150 }
151 inputCounter++;
152 }
153
154 string outputPath = GetStringValue(moduleTree, "output.path", "");
155 if (outputPath == "") {
156 LOG(error) << "CbmTransportConfig: No output path provided!";
157 return false;
158 }
159 LOG(info) << "CbmTransportConfig: Output path: " << outputPath;
160 bool overwrite = moduleTree.get<bool>("output.overwrite", false);
161 if (overwrite) LOG(info) << "CbmTransportConfig: Overwrite output!";
162 obj.SetOutFileName(outputPath + ".tra.root", overwrite);
163 obj.SetParFileName(outputPath + ".par.root");
164 obj.SetGeoFileName(outputPath + ".geo.root");
165
166 return true;
167}
168
169bool CbmTransportConfig::SetTarget(CbmTransport& obj, const pt::ptree& moduleTree)
170{
171 auto material = moduleTree.get_optional<string>("target.material");
172 auto thickness = moduleTree.get_optional<float>("target.thickness");
173 auto diameter = moduleTree.get_optional<float>("target.diameter");
174 auto x = moduleTree.get_optional<float>("target.position.x");
175 auto y = moduleTree.get_optional<float>("target.position.y");
176 auto z = moduleTree.get_optional<float>("target.position.z");
177 auto rotY = moduleTree.get_optional<float>("target.rotation.y");
178 auto density = moduleTree.get_optional<float>("target.density");
179 // one can set a target only if all 3 parameters are present in config file
180 if (material && thickness && diameter) {
181 if (x && y && z && rotY && density && density.get() >= 0.)
182 obj.SetTarget(material.get().c_str(), thickness.get(), diameter.get(), x.get(), y.get(), z.get(), rotY.get(),
183 density.get());
184 if (x && y && z && rotY)
185 obj.SetTarget(material.get().c_str(), thickness.get(), diameter.get(), x.get(), y.get(), z.get(), rotY.get());
186 else if (x && y && z)
187 obj.SetTarget(material.get().c_str(), thickness.get(), diameter.get(), x.get(), y.get(), z.get());
188 else if (x && y)
189 obj.SetTarget(material.get().c_str(), thickness.get(), diameter.get(), x.get(), y.get());
190 else if (x)
191 obj.SetTarget(material.get().c_str(), thickness.get(), diameter.get(), x.get());
192 else
193 obj.SetTarget(material.get().c_str(), thickness.get(), diameter.get());
194 }
195 else {
196 LOG(error) << "CbmTransportConfig: Incomplete target configuration (material, thickness and diameter required)\n";
197 return false;
198 }
199 return true;
200}
201
202bool CbmTransportConfig::SetBeamProfile(CbmTransport& obj, const pt::ptree& moduleTree)
203{
204 auto posX = moduleTree.get_optional<float>("beam.position.x");
205 auto posY = moduleTree.get_optional<float>("beam.position.y");
206 auto posZ = moduleTree.get_optional<float>("beam.position.zFocus");
207 auto posSigmaX = moduleTree.get_optional<float>("beam.position.sigmaX");
208 auto posSigmaY = moduleTree.get_optional<float>("beam.position.sigmaY");
209 if (posX && posY) {
210 if (posSigmaX && posSigmaY && posZ)
211 obj.SetBeamPosition(posX.get(), posY.get(), posSigmaX.get(), posSigmaY.get(), posZ.get());
212 else if (posSigmaX && posSigmaY)
213 obj.SetBeamPosition(posX.get(), posY.get(), posSigmaX.get(), posSigmaY.get());
214 else if (posSigmaX)
215 obj.SetBeamPosition(posX.get(), posY.get(), posSigmaX.get());
216 else if (posX && posY)
217 obj.SetBeamPosition(posX.get(), posY.get());
218 }
219 else {
220 LOG(error) << "CbmTransportConfig: Incomplete beam position configuration (x and y required)\n";
221 return false;
222 }
223 auto angX = moduleTree.get_optional<float>("beam.angle.x");
224 auto angY = moduleTree.get_optional<float>("beam.angle.y");
225 auto angSigmaX = moduleTree.get_optional<float>("beam.angle.sigmaX");
226 auto angSigmaY = moduleTree.get_optional<float>("beam.angle.sigmaY");
227 if (angX && angY) {
228 if (angSigmaX && angSigmaY) obj.SetBeamAngle(angX.get(), angY.get(), angSigmaX.get(), angSigmaY.get());
229 else if (angSigmaX)
230 obj.SetBeamAngle(angX.get(), angY.get(), angSigmaX.get());
231 else if (angX && angY)
232 obj.SetBeamAngle(angX.get(), angY.get());
233 }
234 else {
235 LOG(error) << "CbmTransportConfig: Incomplete beam angle configuration (x and y required)\n";
236 return false;
237 }
238 return true;
239}
240
241bool CbmTransportConfig::SetTransportParameters(CbmTransport& obj, const pt::ptree& moduleTree)
242{
243 bool randomRP = true;
244 auto configRandomRP = moduleTree.get_optional<bool>("randomRP");
245 if (configRandomRP) randomRP = configRandomRP.get();
246 if (randomRP) obj.SetRandomEventPlane();
247
248 ECbmEngine engine = kGeant3;
249 auto geantVersion = moduleTree.get_optional<float>("geantVersion");
250 if (geantVersion) {
251 if (geantVersion.get() == 4) engine = kGeant4;
252 else if (geantVersion.get() != 3) {
253 LOG(error) << "CbmTransportConfig: Unknown Geant version: " << geantVersion.get();
254 return false;
255 }
256 }
257 obj.SetEngine(engine);
258
259 if (engine == kGeant4) {
260 auto g4settings = moduleTree.get_child_optional("geant4vmcSettings");
261 if (g4settings) {
262 auto g4settingsTree = g4settings.get();
263 auto physicsLists = g4settingsTree.get_optional<string>("physicsLists");
264 auto specialProcesses = g4settingsTree.get_optional<string>("specialProcesses");
265 auto maxNsteps = g4settingsTree.get_optional<int>("maxNsteps");
266
267 CbmGeant4Settings* settings = new CbmGeant4Settings();
268
269 if ((physicsLists && !specialProcesses) || (!physicsLists && specialProcesses)) {
270 LOG(error)
271 << "CbmTransportConfig: Incomplete Geant4 configuration: physicsLists and specialProcesses required!";
272 return false;
273 }
274 else if (physicsLists && specialProcesses)
275 settings->SetG4RunConfig("geomRoot", physicsLists.get(), specialProcesses.get());
276
277 if (maxNsteps) settings->SetMaximumNumberOfSteps(maxNsteps.get());
278
279 auto g4commands = g4settingsTree.get_child_optional("geant4commands");
280 if (g4commands)
281 for (auto& command : g4commands.get())
282 settings->AddG4Command(command.second.data());
283 settings->Dump();
284 obj.SetGeant4Settings(settings);
285 }
286 }
287 return true;
288}
289
290bool CbmTransportConfig::SetGeometry(CbmTransport& obj, const pt::ptree& moduleTree)
291{
292 return SetGeometry(obj.GetSetup(), moduleTree);
293};
294
295bool CbmTransportConfig::SetGeometry(CbmSetup* setup, const pt::ptree& moduleTree)
296{
297 auto geometry = moduleTree.get_child_optional("geometry");
298 if (!geometry) {
299 LOG(error) << "CbmTransportConfig: geometry settings missing!";
300 return false;
301 }
302 auto geometryTree = geometry.get();
303 auto baseSetup = geometryTree.get_optional<string>("baseSetup");
304 if (baseSetup) setup->LoadSetup(baseSetup.get().c_str());
305
306 auto fieldTag = geometryTree.get_optional<string>("magneticField.tag");
307 auto fieldScale = geometryTree.get_optional<float>("magneticField.scale");
308 auto fieldX = geometryTree.get_optional<float>("magneticField.position.x");
309 auto fieldY = geometryTree.get_optional<float>("magneticField.position.y");
310 auto fieldZ = geometryTree.get_optional<float>("magneticField.position.z");
311
312 if (fieldTag && fieldScale && fieldX && fieldY && fieldZ)
313 setup->SetField(fieldTag.get().c_str(), fieldScale.get(), fieldX.get(), fieldY.get(), fieldZ.get());
314 else if (fieldScale) {
315 if (baseSetup) setup->SetFieldScale(fieldScale.get());
316 else {
317 LOG(error) << "CbmTransportConfig: Incomplete magnetic field configuration: fieldTag, fieldScale, fieldX, fieldY "
318 "and fieldZ are required if base setup is not defined!";
319 return false;
320 }
321 }
322 auto modules = geometryTree.get_child_optional("subsystems");
323 if (modules)
324 for (auto& module : modules.get()) {
325 auto moduleId = stringToECbmModuleId(module.first);
326 if (module.second.data() == "") setup->RemoveModule(moduleId);
327 else
328 setup->SetModule(moduleId, module.second.data().c_str());
329 }
330 return true;
331}
332
333bool CbmTransportConfig::SetStackFilter(CbmTransport& obj, const pt::ptree& moduleTree)
334{
335 auto stackFilterSettings = moduleTree.get_child_optional("stackFilter");
336 if (!stackFilterSettings) return true;
337 auto settingsTree = stackFilterSettings.get();
338 auto& filter = obj.GetStackFilter();
339 auto storeAllPrimaries = settingsTree.get_optional<bool>("storeAllPrimaries");
340 auto storeAllMothers = settingsTree.get_optional<bool>("storeAllMothers");
341 auto storeAllDecays = settingsTree.get_optional<bool>("storeAllDecays");
342 if (storeAllPrimaries) filter->SetStoreAllPrimaries(storeAllPrimaries.get());
343 if (storeAllMothers) filter->SetStoreAllMothers(storeAllMothers.get());
344 if (storeAllDecays) filter->SetStoreAllPrimaryDecays(storeAllDecays.get());
345 return true;
346}
347
348bool CbmTransportConfig::LoadImpl(CbmTransport& obj, const pt::ptree& moduleTree)
349{
350 return SetIO(obj, moduleTree) && SetTarget(obj, moduleTree) && SetBeamProfile(obj, moduleTree)
351 && SetTransportParameters(obj, moduleTree) && SetGeometry(obj, moduleTree) && SetStackFilter(obj, moduleTree);
352}
353
ClassImp(CbmConverterManager)
@ kUnigen
ECbmEngine
@ kGeant3
@ kGeant4
static std::string GetStringValue(boost::optional< std::string > opt)
static ECbmModuleId stringToECbmModuleId(std::string s)
User interface class to define the Geant4 simulation settings.
void SetFieldScale(Double_t scale)
Definition CbmSetup.h:172
void RemoveModule(ECbmModuleId moduleId)
Definition CbmSetup.cxx:180
void SetModule(ECbmModuleId moduleId, const char *geoTag, Bool_t active=kTRUE)
Definition CbmSetup.cxx:218
void SetField(const char *tag, Double_t scale=1., Double_t xPos=0., Double_t yPos=0., Double_t zPos=0.)
Definition CbmSetup.cxx:203
void LoadSetup(const char *setupName)
Definition CbmSetup.h:64
static TagSet_t GetValidationTags()
static std::string GetModuleTag()
static bool SetTarget(CbmTransport &obj, const pt::ptree &moduleTree)
static TagSet_t GetAcceptedGenerators()
static bool SetIO(CbmTransport &obj, const pt::ptree &moduleTree)
static bool SetTransportParameters(CbmTransport &obj, const pt::ptree &moduleTree)
static bool SetStackFilter(CbmTransport &obj, const pt::ptree &moduleTree)
static bool LoadImpl(CbmTransport &obj, const pt::ptree &moduleTree)
static bool SetGeometry(CbmTransport &obj, const pt::ptree &moduleTree)
CbmConfigBase< CbmTransportConfig, CbmTransport >::TagSet_t TagSet_t
static bool SetBeamProfile(CbmTransport &obj, const pt::ptree &moduleTree)
User interface class for transport simulation.
void SetTarget(const char *medium="Gold", Double_t thickness=0.025, Double_t diameter=2.5, Double_t x=0., Double_t y=0., Double_t z=-44.0, Double_t rot=0., Double_t density=-1)
Define the target.
void SetOutFileName(TString name, Bool_t overwrite=kFALSE)
Set the output file name.
void SetGeoFileName(TString name)
Define geometry file name (output)
void SetBeamPosition(Double_t x0, Double_t y0, Double_t sigmaX=-1., Double_t sigmaY=-1., Double_t zF=0.)
Set the beam position.
void SetRandomEventPlane(Double_t phiMin=0., Double_t phiMax=2. *TMath::Pi())
Activate random event plane.
void AddInput(const char *fileName, ECbmGenerator generator=kUnigen)
Add an input by file name and generator type.
CbmSetup * GetSetup() const
Detector setup interface.
void SetGeant4Settings(CbmGeant4Settings *val)
Set user defined transport settings for Geant4.
std::unique_ptr< CbmStackFilter > & GetStackFilter()
Access to stack filter object.
void SetParFileName(TString name)
Define parameter file name.
void SetEngine(ECbmEngine engine)
Set transport engine.
void SetBeamAngle(Double_t x0, Double_t y0, Double_t sigmaX=-1., Double_t sigmaY=-1.)
Set the beam angle (emittency at the beam position)
Hash for CbmL1LinkKey.