754#include "TRestGeant4Metadata.h"
757#include <TGeoManager.h>
758#include <TObjString.h>
760#include <TRestGDMLParser.h>
763#include "TRestGeant4ParticleSourceCosmics.h"
764#include "TRestGeant4PrimaryGeneratorInfo.h"
767using namespace TRestGeant4PrimaryGeneratorTypes;
822 fMagneticField = Get3DVectorParameterWithUnits(
"magneticField", TVector3(0, 0, 0));
830 cout <<
"\"gdmlFile\" parameter is not defined!" << endl;
837 cout <<
"Error downloading geometry file from URL: " <<
fGdmlFilename << endl;
843 auto volPathSeparator =
850 if (
ToUpper(seedString) ==
"RANDOM" ||
ToUpper(seedString) ==
"RAND" ||
ToUpper(seedString) ==
"AUTO" ||
852 auto dd =
new double();
853 fSeed = (uintptr_t)dd + (uintptr_t)
this;
858 gRandom->SetSeed(
fSeed);
862 if ((((
string)
fGdmlFilename).find_first_not_of(
"./~") == 0 ||
872 Double_t defaultTime = 100. / REST_Units::us;
875 defaultTime = 1. / REST_Units::us;
879 if (nEventsString == PARAMETER_NOT_FOUND_STR) {
887 const auto fNRequestedEntriesString =
GetParameter(
"nRequestedEntries");
889 fNRequestedEntriesString == PARAMETER_NOT_FOUND_STR ? 0 :
StringToInteger(fNRequestedEntriesString);
911 RESTWarning <<
"IMPORTANT: *maxTargetStepSize* parameter is now obsolete!" <<
RESTendl;
912 RESTWarning <<
"The sensitive volume will not define any integration step limit" <<
RESTendl;
914 RESTWarning <<
"In order to avoid this warning REMOVE the *maxTargetStepSize* definition,"
916 RESTWarning <<
"and replace it by the following statement at the <storage> section" <<
RESTendl;
918 RESTWarning <<
"<activeVolume name=\"" << this->
GetSensitiveVolume() <<
"\" maxStepSize=\""
921 RESTInfo <<
"Now, any active volume is allowed to define a maxStepSize" <<
RESTendl;
923 RESTInfo <<
"It is also possible to define a default step size for all active volumes," <<
RESTendl;
924 RESTInfo <<
"so that in case no step is defined, the default will be used." <<
RESTendl;
926 RESTInfo <<
"<storage sensitiveVolume=\"" << this->
GetSensitiveVolume() <<
"\" maxStepSize=\""
957 double countsPerSecondPerCm2 = 0;
958 if (TRestGeant4PrimaryGeneratorTypes::StringToEnergyDistributionTypes(
959 source->GetEnergyDistributionType().Data()) ==
960 TRestGeant4PrimaryGeneratorTypes::EnergyDistributionTypes::FORMULA2 &&
961 TRestGeant4PrimaryGeneratorTypes::StringToAngularDistributionTypes(
962 source->GetAngularDistributionType().Data()) ==
963 TRestGeant4PrimaryGeneratorTypes::AngularDistributionTypes::FORMULA2) {
964 const auto energyRange = source->GetEnergyDistributionRange();
965 const auto angularRange = source->GetAngularDistributionRange();
966 auto function = (TF2*)source->GetEnergyAndAngularDistributionFunction()->Clone();
968 countsPerSecondPerCm2 =
969 function->Integral(energyRange.X(), energyRange.Y(), angularRange.X(), angularRange.Y(), 1E-9);
972 else if (std::string(source->GetName()) ==
"TRestGeant4ParticleSourceCosmics") {
974 const auto names = cosmicSource->GetParticleNames();
975 const auto histograms = cosmicSource->GetHistogramsTransformed();
976 for (
const auto& name : names) {
977 countsPerSecondPerCm2 += histograms.at(name)->Integral();
979 }
else if (TRestGeant4PrimaryGeneratorTypes::StringToEnergyDistributionTypes(
980 source->GetEnergyDistributionType().Data()) ==
981 TRestGeant4PrimaryGeneratorTypes::EnergyDistributionTypes::TH2D &&
982 TRestGeant4PrimaryGeneratorTypes::StringToAngularDistributionTypes(
983 source->GetAngularDistributionType().Data()) ==
984 TRestGeant4PrimaryGeneratorTypes::AngularDistributionTypes::TH2D) {
985 const auto filename = source->GetEnergyDistributionFilename();
986 const auto name = source->GetEnergyDistributionNameInFile();
987 TFile* file = TFile::Open(filename);
988 auto energyAndAngularDistributionHistogram =
989 file->Get<TH2D>(name);
990 if (energyAndAngularDistributionHistogram ==
nullptr) {
991 throw std::runtime_error(
"Histogram not found in file");
993 countsPerSecondPerCm2 = energyAndAngularDistributionHistogram->Integral();
999 throw std::runtime_error(
"Cosmic flux calculation is only supported for TFormula2 or TH2D sources");
1002 return countsPerSecondPerCm2;
1005Double_t TRestGeant4Metadata::GetCosmicIntensityInCountsPerSecond()
const {
1007 const auto surface = GetGeneratorSurfaceCm2();
1008 const auto countsPerSecond = countsPerSecondPerCm2 * surface;
1009 return countsPerSecond;
1015 double scalingFactor = 1.0;
1016 if (type ==
"cosmic") {
1019 if (cosmicSource !=
nullptr) {
1022 ->GetEnergyRangeScalingFactor();
1023 if (scalingFactor < 0 || scalingFactor > 1) {
1024 throw std::runtime_error(
"Energy range scaling factor must be between 0 and 1");
1030 const auto countsPerSecond = GetCosmicIntensityInCountsPerSecond() * scalingFactor;
1031 const auto seconds = double(
fNEvents) / countsPerSecond;
1036void TRestGeant4Metadata::ReadBiasing() {
1037 TiXmlElement* biasingDefinition =
GetElement(
"biasing");
1038 if (biasingDefinition ==
nullptr) {
1042 TString biasEnabled =
GetFieldValue(
"value", biasingDefinition);
1043 TString biasType =
GetFieldValue(
"type", biasingDefinition);
1045 RESTDebug <<
"Bias: " << biasEnabled <<
RESTendl;
1047 if (biasEnabled ==
"on" || biasEnabled ==
"ON" || biasEnabled ==
"On" || biasEnabled ==
"oN") {
1048 RESTInfo <<
"Biasing is enabled" <<
RESTendl;
1050 TiXmlElement* biasVolumeDefinition =
GetElement(
"biasingVolume", biasingDefinition);
1052 while (biasVolumeDefinition) {
1054 RESTDebug <<
"Def: " << biasVolumeDefinition <<
RESTendl;
1056 biasVolume.SetBiasingVolumePosition(
1057 Get3DVectorParameterWithUnits(
"position", biasVolumeDefinition));
1059 biasVolume.SetBiasingVolumeSize(GetDblParameterWithUnits(
"size", biasVolumeDefinition));
1060 biasVolume.SetEnergyRange(Get2DVectorParameterWithUnits(
"energyRange", biasVolumeDefinition));
1061 biasVolume.SetBiasingVolumeType(biasType);
1109 TiXmlElement* generatorDefinition =
GetElement(
"generator");
1112 SpatialGeneratorTypesToString(StringToSpatialGeneratorTypes(
GetParameter(
1113 "type", generatorDefinition, SpatialGeneratorTypesToString(SpatialGeneratorTypes::VOLUME))));
1115 SpatialGeneratorShapesToString(StringToSpatialGeneratorShapes(
GetParameter(
1116 "shape", generatorDefinition, SpatialGeneratorShapesToString(SpatialGeneratorShapes::BOX))));
1120 SpatialGeneratorShapesToString(SpatialGeneratorShapes::GDML);
1123 Get3DVectorParameterWithUnits(
"size", generatorDefinition, {0, 0, 0});
1125 Get3DVectorParameterWithUnits(
"position", generatorDefinition, {0, 0, 0});
1127 Get3DVectorParameterWithUnits(
"rotationAxis", generatorDefinition, {0, 0, 1});
1129 GetDblParameterWithUnits(
"rotationAngle", generatorDefinition, 0);
1133 TiXmlElement* sourceDefinition =
GetElement(
"source", generatorDefinition);
1134 while (sourceDefinition) {
1135 string use =
GetParameter(
"use", sourceDefinition,
"");
1141 if (
string(source->GetName()) ==
"TRestGeant4ParticleSourceCosmics") {
1142 TRestGeant4ParticleSourceCosmics::SetSeed(
GetSeed());
1150 RESTError <<
"No sources are added inside generator!" <<
RESTendl;
1159 TiXmlElement* sourceDefinition = definition;
1161 source->SetParticleName(
GetParameter(
"particle", sourceDefinition));
1165 TString fullChain =
GetParameter(
"fullChain", sourceDefinition);
1167 if (fullChain.EqualTo(
"on", TString::ECaseCompare::kIgnoreCase)) {
1171 const TString fullChainStopIsotopesString =
GetParameter(
"fullChainStopIsotopes", sourceDefinition,
"");
1172 if (fullChainStopIsotopesString !=
"") {
1173 TObjArray* fullChainStopIsotopesArray = fullChainStopIsotopesString.Tokenize(
",");
1174 for (
int i = 0; i < fullChainStopIsotopesArray->GetEntries(); i++) {
1175 TString isotope = ((TObjString*)fullChainStopIsotopesArray->At(i))->String();
1181 TiXmlElement* angularDefinition =
GetElement(
"angular", sourceDefinition);
1182 if (angularDefinition ==
nullptr) {
1183 angularDefinition =
GetElement(
"angularDist", sourceDefinition);
1186 "type", angularDefinition, AngularDistributionTypesToString(AngularDistributionTypes::FLUX)));
1187 if ((StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1188 AngularDistributionTypes::TH1D) ||
1189 (StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1190 AngularDistributionTypes::TH2D)) {
1193 if (name ==
"NO_SUCH_PARA") {
1196 source->SetAngularDistributionNameInFile(name);
1198 source->SetAngularDistributionRange(
1199 Get2DVectorParameterWithUnits(
"range", angularDefinition, {0, TMath::Pi()}));
1200 if (StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1201 AngularDistributionTypes::FORMULA) {
1202 source->SetAngularDistributionFormula(
GetParameter(
"name", angularDefinition));
1204 const auto function = source->GetAngularDistributionFunction();
1205 if (source->GetAngularDistributionRangeMin() < function->GetXaxis()->GetXmin()) {
1206 source->SetAngularDistributionRange(
1207 {function->GetXaxis()->GetXmin(), source->GetAngularDistributionRangeMax()});
1209 if (source->GetAngularDistributionRangeMax() > function->GetXaxis()->GetXmax()) {
1210 source->SetAngularDistributionRange(
1211 {source->GetAngularDistributionRangeMin(), function->GetXaxis()->GetXmax()});
1214 if ((StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1215 AngularDistributionTypes::FORMULA) ||
1216 (StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1217 AngularDistributionTypes::FORMULA2)) {
1218 source->SetAngularDistributionFormulaNPoints(
static_cast<size_t>(GetDblParameterWithUnits(
1219 "nPoints", angularDefinition, source->GetAngularDistributionFormulaNPoints())));
1222 StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1223 AngularDistributionTypes::BACK_TO_BACK) {
1224 cout <<
"WARNING: First source cannot be backtoback. Setting it to isotropic" << endl;
1225 source->SetAngularDistributionType(
1226 AngularDistributionTypesToString(AngularDistributionTypes::ISOTROPIC));
1230 if ((StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1231 AngularDistributionTypes::ISOTROPIC)) {
1232 source->SetAngularDistributionRange({0, TMath::Pi()});
1233 const double coneHalfAngle = GetDblParameterWithUnits(
"coneHalfAngle", angularDefinition, 0);
1234 source->SetAngularDistributionIsotropicConeHalfAngle(coneHalfAngle);
1237 TiXmlElement* energyDefinition =
GetElement(
"energy", sourceDefinition);
1238 if (energyDefinition ==
nullptr) {
1239 energyDefinition =
GetElement(
"energyDist", sourceDefinition);
1242 "type", energyDefinition, EnergyDistributionTypesToString(EnergyDistributionTypes::MONO)));
1243 if ((StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1244 EnergyDistributionTypes::TH1D) ||
1245 (StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1246 EnergyDistributionTypes::TH2D)) {
1249 if (name ==
"NO_SUCH_PARA") {
1252 source->SetEnergyDistributionNameInFile(name);
1254 source->SetEnergyDistributionRange(Get2DVectorParameterWithUnits(
"range", energyDefinition, {0, 1E20}));
1255 if (StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1256 EnergyDistributionTypes::MONO) {
1258 energy = GetDblParameterWithUnits(
"energy", energyDefinition, 0);
1259 source->SetEnergyDistributionRange({energy, energy});
1260 source->SetEnergy(energy);
1262 if (StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1263 EnergyDistributionTypes::FORMULA) {
1264 source->SetEnergyDistributionFormula(
GetParameter(
"name", energyDefinition));
1266 const auto function = source->GetEnergyDistributionFunction();
1267 if (source->GetEnergyDistributionRangeMin() < function->GetXaxis()->GetXmin()) {
1268 source->SetEnergyDistributionRange(
1269 {function->GetXaxis()->GetXmin(), source->GetEnergyDistributionRangeMax()});
1271 if (source->GetEnergyDistributionRangeMax() > function->GetXaxis()->GetXmax()) {
1272 source->SetEnergyDistributionRange(
1273 {source->GetEnergyDistributionRangeMin(), function->GetXaxis()->GetXmax()});
1276 if ((StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1277 EnergyDistributionTypes::FORMULA) ||
1278 (StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1279 EnergyDistributionTypes::FORMULA2)) {
1280 source->SetEnergyDistributionFormulaNPoints(
static_cast<size_t>(GetDblParameterWithUnits(
1281 "nPoints", energyDefinition, source->GetEnergyDistributionFormulaNPoints())));
1283 if (StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1284 EnergyDistributionTypes::FORMULA2 &&
1285 StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1286 AngularDistributionTypes::FORMULA2) {
1287 const auto empty = TString(
"");
1288 auto energyDistName =
GetParameter(
"name", energyDefinition, empty);
1289 auto angularDistName =
GetParameter(
"name", energyDefinition, empty);
1291 if (energyDistName == empty && angularDistName == empty) {
1292 RESTError <<
"No name specified for energy and angular distribution" <<
RESTendl;
1295 if (energyDistName == empty) {
1296 angularDistName = energyDistName;
1297 RESTWarning <<
"No name specified for energy distribution. Using angular distribution name: "
1300 if (angularDistName == empty) {
1301 energyDistName = energyDistName;
1302 RESTWarning <<
"No name specified for angular distribution. Using energy distribution name: "
1306 if (energyDistName == empty || angularDistName == empty) {
1308 RESTError <<
"When using 'formula2' the name of energy and angular dist must match" <<
RESTendl;
1311 const auto energyAndAngularDistName = energyDistName;
1312 source->SetEnergyAndAngularDistributionFormula(energyAndAngularDistName);
1314 const auto function = source->GetEnergyAndAngularDistributionFunction();
1317 if (source->GetEnergyDistributionRangeMin() < function->GetXaxis()->GetXmin()) {
1318 source->SetEnergyDistributionRange(
1319 {function->GetXaxis()->GetXmin(), source->GetEnergyDistributionRangeMax()});
1321 if (source->GetEnergyDistributionRangeMax() > function->GetXaxis()->GetXmax()) {
1322 source->SetEnergyDistributionRange(
1323 {source->GetEnergyDistributionRangeMin(), function->GetXaxis()->GetXmax()});
1327 if (source->GetAngularDistributionRangeMin() < function->GetYaxis()->GetXmin()) {
1328 source->SetAngularDistributionRange(
1329 {function->GetYaxis()->GetXmin(), source->GetAngularDistributionRangeMax()});
1331 if (source->GetAngularDistributionRangeMax() > function->GetYaxis()->GetXmax()) {
1332 source->SetAngularDistributionRange(
1333 {source->GetAngularDistributionRangeMin(), function->GetYaxis()->GetXmax()});
1367 RESTInfo <<
"TRestGeant4Metadata: Processing detector section" <<
RESTendl;
1368 TiXmlElement* detectorDefinition =
GetElement(
"detector");
1369 if (detectorDefinition ==
nullptr) {
1370 RESTError <<
"Detector section (<detector>) is not present in metadata!" <<
RESTendl;
1374 const bool activateAllVolumes =
1375 StringToBool(
GetParameter(
"activateAllVolumes", detectorDefinition,
"true"));
1379 TiXmlElement* removeUnwantedTracksDefinition =
GetElement(
"removeUnwantedTracks", detectorDefinition);
1380 if (removeUnwantedTracksDefinition !=
nullptr) {
1383 StringToBool(
GetParameter(
"keepZeroEnergyTracks", removeUnwantedTracksDefinition,
"false"));
1389 Double_t defaultStep = GetDblParameterWithUnits(
"maxStepSize", detectorDefinition);
1390 if (defaultStep < 0) {
1394 TiXmlElement* volumeDefinition =
GetElement(
"volume", detectorDefinition);
1395 while (volumeDefinition !=
nullptr) {
1397 if (name.empty() || name ==
"Not defined") {
1398 RESTError <<
"volume inside detector section defined without name" <<
RESTendl;
1401 vector<string> physicalVolumes;
1404 RESTDebug <<
"Volume name '" << name <<
"' is a valid logical volume. "
1405 <<
"Inserting all physical volumes from it." <<
RESTendl;
1407 for (
const auto& altPhysical :
1409 physicalVolumes.emplace_back(altPhysical);
1414 if (physicalVolumes.empty()) {
1415 RESTDebug <<
"Volume name '" << name <<
"' is not a valid logical volume. "
1416 <<
"Trying to match as regular expression for physical volumes." <<
RESTendl;
1417 for (
const auto& physical :
1419 RESTExtreme <<
"Volume name '" << name <<
"' matches physical volume '" << physical <<
"'"
1421 physicalVolumes.emplace_back(physical);
1424 if (physicalVolumes.empty()) {
1425 RESTDebug <<
"Volume name '" << name
1426 <<
"' is not a valid logical volume neither physical volume regex. "
1427 <<
"Trying to match as regular expression for logical volumes." <<
RESTendl;
1429 for (
const auto& physical :
1431 RESTExtreme <<
"Volume name '" << name <<
"' matches logical volume '" << logical
1432 <<
"' with physical volume '" << physical <<
"'" <<
RESTendl;
1433 for (
const auto& altPhysical :
1435 physicalVolumes.emplace_back(altPhysical);
1441 RESTDebug <<
"Volume name '" << name <<
"' is a valid physical volume." <<
RESTendl;
1442 physicalVolumes.push_back(name);
1445 if (physicalVolumes.empty()) {
1447 <<
"volume '" << name
1448 <<
"' is not defined in the geometry. Could not match to a physical, logical volume or regex"
1453 bool isSensitive =
false;
1454 const string isSensitiveValue =
GetFieldValue(
"sensitive", volumeDefinition);
1455 if (isSensitiveValue !=
"Not defined") {
1456 isSensitive = StringToBool(isSensitiveValue);
1459 bool isKeepTracks = isSensitive;
1460 const string isKeepTracksValue =
GetFieldValue(
"keepTracks", volumeDefinition);
1461 if (isKeepTracksValue !=
"Not defined") {
1462 isKeepTracks = StringToBool(isKeepTracksValue);
1465 bool isKill =
false;
1466 const string isKillValue =
GetFieldValue(
"kill", volumeDefinition);
1467 if (isKillValue !=
"Not defined") {
1468 isKill = StringToBool(isKillValue);
1472 if (chance == -1 || chance < 0) {
1475 Double_t maxStep = GetDblParameterWithUnits(
"maxStepSize", volumeDefinition);
1477 maxStep = defaultStep;
1480 for (
const auto& physical : physicalVolumes) {
1481 RESTInfo <<
"Adding " << (isSensitive ?
"sensitive" :
"active") <<
" volume from RML: '"
1482 << physical <<
"'" << (chance != 1 ?
" with chance: " + to_string(chance) :
" ")
1492 fKillVolumes.insert(physical);
1499 cout <<
"No sensitive volumes defined in detector section. Adding 'gas' as sensitive volume" << endl;
1529 if (!IsActiveVolume(name)) {
1531 RESTInfo <<
"Automatically adding active volume: '" << name <<
"' with chance: " << 1
1538 RESTError <<
"No active volumes defined. Please check the detector section" <<
RESTendl;
1557 RESTMetadata <<
"Reset global time: enabled" <<
RESTendl;
1558 RESTMetadata <<
"Reset Time precision " << GetResetTimePrecision() <<
" us" <<
RESTendl;
1560 RESTMetadata <<
"Reset global time: disabled" <<
RESTendl;
1566 RESTMetadata <<
"Magnetic field: (" << mx <<
", " << my <<
", " << mz <<
") T" <<
RESTendl;
1569 RESTMetadata <<
"Register empty tracks was enabled" <<
RESTendl;
1571 RESTMetadata <<
"Register empty tracks was NOT enabled" <<
RESTendl;
1575 RESTMetadata <<
" ++++++++++ Generator +++++++++++ " <<
RESTendl;
1582 RESTMetadata <<
" ++++++++++ Detector +++++++++++ " <<
RESTendl;
1585 RESTMetadata <<
"Number of sensitive volumes: " << GetNumberOfSensitiveVolumes() <<
RESTendl;
1587 RESTMetadata <<
"Sensitive volume: " << sensitiveVolume <<
RESTendl;
1601 if (GetRemoveUnwantedTracks()) {
1602 RESTMetadata <<
"removeUnwantedTracks is enabled "
1604 <<
" keeping zero energy tracks" <<
RESTendl;
1614 RESTMetadata <<
"+++++" <<
RESTendl;
1644 if (name == activeVolumeName) {
1653 fActiveVolumesSet.insert(name.Data());
1656double TRestGeant4Metadata::GetGeneratorSurfaceCm2()
const {
1660 if (type ==
"surface" && shape ==
"circle") {
1662 return TMath::Pi() * radius * radius * 0.01;
1663 }
else if (type ==
"cosmic") {
1667 throw std::runtime_error(
1668 "TRestGeant4Metadata::GetGeneratorSurfaceCm2: Can only be called for 'cosmic' and 'surface/circle' "
1697 RESTWarning <<
"TRestGeant4Metadata::GetStorageChance. Volume " << volume <<
" not found" <<
RESTendl;
1711 RESTWarning <<
"TRestGeant4Metadata::GetMaxStepSize. Volume " << volume <<
" not found" <<
RESTendl;
1716size_t TRestGeant4Metadata::GetGeant4VersionMajor()
const {
1717 TString majorVersion =
"";
1725 return std::stoi(majorVersion.Data());
1742 fIsMerge = metadata.fIsMerge;
1771 fKillVolumes = metadata.fKillVolumes;
std::set< TString > GetAlternativeNamesFromGeant4PhysicalName(const TString &) const
Gets all the alternative physical volume names from the GDML file naming that correspond to a given G...
std::vector< TString > GetAllPhysicalVolumes() const
Gets all the (GDML) physical volume names.
bool IsValidLogicalVolume(const TString &volume) const
Checks if a logical volume name exists in the geometry.
std::vector< TString > GetAllPhysicalVolumesMatchingExpression(const TString &) const
Gets all the (GDML) physical volume names matching a given regular expression.
std::vector< TString > GetAllLogicalVolumesMatchingExpression(const TString &) const
Gets all the logical volume names matching a given regular expression.
std::vector< TString > GetAllPhysicalVolumesFromLogical(const TString &logicalVolume) const
Gets all the (Geant4) physical volume names corresponding to a given logical volume name.
virtual void PrintMetadata() override
Implemented it in the derived metadata class to print out specific metadata information.
TVector3 fSpatialGeneratorSize
The size of the generator. Stores up to three dimensions according to the shape box: length,...
TString GetSpatialGeneratorType() const
Returns a std::string specifying the generator type (volume, surface, point, virtualWall,...
TString fSpatialGeneratorFrom
The volume name where the events are generated, in case of volume or surface generator types.
TString fSpatialGeneratorSpatialDensityFunction
Defines density distribution of the generator shape. rho=F(x,y,z), in range 0~1.
Double_t fSpatialGeneratorRotationValue
degrees of rotation for generator virtual shape along the axis
TVector3 fSpatialGeneratorPosition
The position of the generator for virtual, and point, generator types.
Double_t GetSpatialGeneratorCosmicSurfaceTermCm2() const
Returns cosmic surface term (cm2) for simulation time computation.
TVector3 fSpatialGeneratorRotationAxis
A 3d-std::vector with the angles, measured in degrees, of a XYZ rotation applied to the virtual gener...
TVector3 GetSpatialGeneratorSize() const
Returns the main spatial dimension of virtual generator. It is the size of a virtualBox.
TString GetSpatialGeneratorShape() const
Returns a std::string specifying the generator shape (point, wall, box, etc )
TString fSpatialGeneratorShape
Shape of spatial generator (wall, GDML, sphere, etc)
TString fSpatialGeneratorType
Type of spatial generator (point, surface, volume, custom)
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.
Double_t StringToDouble(std::string in)
Gets a double from a string.
std::string ToUpper(std::string in)
Convert string to its upper case. Alternative of TString::ToUpper.
Int_t StringToInteger(std::string in)
Gets an integer from a string.
std::string ToLower(std::string in)
Convert string to its lower case. Alternative of TString::ToLower.
TVector3 StringTo3DVector(std::string in)
Gets a 3D-vector from a string. Format should be : (X,Y,Z).