REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
src/TRestGeant4Metadata.cxx
1/*************************************************************************
2 * This file is part of the REST software framework. *
3 * *
4 * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5 * For more information see http://gifna.unizar.es/trex *
6 * *
7 * REST is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * REST is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have a copy of the GNU General Public License along with *
18 * REST in $REST_PATH/LICENSE. *
19 * If not, see http://www.gnu.org/licenses/. *
20 * For the list of contributors see $REST_PATH/CREDITS. *
21 *************************************************************************/
22
734
735#include "TRestGeant4Metadata.h"
736
737#include <TAxis.h>
738#include <TGeoManager.h>
739#include <TObjString.h>
740#include <TRandom.h>
741#include <TRestGDMLParser.h>
742#include <TRestRun.h>
743
744#include "TRestGeant4ParticleSourceCosmics.h"
745#include "TRestGeant4PrimaryGeneratorInfo.h"
746
747using namespace std;
748using namespace TRestGeant4PrimaryGeneratorTypes;
749
750ClassImp(TRestGeant4Metadata);
751
756
771TRestGeant4Metadata::TRestGeant4Metadata(const char* configFilename, const string& name)
772 : TRestMetadata(configFilename) {
773 Initialize();
774
776}
777
782
787 SetSectionName(this->ClassName());
788 SetLibraryVersion(LIBRARY_VERSION);
789
790 fChance.clear();
791 fActiveVolumes.clear();
792 fBiasingVolumes.clear();
793
795}
796
801 this->Initialize();
802
803 fMagneticField = Get3DVectorParameterWithUnits("magneticField", TVector3(0, 0, 0));
804
805 // Initialize the metadata members from a configfile
806 fGdmlFilename = GetParameter("gdmlFile");
807 if (fGdmlFilename == PARAMETER_NOT_FOUND_STR) {
808 fGdmlFilename = GetParameter("gdml_file"); // old name
809 }
810 if (fGdmlFilename == PARAMETER_NOT_FOUND_STR) {
811 cout << "\"gdmlFile\" parameter is not defined!" << endl;
812 exit(1);
813 }
814 if (TRestTools::isURL(fGdmlFilename.Data())) {
815 fGeometryPath = "";
817 if (fGdmlFilename == "") {
818 cout << "Error downloading geometry file from URL: " << fGdmlFilename << endl;
819 exit(1);
820 }
821 }
822
823 fGeometryPath = GetParameter("geometryPath", "");
824
825 fStoreHadronicTargetInfo = StringToBool(GetParameter("storeHadronicTargetInfo", "false"));
826
827 string seedString = GetParameter("seed", "0");
828 if (ToUpper(seedString) == "RANDOM" || ToUpper(seedString) == "RAND" || ToUpper(seedString) == "AUTO" ||
829 seedString == "0") {
830 auto dd = new double();
831 fSeed = (uintptr_t)dd + (uintptr_t)this;
832 delete dd;
833 } else {
834 fSeed = (Long_t)StringToInteger(seedString);
835 }
836 gRandom->SetSeed(fSeed);
837
838 // if "gdmlFile" is purely a file (without any path) and "geometryPath" is
839 // defined, we recombine them together
840 if ((((string)fGdmlFilename).find_first_not_of("./~") == 0 ||
841 ((string)fGdmlFilename).find('/') == string::npos) &&
842 fGeometryPath != "") {
843 if (fGeometryPath[fGeometryPath.Length() - 1] == '/') {
845 } else {
846 fGdmlFilename = fGeometryPath + "/" + GetParameter("gdmlFile");
847 }
848 }
849
850 Double_t defaultTime = 1. / REST_Units::s;
851 fSubEventTimeDelay = GetDblParameterWithUnits("subEventTimeDelay", defaultTime);
852
853 auto nEventsString = GetParameter("nEvents");
854 if (nEventsString == PARAMETER_NOT_FOUND_STR) {
855 nEventsString = GetParameter("Nevents"); // old name
856 }
857 fNEvents = nEventsString == PARAMETER_NOT_FOUND_STR ? 0 : StringToInteger(nEventsString);
858
859 fStoreTracks = ToUpper(GetParameter("storeTracks", "true")) == "TRUE" ||
860 ToUpper(GetParameter("storeTracks", "on")) == "ON";
861
862 const auto fNRequestedEntriesString = GetParameter("nRequestedEntries");
864 fNRequestedEntriesString == PARAMETER_NOT_FOUND_STR ? 0 : StringToInteger(fNRequestedEntriesString);
865
866 fSaveAllEvents = ToUpper(GetParameter("saveAllEvents", "false")) == "TRUE" ||
867 ToUpper(GetParameter("saveAllEvents", "off")) == "ON";
868
869 fPrintProgress = ToUpper(GetParameter("printProgress", "true")) == "TRUE" ||
870 ToUpper(GetParameter("printProgress", "on")) == "ON";
871
872 fRegisterEmptyTracks = ToUpper(GetParameter("registerEmptyTracks", "false")) == "TRUE" ||
873 ToUpper(GetParameter("registerEmptyTracks", "off")) == "ON";
874
876 // Detector (old storage) section is processed after initializing geometry info in Detector Construction
877 // This allows to use regular expression to match logical or physical volumes etc.
878 ReadBiasing();
879
880 fMaxTargetStepSize = GetDblParameterWithUnits("maxTargetStepSize", -1);
881 if (fMaxTargetStepSize > 0) {
882 cout << " " << endl;
883 RESTWarning << "IMPORTANT: *maxTargetStepSize* parameter is now obsolete!" << RESTendl;
884 RESTWarning << "The sensitive volume will not define any integration step limit" << RESTendl;
885 cout << " " << endl;
886 RESTWarning << "In order to avoid this warning REMOVE the *maxTargetStepSize* definition,"
887 << RESTendl;
888 RESTWarning << "and replace it by the following statement at the <storage> section" << RESTendl;
889 cout << " " << endl;
890 RESTWarning << "<activeVolume name=\"" << this->GetSensitiveVolume() << "\" maxStepSize=\""
891 << fMaxTargetStepSize << "mm\" />" << RESTendl;
892 cout << " " << endl;
893 RESTInfo << "Now, any active volume is allowed to define a maxStepSize" << RESTendl;
894 cout << " " << endl;
895 RESTInfo << "It is also possible to define a default step size for all active volumes," << RESTendl;
896 RESTInfo << "so that in case no step is defined, the default will be used." << RESTendl;
897 cout << " " << endl;
898 RESTInfo << "<storage sensitiveVolume=\"" << this->GetSensitiveVolume() << "\" maxStepSize=\""
899 << fMaxTargetStepSize << "mm\" />" << RESTendl;
900 cout << " " << endl;
901 GetChar();
902 }
903
904 // should return success or fail
905}
906
925
927 const auto source = GetParticleSource();
928
929 double countsPerSecondPerCm2 = 0;
930 if (TRestGeant4PrimaryGeneratorTypes::StringToEnergyDistributionTypes(
931 source->GetEnergyDistributionType().Data()) ==
932 TRestGeant4PrimaryGeneratorTypes::EnergyDistributionTypes::FORMULA2 &&
933 TRestGeant4PrimaryGeneratorTypes::StringToAngularDistributionTypes(
934 source->GetAngularDistributionType().Data()) ==
935 TRestGeant4PrimaryGeneratorTypes::AngularDistributionTypes::FORMULA2) {
936 const auto energyRange = source->GetEnergyDistributionRange();
937 const auto angularRange = source->GetAngularDistributionRange();
938 auto function = (TF2*)source->GetEnergyAndAngularDistributionFunction()->Clone();
939 // counts per second per cm2 (distribution is already integrated over uniform phi)
940 countsPerSecondPerCm2 =
941 function->Integral(energyRange.X(), energyRange.Y(), angularRange.X(), angularRange.Y(), 1E-9);
942 }
943
944 else if (std::string(source->GetName()) == "TRestGeant4ParticleSourceCosmics") {
945 auto cosmicSource = dynamic_cast<TRestGeant4ParticleSourceCosmics*>(source);
946 const auto names = cosmicSource->GetParticleNames();
947 const auto histograms = cosmicSource->GetHistogramsTransformed();
948 for (const auto& name : names) {
949 countsPerSecondPerCm2 += histograms.at(name)->Integral();
950 }
951 } else if (TRestGeant4PrimaryGeneratorTypes::StringToEnergyDistributionTypes(
952 source->GetEnergyDistributionType().Data()) ==
953 TRestGeant4PrimaryGeneratorTypes::EnergyDistributionTypes::TH2D &&
954 TRestGeant4PrimaryGeneratorTypes::StringToAngularDistributionTypes(
955 source->GetAngularDistributionType().Data()) ==
956 TRestGeant4PrimaryGeneratorTypes::AngularDistributionTypes::TH2D) {
957 const auto filename = source->GetEnergyDistributionFilename();
958 const auto name = source->GetEnergyDistributionNameInFile();
959 TFile* file = TFile::Open(filename);
960 auto energyAndAngularDistributionHistogram =
961 file->Get<TH2D>(name); // it's the same for both angular and energy
962 if (energyAndAngularDistributionHistogram == nullptr) {
963 throw std::runtime_error("Histogram not found in file");
964 }
965 countsPerSecondPerCm2 = energyAndAngularDistributionHistogram->Integral();
966 file->Close();
967 delete file;
968 }
969
970 else {
971 throw std::runtime_error("Cosmic flux calculation is only supported for TFormula2 or TH2D sources");
972 }
973
974 return countsPerSecondPerCm2;
975}
976
977Double_t TRestGeant4Metadata::GetCosmicIntensityInCountsPerSecond() const {
978 const auto countsPerSecondPerCm2 = GetCosmicFluxInCountsPerCm2PerSecond();
979 const auto surface = GetGeneratorSurfaceCm2();
980 const auto countsPerSecond = countsPerSecondPerCm2 * surface;
981 return countsPerSecond;
982}
983
986
987 double scalingFactor = 1.0;
988 if (type == "cosmic") {
989 // get the cosmic generator
990 auto cosmicSource = dynamic_cast<TRestGeant4ParticleSourceCosmics*>(GetParticleSource());
991 if (cosmicSource != nullptr) {
992 scalingFactor =
993 cosmicSource
994 ->GetEnergyRangeScalingFactor(); // number less than 1, to account for energy range
995 if (scalingFactor < 0 || scalingFactor > 1) {
996 throw std::runtime_error("Energy range scaling factor must be between 0 and 1");
997 }
998 }
999 }
1000
1001 // counts per seconds should be reduced proportionally to the range we are sampling
1002 const auto countsPerSecond = GetCosmicIntensityInCountsPerSecond() * scalingFactor;
1003 const auto seconds = double(fNEvents) / countsPerSecond;
1004
1005 return seconds;
1006}
1007
1008void TRestGeant4Metadata::ReadBiasing() {
1009 TiXmlElement* biasingDefinition = GetElement("biasing");
1010 if (biasingDefinition == nullptr) {
1011 fNBiasingVolumes = 0;
1012 return;
1013 }
1014 TString biasEnabled = GetFieldValue("value", biasingDefinition);
1015 TString biasType = GetFieldValue("type", biasingDefinition);
1016
1017 RESTDebug << "Bias: " << biasEnabled << RESTendl;
1018
1019 if (biasEnabled == "on" || biasEnabled == "ON" || biasEnabled == "On" || biasEnabled == "oN") {
1020 RESTInfo << "Biasing is enabled" << RESTendl;
1021
1022 TiXmlElement* biasVolumeDefinition = GetElement("biasingVolume", biasingDefinition);
1023 Int_t n = 0;
1024 while (biasVolumeDefinition) {
1025 TRestGeant4BiasingVolume biasVolume;
1026 RESTDebug << "Def: " << biasVolumeDefinition << RESTendl;
1027
1028 biasVolume.SetBiasingVolumePosition(
1029 Get3DVectorParameterWithUnits("position", biasVolumeDefinition));
1030 biasVolume.SetBiasingFactor(StringToDouble(GetParameter("factor", biasVolumeDefinition)));
1031 biasVolume.SetBiasingVolumeSize(GetDblParameterWithUnits("size", biasVolumeDefinition));
1032 biasVolume.SetEnergyRange(Get2DVectorParameterWithUnits("energyRange", biasVolumeDefinition));
1033 biasVolume.SetBiasingVolumeType(biasType); // For the moment all the volumes should be same type
1034
1035 /* TODO check that values are right if not printBiasingVolume with
1036 getchar() biasVolume.PrintBiasingVolume(); getchar();
1037 */
1038
1039 fBiasingVolumes.push_back(biasVolume);
1040 biasVolumeDefinition = GetNextElement(biasVolumeDefinition);
1041 n++;
1042 }
1043 fNBiasingVolumes = n;
1044 }
1045}
1046
1072 // TODO if some fields are defined in the generator but not finally used
1073 // i.e. <generator type="volume" from="gasTarget" position="(100,0,-100)
1074 // here position is irrelevant since the event will be generated from the
1075 // volume defined in the geometry we should take care of these values so they
1076 // are not stored in metadata (to avoid future confusion) In the particular
1077 // case of position, the value is overwritten in DetectorConstruction by the
1078 // center of the volume (i.e. gasTarget) but if i.e rotation or side are
1079 // defined and not relevant we should set it to -1
1080
1081 TiXmlElement* generatorDefinition = GetElement("generator");
1082
1084 SpatialGeneratorTypesToString(StringToSpatialGeneratorTypes(GetParameter(
1085 "type", generatorDefinition, SpatialGeneratorTypesToString(SpatialGeneratorTypes::VOLUME))));
1087 SpatialGeneratorShapesToString(StringToSpatialGeneratorShapes(GetParameter(
1088 "shape", generatorDefinition, SpatialGeneratorShapesToString(SpatialGeneratorShapes::BOX))));
1089 fGeant4PrimaryGeneratorInfo.fSpatialGeneratorFrom = GetParameter("from", generatorDefinition);
1090 if (fGeant4PrimaryGeneratorInfo.fSpatialGeneratorFrom != PARAMETER_NOT_FOUND_STR) {
1092 SpatialGeneratorShapesToString(SpatialGeneratorShapes::GDML);
1093 }
1095 Get3DVectorParameterWithUnits("size", generatorDefinition, {0, 0, 0});
1097 Get3DVectorParameterWithUnits("position", generatorDefinition, {0, 0, 0});
1099 Get3DVectorParameterWithUnits("rotationAxis", generatorDefinition, {0, 0, 1});
1101 GetDblParameterWithUnits("rotationAngle", generatorDefinition, 0);
1103 GetParameter("densityFunc", generatorDefinition, "1");
1104
1105 TiXmlElement* sourceDefinition = GetElement("source", generatorDefinition);
1106 while (sourceDefinition) {
1107 string use = GetParameter("use", sourceDefinition, "");
1108
1109 TRestGeant4ParticleSource* source = TRestGeant4ParticleSource::instantiate(use);
1110 ReadParticleSource(source, sourceDefinition);
1111 AddParticleSource(source);
1112
1113 if (string(source->GetName()) == "TRestGeant4ParticleSourceCosmics") {
1114 TRestGeant4ParticleSourceCosmics::SetSeed(GetSeed());
1115 }
1116
1117 sourceDefinition = GetNextElement(sourceDefinition);
1118 }
1119
1120 // check if the generator is valid.
1121 if (GetNumberOfSources() == 0) {
1122 RESTError << "No sources are added inside generator!" << RESTendl;
1123 exit(1);
1124 }
1125}
1126
1131 TiXmlElement* sourceDefinition = definition;
1132
1133 source->SetParticleName(GetParameter("particle", sourceDefinition));
1134 source->SetExcitationLevel(StringToDouble(GetParameter("excitedLevel", sourceDefinition)));
1135 source->SetParticleCharge(StringToInteger(GetParameter("charge", sourceDefinition, "0")));
1136
1137 TString fullChain = GetParameter("fullChain", sourceDefinition);
1138 SetFullChain(false);
1139 if (fullChain.EqualTo("on", TString::ECaseCompare::kIgnoreCase)) {
1140 SetFullChain(true);
1141 }
1142
1143 const TString fullChainStopIsotopesString = GetParameter("fullChainStopIsotopes", sourceDefinition, "");
1144 if (fullChainStopIsotopesString != "") {
1145 TObjArray* fullChainStopIsotopesArray = fullChainStopIsotopesString.Tokenize(",");
1146 for (int i = 0; i < fullChainStopIsotopesArray->GetEntries(); i++) {
1147 TString isotope = ((TObjString*)fullChainStopIsotopesArray->At(i))->String();
1148 fFullChainStopIsotopes.insert(isotope.Data());
1149 }
1150 }
1151
1152 // Angular distribution parameters
1153 TiXmlElement* angularDefinition = GetElement("angular", sourceDefinition);
1154 if (angularDefinition == nullptr) {
1155 angularDefinition = GetElement("angularDist", sourceDefinition); // old name
1156 }
1157 source->SetAngularDistributionType(GetParameter(
1158 "type", angularDefinition, AngularDistributionTypesToString(AngularDistributionTypes::FLUX)));
1159 if ((StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1160 AngularDistributionTypes::TH1D) ||
1161 (StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1162 AngularDistributionTypes::TH2D)) {
1163 source->SetAngularDistributionFilename(SearchFile(GetParameter("file", angularDefinition)));
1164 auto name = GetParameter("name", angularDefinition);
1165 if (name == "NO_SUCH_PARA") {
1166 name = GetParameter("spctName", angularDefinition); // old name
1167 }
1168 source->SetAngularDistributionNameInFile(name);
1169 }
1170 source->SetAngularDistributionRange(
1171 Get2DVectorParameterWithUnits("range", angularDefinition, {0, TMath::Pi()}));
1172 if (StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1173 AngularDistributionTypes::FORMULA) {
1174 source->SetAngularDistributionFormula(GetParameter("name", angularDefinition));
1175 // We cannot use an angular range bigger than the range of the formula
1176 const auto function = source->GetAngularDistributionFunction();
1177 if (source->GetAngularDistributionRangeMin() < function->GetXaxis()->GetXmin()) {
1178 source->SetAngularDistributionRange(
1179 {function->GetXaxis()->GetXmin(), source->GetAngularDistributionRangeMax()});
1180 }
1181 if (source->GetAngularDistributionRangeMax() > function->GetXaxis()->GetXmax()) {
1182 source->SetAngularDistributionRange(
1183 {source->GetAngularDistributionRangeMin(), function->GetXaxis()->GetXmax()});
1184 }
1185 }
1186 if ((StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1187 AngularDistributionTypes::FORMULA) ||
1188 (StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1189 AngularDistributionTypes::FORMULA2)) {
1190 source->SetAngularDistributionFormulaNPoints(static_cast<size_t>(GetDblParameterWithUnits(
1191 "nPoints", angularDefinition, source->GetAngularDistributionFormulaNPoints())));
1192 }
1193 if (GetNumberOfSources() == 0 &&
1194 StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1195 AngularDistributionTypes::BACK_TO_BACK) {
1196 cout << "WARNING: First source cannot be backtoback. Setting it to isotropic" << endl;
1197 source->SetAngularDistributionType(
1198 AngularDistributionTypesToString(AngularDistributionTypes::ISOTROPIC));
1199 }
1200 source->SetDirection(StringTo3DVector(GetParameter("direction", angularDefinition, "(1,0,0)")));
1201
1202 if ((StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1203 AngularDistributionTypes::ISOTROPIC)) {
1204 source->SetAngularDistributionRange({0, TMath::Pi()});
1205 const double coneHalfAngle = GetDblParameterWithUnits("coneHalfAngle", angularDefinition, 0);
1206 source->SetAngularDistributionIsotropicConeHalfAngle(coneHalfAngle);
1207 }
1208 // Energy distribution parameters
1209 TiXmlElement* energyDefinition = GetElement("energy", sourceDefinition);
1210 if (energyDefinition == nullptr) {
1211 energyDefinition = GetElement("energyDist", sourceDefinition); // old name
1212 }
1213 source->SetEnergyDistributionType(GetParameter(
1214 "type", energyDefinition, EnergyDistributionTypesToString(EnergyDistributionTypes::MONO)));
1215 if ((StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1216 EnergyDistributionTypes::TH1D) ||
1217 (StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1218 EnergyDistributionTypes::TH2D)) {
1219 source->SetEnergyDistributionFilename(SearchFile(GetParameter("file", energyDefinition)));
1220 auto name = GetParameter("name", energyDefinition);
1221 if (name == "NO_SUCH_PARA") {
1222 name = GetParameter("spctName", energyDefinition); // old name
1223 }
1224 source->SetEnergyDistributionNameInFile(name);
1225 }
1226 source->SetEnergyDistributionRange(Get2DVectorParameterWithUnits("range", energyDefinition, {0, 1E20}));
1227 if (StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1228 EnergyDistributionTypes::MONO) {
1229 Double_t energy;
1230 energy = GetDblParameterWithUnits("energy", energyDefinition, 0);
1231 source->SetEnergyDistributionRange({energy, energy});
1232 source->SetEnergy(energy);
1233 }
1234 if (StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1235 EnergyDistributionTypes::FORMULA) {
1236 source->SetEnergyDistributionFormula(GetParameter("name", energyDefinition));
1237 // We cannot use an energy range bigger than the range of the formula
1238 const auto function = source->GetEnergyDistributionFunction();
1239 if (source->GetEnergyDistributionRangeMin() < function->GetXaxis()->GetXmin()) {
1240 source->SetEnergyDistributionRange(
1241 {function->GetXaxis()->GetXmin(), source->GetEnergyDistributionRangeMax()});
1242 }
1243 if (source->GetEnergyDistributionRangeMax() > function->GetXaxis()->GetXmax()) {
1244 source->SetEnergyDistributionRange(
1245 {source->GetEnergyDistributionRangeMin(), function->GetXaxis()->GetXmax()});
1246 }
1247 }
1248 if ((StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1249 EnergyDistributionTypes::FORMULA) ||
1250 (StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1251 EnergyDistributionTypes::FORMULA2)) {
1252 source->SetEnergyDistributionFormulaNPoints(static_cast<size_t>(GetDblParameterWithUnits(
1253 "nPoints", energyDefinition, source->GetEnergyDistributionFormulaNPoints())));
1254 }
1255 if (StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1256 EnergyDistributionTypes::FORMULA2 &&
1257 StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1258 AngularDistributionTypes::FORMULA2) {
1259 const auto empty = TString("");
1260 auto energyDistName = GetParameter("name", energyDefinition, empty);
1261 auto angularDistName = GetParameter("name", energyDefinition, empty);
1262
1263 if (energyDistName == empty && angularDistName == empty) {
1264 RESTError << "No name specified for energy and angular distribution" << RESTendl;
1265 exit(1);
1266 }
1267 if (energyDistName == empty) {
1268 angularDistName = energyDistName;
1269 RESTWarning << "No name specified for energy distribution. Using angular distribution name: "
1270 << angularDistName << RESTendl;
1271 }
1272 if (angularDistName == empty) {
1273 energyDistName = energyDistName;
1274 RESTWarning << "No name specified for angular distribution. Using energy distribution name: "
1275 << energyDistName << RESTendl;
1276 }
1277
1278 if (energyDistName == empty || angularDistName == empty) {
1279 // we should never enter here, just leave this as a check
1280 RESTError << "When using 'formula2' the name of energy and angular dist must match" << RESTendl;
1281 exit(1);
1282 }
1283 const auto energyAndAngularDistName = energyDistName;
1284 source->SetEnergyAndAngularDistributionFormula(energyAndAngularDistName);
1285
1286 const auto function = source->GetEnergyAndAngularDistributionFunction();
1287
1288 // Set energy range
1289 if (source->GetEnergyDistributionRangeMin() < function->GetXaxis()->GetXmin()) {
1290 source->SetEnergyDistributionRange(
1291 {function->GetXaxis()->GetXmin(), source->GetEnergyDistributionRangeMax()});
1292 }
1293 if (source->GetEnergyDistributionRangeMax() > function->GetXaxis()->GetXmax()) {
1294 source->SetEnergyDistributionRange(
1295 {source->GetEnergyDistributionRangeMin(), function->GetXaxis()->GetXmax()});
1296 }
1297
1298 // Set angular range
1299 if (source->GetAngularDistributionRangeMin() < function->GetYaxis()->GetXmin()) {
1300 source->SetAngularDistributionRange(
1301 {function->GetYaxis()->GetXmin(), source->GetAngularDistributionRangeMax()});
1302 }
1303 if (source->GetAngularDistributionRangeMax() > function->GetYaxis()->GetXmax()) {
1304 source->SetAngularDistributionRange(
1305 {source->GetAngularDistributionRangeMin(), function->GetYaxis()->GetXmax()});
1306 }
1307 }
1308 // allow custom configuration from the class
1309 source->LoadConfigFromElement(sourceDefinition, fElementGlobal, fVariables);
1310 // AddParticleSource(source);
1311}
1312
1314 for (auto source : fParticleSource) {
1315 delete source;
1316 }
1317 fParticleSource.clear();
1318}
1319
1321 fParticleSource.push_back(src);
1322}
1323
1339 RESTInfo << "TRestGeant4Metadata: Processing detector section" << RESTendl;
1340 TiXmlElement* detectorDefinition = GetElement("detector");
1341 if (detectorDefinition == nullptr) {
1342 RESTError << "Detector section (<detector>) is not present in metadata!" << RESTendl;
1343 exit(1);
1344 }
1345
1346 const bool activateAllVolumes =
1347 StringToBool(GetParameter("activateAllVolumes", detectorDefinition, "true"));
1348 RESTInfo << "TRestGeant4Metadata: Setting 'fActivateAllVolumes' to " << fActivateAllVolumes << RESTendl;
1349 fActivateAllVolumes = activateAllVolumes;
1350
1351 TiXmlElement* removeUnwantedTracksDefinition = GetElement("removeUnwantedTracks", detectorDefinition);
1352 if (removeUnwantedTracksDefinition != nullptr) {
1353 fRemoveUnwantedTracks = StringToBool(GetParameter("enabled", removeUnwantedTracksDefinition, "true"));
1355 StringToBool(GetParameter("keepZeroEnergyTracks", removeUnwantedTracksDefinition, "false"));
1356 RESTInfo << "TRestGeant4Metadata: Setting 'fRemoveUnwantedTracks' to " << fRemoveUnwantedTracks
1357 << " with 'keepZeroEnergyTracks' option set to " << fRemoveUnwantedTracksKeepZeroEnergyTracks
1358 << RESTendl;
1359 }
1360
1361 Double_t defaultStep = GetDblParameterWithUnits("maxStepSize", detectorDefinition);
1362 if (defaultStep < 0) {
1363 defaultStep = 0;
1364 }
1365
1366 TiXmlElement* volumeDefinition = GetElement("volume", detectorDefinition);
1367 while (volumeDefinition != nullptr) {
1368 string name = GetFieldValue("name", volumeDefinition);
1369 if (name.empty() || name == "Not defined") {
1370 RESTError << "volume inside detector section defined without name" << RESTendl;
1371 exit(1);
1372 }
1373 vector<string> physicalVolumes;
1374 if (!fGeant4GeometryInfo.IsValidGdmlName(name)) {
1375 if (fGeant4GeometryInfo.IsValidLogicalVolume(name)) {
1376 for (const auto& physical : fGeant4GeometryInfo.GetAllPhysicalVolumesFromLogical(name)) {
1377 physicalVolumes.emplace_back(
1378 fGeant4GeometryInfo.GetAlternativeNameFromGeant4PhysicalName(physical));
1379 }
1380 }
1381 // does not match a explicit (gdml) physical name or a logical name, perhaps its a regular exp
1382 if (physicalVolumes.empty()) {
1383 for (const auto& physical :
1384 fGeant4GeometryInfo.GetAllPhysicalVolumesMatchingExpression(name)) {
1385 physicalVolumes.emplace_back(
1386 fGeant4GeometryInfo.GetAlternativeNameFromGeant4PhysicalName(physical));
1387 }
1388 }
1389 if (physicalVolumes.empty()) {
1390 for (const auto& logical : fGeant4GeometryInfo.GetAllLogicalVolumesMatchingExpression(name)) {
1391 for (const auto& physical :
1392 fGeant4GeometryInfo.GetAllPhysicalVolumesFromLogical(logical)) {
1393 physicalVolumes.emplace_back(
1394 fGeant4GeometryInfo.GetAlternativeNameFromGeant4PhysicalName(physical));
1395 }
1396 }
1397 }
1398 } else {
1399 physicalVolumes.push_back(name);
1400 }
1401
1402 if (physicalVolumes.empty()) {
1403 RESTError
1404 << "volume '" << name
1405 << "' is not defined in the geometry. Could not match to a physical, logical volume or regex"
1406 << RESTendl;
1407 exit(1);
1408 }
1409
1410 bool isSensitive = false;
1411 const string isSensitiveValue = GetFieldValue("sensitive", volumeDefinition);
1412 if (isSensitiveValue != "Not defined") {
1413 isSensitive = StringToBool(isSensitiveValue);
1414 }
1415
1416 bool isKeepTracks = isSensitive;
1417 const string isKeepTracksValue = GetFieldValue("keepTracks", volumeDefinition);
1418 if (isKeepTracksValue != "Not defined") {
1419 isKeepTracks = StringToBool(isKeepTracksValue);
1420 }
1421
1422 bool isKill = false;
1423 const string isKillValue = GetFieldValue("kill", volumeDefinition);
1424 if (isKillValue != "Not defined") {
1425 isKill = StringToBool(isKillValue);
1426 }
1427
1428 Double_t chance = StringToDouble(GetFieldValue("chance", volumeDefinition));
1429 if (chance == -1 || chance < 0) {
1430 chance = 1.0;
1431 }
1432 Double_t maxStep = GetDblParameterWithUnits("maxStepSize", volumeDefinition);
1433 if (maxStep < 0) {
1434 maxStep = defaultStep;
1435 }
1436
1437 for (const auto& physical : physicalVolumes) {
1438 RESTInfo << "Adding " << (isSensitive ? "sensitive" : "active") << " volume from RML: '"
1439 << physical << (chance != 1 ? " with change: " + to_string(chance) : " ") << RESTendl;
1440 SetActiveVolume(physical, chance, maxStep);
1441 if (isSensitive) {
1442 InsertSensitiveVolume(physical);
1443 }
1444 if (fRemoveUnwantedTracks && isKeepTracks) {
1445 fRemoveUnwantedTracksVolumesToKeep.insert(physical);
1446 }
1447 if (isKill) {
1448 fKillVolumes.insert(physical);
1449 }
1450 }
1451 volumeDefinition = GetNextElement(volumeDefinition);
1452 }
1453
1454 if (fSensitiveVolumes.empty()) {
1455 cout << "No sensitive volumes defined in detector section. Adding 'gas' as sensitive volume" << endl;
1456 InsertSensitiveVolume("gas");
1457 }
1458
1459 fEnergyRangeStored = Get2DVectorParameterWithUnits("energyRange", detectorDefinition, fEnergyRangeStored);
1460 // TODO: Place this as a generic method
1461 if (fEnergyRangeStored.X() < 0) {
1463 }
1464 if (fEnergyRangeStored.Y() < 0) {
1466 }
1467 if (fEnergyRangeStored.Y() > fEnergyRangeStored.Y()) {
1469 }
1470 if (fEnergyRangeStored.Y() <= 0) {
1471 RESTError << "Energy range is not valid: (" << fEnergyRangeStored.X() << ", "
1472 << fEnergyRangeStored.Y() << ") keV" << RESTendl;
1473 exit(1);
1474 }
1475
1476 auto gdml = new TRestGDMLParser();
1477 gdml->Load(GetGdmlFilename().Data());
1478
1479 fGeant4GeometryInfo.PopulateFromGdml(gdml->GetOutputGDMLFile());
1480
1481 // If the user did not add explicitly any volume to the storage section we understand
1482 // the user wants to register all the volumes
1483 if (fActivateAllVolumes) {
1484 for (const auto& name : fGeant4GeometryInfo.GetAllPhysicalVolumes()) {
1485 if (!IsActiveVolume(name)) {
1486 SetActiveVolume(name, 1, defaultStep);
1487 RESTInfo << "Automatically adding active volume: '" << name << "' with chance: " << 1
1488 << RESTendl;
1489 }
1490 }
1491 }
1492
1493 if (GetNumberOfActiveVolumes() == 0) {
1494 RESTError << "No active volumes defined. Please check the detector section" << RESTendl;
1495 exit(1);
1496 }
1497}
1498
1505
1506 RESTMetadata << "Geant4 version: " << GetGeant4Version() << RESTendl;
1507 RESTMetadata << "Random seed: " << GetSeed() << RESTendl;
1508 RESTMetadata << "GDML geometry: " << GetGdmlReference() << RESTendl;
1509 RESTMetadata << "GDML materials reference: " << GetMaterialsReference() << RESTendl;
1510 RESTMetadata << "Sub-event time delay: " << GetSubEventTimeDelay() << " us" << RESTendl;
1511 Double_t mx = GetMagneticField().X();
1512 Double_t my = GetMagneticField().Y();
1513 Double_t mz = GetMagneticField().Z();
1514 RESTMetadata << "Magnetic field: (" << mx << ", " << my << ", " << mz << ") T" << RESTendl;
1515 if (fSaveAllEvents) RESTMetadata << "Save all events was enabled!" << RESTendl;
1517 RESTMetadata << "Register empty tracks was enabled" << RESTendl;
1518 } else {
1519 RESTMetadata << "Register empty tracks was NOT enabled" << RESTendl;
1520 }
1521
1522 RESTMetadata << " " << RESTendl;
1523 RESTMetadata << " ++++++++++ Generator +++++++++++ " << RESTendl;
1524 RESTMetadata << "Number of generated events: " << GetNumberOfEvents() << RESTendl;
1526
1527 for (int i = 0; i < GetNumberOfSources(); i++) GetParticleSource(i)->PrintMetadata();
1528
1529 RESTMetadata << " " << RESTendl;
1530 RESTMetadata << " ++++++++++ Detector +++++++++++ " << RESTendl;
1531 RESTMetadata << "Energy range (keV): (" << GetMinimumEnergyStored() << ", " << GetMaximumEnergyStored()
1532 << ")" << RESTendl;
1533 RESTMetadata << "Number of sensitive volumes: " << GetNumberOfSensitiveVolumes() << RESTendl;
1534 for (const auto& sensitiveVolume : fSensitiveVolumes) {
1535 RESTMetadata << "Sensitive volume: " << sensitiveVolume << RESTendl;
1536 }
1537 RESTMetadata << "Number of active volumes: " << GetNumberOfActiveVolumes() << RESTendl;
1538 for (unsigned int n = 0; n < GetNumberOfActiveVolumes(); n++) {
1539 const auto name = GetActiveVolumeName(n);
1540 RESTMetadata << "Name: " << name << ", ID: " << fGeant4GeometryInfo.GetIDFromVolume(name)
1541 << ", maxStep: " << GetMaxStepSize(name) << "mm "
1542 << ", chance: " << GetStorageChance(name) << RESTendl;
1543 }
1544
1545 for (unsigned int n = 0; n < GetNumberOfBiasingVolumes(); n++) {
1546 GetBiasingVolume(n).PrintBiasingVolume();
1547 }
1548
1549 if (GetRemoveUnwantedTracks()) {
1550 RESTMetadata << "removeUnwantedTracks is enabled "
1551 << (fRemoveUnwantedTracksKeepZeroEnergyTracks ? "with" : "without")
1552 << " keeping zero energy tracks" << RESTendl;
1553
1554 /*
1555 RESTMetadata << "keep volumes for removeUnwantedTracks:" << RESTendl;
1556 for (const auto& volume : fRemoveUnwantedTracksVolumesToKeep) {
1557 RESTMetadata << "\t" << volume << RESTendl;
1558 }
1559 */
1560 }
1561
1562 RESTMetadata << "+++++" << RESTendl;
1563}
1564
1567Int_t TRestGeant4Metadata::GetActiveVolumeID(const TString& name) {
1568 Int_t id;
1569 for (id = 0; id < (Int_t)fActiveVolumes.size(); id++) {
1570 if (fActiveVolumes[id] == name) return id;
1571 }
1572 return -1;
1573}
1574
1589void TRestGeant4Metadata::SetActiveVolume(const TString& name, Double_t chance, Double_t maxStep) {
1590 for (size_t i = 0; i < fActiveVolumes.size(); i++) {
1591 const auto activeVolumeName = fActiveVolumes[i];
1592 if (name == activeVolumeName) {
1593 fChance[i] = chance;
1594 fMaxStepSize[i] = maxStep;
1595 return;
1596 }
1597 }
1598 fActiveVolumes.push_back(name);
1599 fChance.push_back(chance);
1600 fMaxStepSize.push_back(maxStep);
1601 fActiveVolumesSet.insert(name.Data());
1602}
1603
1604double TRestGeant4Metadata::GetGeneratorSurfaceCm2() const {
1607
1608 if (type == "surface" && shape == "circle") {
1609 const auto radius = fGeant4PrimaryGeneratorInfo.GetSpatialGeneratorSize().X();
1610 return TMath::Pi() * radius * radius * 0.01; // cm2
1611 } else if (type == "cosmic") {
1613 }
1614
1615 throw std::runtime_error(
1616 "TRestGeant4Metadata::GetGeneratorSurfaceCm2: Can only be called for 'cosmic' and 'surface/circle' "
1617 "generators");
1618}
1619
1624Bool_t TRestGeant4Metadata::isVolumeStored(const TString& volume) const {
1625 for (unsigned int n = 0; n < GetNumberOfActiveVolumes(); n++) {
1626 if (GetActiveVolumeName(n) == volume) {
1627 return true;
1628 }
1629 }
1630
1631 return false;
1632}
1633
1637Double_t TRestGeant4Metadata::GetStorageChance(const TString& volume) {
1638 for (auto id = 0; id < (Int_t)fActiveVolumes.size(); id++) {
1639 {
1640 if (fActiveVolumes[id] == volume) {
1641 return fChance[id];
1642 }
1643 }
1644 }
1645 RESTWarning << "TRestGeant4Metadata::GetStorageChance. Volume " << volume << " not found" << RESTendl;
1646
1647 return 0;
1648}
1649
1653Double_t TRestGeant4Metadata::GetMaxStepSize(const TString& volume) {
1654 for (Int_t i = 0; i < (Int_t)fActiveVolumes.size(); i++) {
1655 if (volume.EqualTo(fActiveVolumes[i], TString::kIgnoreCase)) {
1656 return fMaxStepSize[i];
1657 }
1658 }
1659 RESTWarning << "TRestGeant4Metadata::GetMaxStepSize. Volume " << volume << " not found" << RESTendl;
1660
1661 return 0;
1662}
1663
1664size_t TRestGeant4Metadata::GetGeant4VersionMajor() const {
1665 TString majorVersion = "";
1666 for (int i = 0; i < fGeant4Version.Length(); i++) {
1667 auto c = fGeant4Version[i];
1668 if (c == '.') {
1669 break;
1670 }
1671 majorVersion += c;
1672 }
1673 return std::stoi(majorVersion.Data());
1674}
1675
1676void TRestGeant4Metadata::Merge(const TRestGeant4Metadata& metadata) {
1677 fIsMerge = true;
1678 fSeed = 0; // seed makes no sense in a merged file
1679
1680 fNEvents += metadata.fNEvents;
1682 fSimulationTime += metadata.fSimulationTime;
1683}
1684
1686 *this = metadata;
1687}
1688
1689TRestGeant4Metadata& TRestGeant4Metadata::operator=(const TRestGeant4Metadata& metadata) {
1690 fIsMerge = metadata.fIsMerge;
1694 fGeant4Version = metadata.fGeant4Version;
1695 fGdmlReference = metadata.fGdmlReference;
1698 fActiveVolumes = metadata.fActiveVolumes;
1699 fChance = metadata.fChance;
1700 fMaxStepSize = metadata.fMaxStepSize;
1701 // fParticleSource = metadata.fParticleSource; // segfaults (pointers!)
1706 fFullChain = metadata.fFullChain;
1708 fNEvents = metadata.fNEvents;
1710 fStoreTracks = metadata.fStoreTracks;
1712 fSeed = metadata.fSeed;
1713 fSaveAllEvents = metadata.fSaveAllEvents;
1717 fKillVolumes = metadata.fKillVolumes;
1719 fMagneticField = metadata.fMagneticField;
1720 return *this;
1721}
The main class to store the Geant4 simulation conditions that will be used by restG4.
std::vector< TString > fSensitiveVolumes
The volume that serves as trigger for data storage. Only events that deposit a non-zero energy on thi...
void ReadGenerator()
Reads the generator section defined inside TRestGeant4Metadata.
Long_t GetSeed() const
// Used for faster lookup
std::vector< TRestGeant4BiasingVolume > fBiasingVolumes
A std::vector containing the biasing volume properties.
Bool_t fFullChain
Defines if a radioactive isotope decay is simulated in full chain (fFullChain=true),...
size_t GetNumberOfBiasingVolumes() const
Returns the number of biasing volumes defined.
Bool_t fStoreTracks
Store event tracks (default is true)
void ReadDetector()
Reads the storage section defined inside TRestGeant4Metadata.
Bool_t fActivateAllVolumes
Sets all volume as active without having to explicitly list them.
TString fGeometryPath
The local path to the GDML geometry.
TString GetSensitiveVolume(int n=0) const
Returns a std::string with the name of the sensitive volume.
TVector3 GetMagneticField() const
Returns the world magnetic field in Tesla.
void AddParticleSource(TRestGeant4ParticleSource *src)
Adds a new particle source.
Int_t GetActiveVolumeID(const TString &name)
Returns the id of an active volume giving as parameter its name.
TRestGeant4Metadata()
Default constructor.
void InitFromConfigFile() override
Initialization of TRestGeant4Metadata members through a RML file.
TString fMaterialsReference
A GDML materials reference introduced in the header of the GDML of materials definition.
TString GetGdmlReference() const
Returns the reference provided at the GDML file header.
Int_t fNBiasingVolumes
The number of biasing volumes used in the simulation. If zero, no biasing technique is used.
void Initialize() override
Initialization of TRestGeant4Metadata members.
void PrintMetadata() override
Prints on screen the details about the Geant4 simulation conditions, stored in TRestGeant4Metadata.
void SetActiveVolume(const TString &name, Double_t chance, Double_t maxStep=0)
Adds a geometry volume to the list of active volumes.
Double_t GetMinimumEnergyStored() const
Returns the minimum event energy required for an event to be stored.
TRestGeant4GeometryInfo fGeant4GeometryInfo
Class used to store and retrieve geometry info.
unsigned int GetNumberOfActiveVolumes() const
Returns the number of active volumes, or geometry volumes that have been selected for data storage.
Double_t GetSubEventTimeDelay() const
Returns the time gap, in us, required to consider a Geant4 hit as a new independent event....
TString fGdmlReference
A GDML geometry reference introduced in the header of the GDML main setup.
Double_t GetMaxStepSize(const TString &volume)
Returns the maximum step at a particular active volume.
Bool_t fStoreHadronicTargetInfo
Option to store target isotope information on hadronic processes (disabled by default)
~TRestGeant4Metadata()
Default destructor.
std::vector< Double_t > fMaxStepSize
A std::vector to store the maximum step size at a particular volume.
std::set< std::string > fRemoveUnwantedTracksVolumesToKeep
A container related to fRemoveUnwantedTracks.
TVector2 fEnergyRangeStored
A 2d-std::vector storing the energy range, in keV, to decide if a particular event should be written ...
TVector3 fMagneticField
The world magnetic field.
TRestGeant4PhysicsInfo fGeant4PhysicsInfo
Class used to store and retrieve physics info such as process names or particle names.
TRestGeant4BiasingVolume GetBiasingVolume(int n)
Return the biasing volume with index n.
TString fGeant4Version
The version of Geant4 used to generate the data.
TString GetActiveVolumeName(Int_t n) const
Returns a std::string with the name of the active volume with index n.
std::vector< TString > fActiveVolumes
A std::vector to store the names of the active volumes.
TString GetGeant4Version() const
Returns a std::string with the version of Geant4 used on the event data simulation.
Long64_t fNEvents
The number of events simulated, or to be simulated.
Long_t fSeed
The seed value used for Geant4 random event generator. If it is zero its value will be assigned using...
Double_t fSimulationMaxTimeSeconds
Time before simulation is ended and saved.
void SetFullChain(Bool_t fullChain)
Enables/disables the full chain decay generation.
Long64_t GetNumberOfEvents() const
Returns the number of events to be simulated.
Int_t GetNumberOfSources() const
Returns the number of primary event sources defined in the generator.
void RemoveParticleSources()
Remove all the particle sources.
std::vector< Double_t > fChance
A std::vector to store the probability value to write to disk the hits in a particular event.
std::set< std::string > fFullChainStopIsotopes
If defined, it will stop the full chain decay simulation when one of these isotope appears.
Double_t GetCosmicFluxInCountsPerCm2PerSecond() const
Reads the biasing section defined inside TRestGeant4Metadata.
Bool_t fPrintProgress
If this parameter is set to 'true' it will print out on screen every time 10k events are reached.
Bool_t fSaveAllEvents
If this parameter is set to 'true' it will save all events even if they leave no energy in the sensit...
Double_t fMaxTargetStepSize
The maximum target step size, in mm, allowed in Geant4 for the target volume (usually the gas volume)...
Double_t GetMaximumEnergyStored() const
Returns the maximum event energy required for an event to be stored.
std::vector< TRestGeant4ParticleSource * > fParticleSource
It the defines the primary source properties, particle type, momentum, energy, etc.
Bool_t fRegisterEmptyTracks
If this parameter is enabled it will register tracks with no hits inside. This is the default behavio...
Double_t GetStorageChance(Int_t n) const
Returns the probability per event to register (write to disk) hits in the storage volume with index n...
Double_t fSubEventTimeDelay
A time gap, in us, determining if an energy hit should be considered (and stored) as an independent e...
TString fGdmlFilename
The filename of the GDML geometry.
Bool_t fRemoveUnwantedTracks
If activated will remove tracks not present in volumes marked as "keep" or "sensitive".
void ReadParticleSource(TRestGeant4ParticleSource *src, TiXmlElement *sourceDefinition)
It reads the <source definition given by argument.
TRestGeant4PrimaryGeneratorInfo fGeant4PrimaryGeneratorInfo
Class used to store and retrieve Geant4 primary generator info.
Long64_t fNRequestedEntries
The number of events the user requested to be on the file.
TString GetGdmlFilename() const
Returns the main filename of the GDML geometry.
Bool_t isVolumeStored(const TString &volume) const
Returns true if the volume named volName has been registered for data storage.
Double_t fSimulationTime
The time, in seconds, that the simulation took to complete (wall time)
TRestGeant4ParticleSource * GetParticleSource(size_t n=0) const
Returns the name of the particle source with index n (Geant4 based names).
Double_t GetEquivalentSimulatedTime() const
Returns the equivalent simulated time in seconds (physical time simulated)
void InsertSensitiveVolume(const TString &volume)
Sets the name of the sensitive volume.
Bool_t fRemoveUnwantedTracksKeepZeroEnergyTracks
Option for 'removeUnwantedTracks', if enabled tracks with hits in volumes will be kept event if they ...
TString GetMaterialsReference() const
Returns the reference provided at the materials file header.
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)
A base class for any REST metadata class.
Definition: TRestMetadata.h:74
std::map< std::string, std::string > fVariables
Saving a list of rml variables. name-value std::pair.
virtual void PrintMetadata()
Implemented it in the derived metadata class to print out specific metadata information.
endl_t RESTendl
Termination flag object for TRestStringOutput.
TiXmlElement * GetElement(std::string eleDeclare, TiXmlElement *e=nullptr)
Get an xml element from a given parent element, according to its declaration.
Int_t LoadConfigFromFile(const std::string &configFilename, const std::string &sectionName="")
Give the file name, find out the corresponding section. Then call the main starter.
TiXmlElement * fElementGlobal
Saving the global element, to be passed to the resident class, if necessary.
void SetLibraryVersion(TString version)
Set the library version of this metadata class.
std::string GetFieldValue(std::string parName, TiXmlElement *e)
Returns the field value of an xml element which has the specified name.
Int_t LoadConfigFromElement(TiXmlElement *eSectional, TiXmlElement *eGlobal, std::map< std::string, std::string > envs={})
Main starter method.
void SetSectionName(std::string sName)
set the section name, clear the section content
std::string SearchFile(std::string filename)
Search files in current directory and directories specified in "searchPath" section.
std::string fConfigFileName
Full name of the rml file.
TiXmlElement * GetNextElement(TiXmlElement *e)
Get the next sibling xml element of this element, with same eleDeclare.
std::string GetParameter(std::string parName, TiXmlElement *e, TString defaultValue=PARAMETER_NOT_FOUND_STR)
Returns the value for the parameter named parName in the given section.
static std::string DownloadRemoteFile(const std::string &remoteFile, bool pidPrefix=false)
download the remote file automatically, returns the downloaded file name.
static bool isURL(const std::string &filename)
Returns true if filename is an http address.
Definition: TRestTools.cxx:770
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).