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
753
754#include "TRestGeant4Metadata.h"
755
756#include <TAxis.h>
757#include <TGeoManager.h>
758#include <TObjString.h>
759#include <TRandom.h>
760#include <TRestGDMLParser.h>
761#include <TRestRun.h>
762
763#include "TRestGeant4ParticleSourceCosmics.h"
764#include "TRestGeant4PrimaryGeneratorInfo.h"
765
766using namespace std;
767using namespace TRestGeant4PrimaryGeneratorTypes;
768
769ClassImp(TRestGeant4Metadata);
770
775
790TRestGeant4Metadata::TRestGeant4Metadata(const char* configFilename, const string& name)
791 : TRestMetadata(configFilename) {
792 Initialize();
793
795}
796
801
806 SetSectionName(this->ClassName());
807 SetLibraryVersion(LIBRARY_VERSION);
808
809 fChance.clear();
810 fActiveVolumes.clear();
811 fBiasingVolumes.clear();
812
814}
815
820 this->Initialize();
821
822 fMagneticField = Get3DVectorParameterWithUnits("magneticField", TVector3(0, 0, 0));
823
824 // Initialize the metadata members from a configfile
825 fGdmlFilename = GetParameter("gdmlFile");
826 if (fGdmlFilename == PARAMETER_NOT_FOUND_STR) {
827 fGdmlFilename = GetParameter("gdml_file"); // old name
828 }
829 if (fGdmlFilename == PARAMETER_NOT_FOUND_STR) {
830 cout << "\"gdmlFile\" parameter is not defined!" << endl;
831 exit(1);
832 }
833 if (TRestTools::isURL(fGdmlFilename.Data())) {
834 fGeometryPath = "";
836 if (fGdmlFilename == "") {
837 cout << "Error downloading geometry file from URL: " << fGdmlFilename << endl;
838 exit(1);
839 }
840 }
841
842 fGeometryPath = GetParameter("geometryPath", "");
843 auto volPathSeparator =
844 GetParameter("volPathSeparator", "_"); // for TRestGeant4GeometryInfo::fPathSeparator
845 fGeant4GeometryInfo.SetPathSeparator(volPathSeparator);
846
847 fStoreHadronicTargetInfo = StringToBool(GetParameter("storeHadronicTargetInfo", "false"));
848
849 string seedString = GetParameter("seed", "0");
850 if (ToUpper(seedString) == "RANDOM" || ToUpper(seedString) == "RAND" || ToUpper(seedString) == "AUTO" ||
851 seedString == "0") {
852 auto dd = new double();
853 fSeed = (uintptr_t)dd + (uintptr_t)this;
854 delete dd;
855 } else {
856 fSeed = (Long_t)StringToInteger(seedString);
857 }
858 gRandom->SetSeed(fSeed);
859
860 // if "gdmlFile" is purely a file (without any path) and "geometryPath" is
861 // defined, we recombine them together
862 if ((((string)fGdmlFilename).find_first_not_of("./~") == 0 ||
863 ((string)fGdmlFilename).find('/') == string::npos) &&
864 fGeometryPath != "") {
865 if (fGeometryPath[fGeometryPath.Length() - 1] == '/') {
867 } else {
868 fGdmlFilename = fGeometryPath + "/" + GetParameter("gdmlFile");
869 }
870 }
871
872 Double_t defaultTime = 100. / REST_Units::us;
873 fSubEventTimeDelay = GetDblParameterWithUnits("subEventTimeDelay", defaultTime);
874
875 defaultTime = 1. / REST_Units::us;
876 fResetTimePrecision = GetDblParameterWithUnits("resetTimePrecision", defaultTime);
877
878 auto nEventsString = GetParameter("nEvents");
879 if (nEventsString == PARAMETER_NOT_FOUND_STR) {
880 nEventsString = GetParameter("Nevents"); // old name
881 }
882 fNEvents = nEventsString == PARAMETER_NOT_FOUND_STR ? 0 : StringToInteger(nEventsString);
883
884 fStoreTracks = ToUpper(GetParameter("storeTracks", "true")) == "TRUE" ||
885 ToUpper(GetParameter("storeTracks", "on")) == "ON";
886
887 const auto fNRequestedEntriesString = GetParameter("nRequestedEntries");
889 fNRequestedEntriesString == PARAMETER_NOT_FOUND_STR ? 0 : StringToInteger(fNRequestedEntriesString);
890
891 fSaveAllEvents = ToUpper(GetParameter("saveAllEvents", "false")) == "TRUE" ||
892 ToUpper(GetParameter("saveAllEvents", "off")) == "ON";
893
894 fPrintProgress = ToUpper(GetParameter("printProgress", "true")) == "TRUE" ||
895 ToUpper(GetParameter("printProgress", "on")) == "ON";
896
897 fRegisterEmptyTracks = ToUpper(GetParameter("registerEmptyTracks", "false")) == "TRUE" ||
898 ToUpper(GetParameter("registerEmptyTracks", "off")) == "ON";
899
900 fResetGlobalTime = ToUpper(GetParameter("resetGlobalTime", "true")) == "TRUE" ||
901 ToUpper(GetParameter("resetGlobalTime", "on")) == "ON";
902
904 // Detector (old storage) section is processed after initializing geometry info in Detector Construction
905 // This allows to use regular expression to match logical or physical volumes etc.
906 ReadBiasing();
907
908 fMaxTargetStepSize = GetDblParameterWithUnits("maxTargetStepSize", -1);
909 if (fMaxTargetStepSize > 0) {
910 cout << " " << endl;
911 RESTWarning << "IMPORTANT: *maxTargetStepSize* parameter is now obsolete!" << RESTendl;
912 RESTWarning << "The sensitive volume will not define any integration step limit" << RESTendl;
913 cout << " " << endl;
914 RESTWarning << "In order to avoid this warning REMOVE the *maxTargetStepSize* definition,"
915 << RESTendl;
916 RESTWarning << "and replace it by the following statement at the <storage> section" << RESTendl;
917 cout << " " << endl;
918 RESTWarning << "<activeVolume name=\"" << this->GetSensitiveVolume() << "\" maxStepSize=\""
919 << fMaxTargetStepSize << "mm\" />" << RESTendl;
920 cout << " " << endl;
921 RESTInfo << "Now, any active volume is allowed to define a maxStepSize" << RESTendl;
922 cout << " " << endl;
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;
925 cout << " " << endl;
926 RESTInfo << "<storage sensitiveVolume=\"" << this->GetSensitiveVolume() << "\" maxStepSize=\""
927 << fMaxTargetStepSize << "mm\" />" << RESTendl;
928 cout << " " << endl;
929 GetChar();
930 }
931
932 // should return success or fail
933}
934
953
955 const auto source = GetParticleSource();
956
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();
967 // counts per second per cm2 (distribution is already integrated over uniform phi)
968 countsPerSecondPerCm2 =
969 function->Integral(energyRange.X(), energyRange.Y(), angularRange.X(), angularRange.Y(), 1E-9);
970 }
971
972 else if (std::string(source->GetName()) == "TRestGeant4ParticleSourceCosmics") {
973 auto cosmicSource = dynamic_cast<TRestGeant4ParticleSourceCosmics*>(source);
974 const auto names = cosmicSource->GetParticleNames();
975 const auto histograms = cosmicSource->GetHistogramsTransformed();
976 for (const auto& name : names) {
977 countsPerSecondPerCm2 += histograms.at(name)->Integral();
978 }
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); // it's the same for both angular and energy
990 if (energyAndAngularDistributionHistogram == nullptr) {
991 throw std::runtime_error("Histogram not found in file");
992 }
993 countsPerSecondPerCm2 = energyAndAngularDistributionHistogram->Integral();
994 file->Close();
995 delete file;
996 }
997
998 else {
999 throw std::runtime_error("Cosmic flux calculation is only supported for TFormula2 or TH2D sources");
1000 }
1001
1002 return countsPerSecondPerCm2;
1003}
1004
1005Double_t TRestGeant4Metadata::GetCosmicIntensityInCountsPerSecond() const {
1006 const auto countsPerSecondPerCm2 = GetCosmicFluxInCountsPerCm2PerSecond();
1007 const auto surface = GetGeneratorSurfaceCm2();
1008 const auto countsPerSecond = countsPerSecondPerCm2 * surface;
1009 return countsPerSecond;
1010}
1011
1014
1015 double scalingFactor = 1.0;
1016 if (type == "cosmic") {
1017 // get the cosmic generator
1018 auto cosmicSource = dynamic_cast<TRestGeant4ParticleSourceCosmics*>(GetParticleSource());
1019 if (cosmicSource != nullptr) {
1020 scalingFactor =
1021 cosmicSource
1022 ->GetEnergyRangeScalingFactor(); // number less than 1, to account for energy range
1023 if (scalingFactor < 0 || scalingFactor > 1) {
1024 throw std::runtime_error("Energy range scaling factor must be between 0 and 1");
1025 }
1026 }
1027 }
1028
1029 // counts per seconds should be reduced proportionally to the range we are sampling
1030 const auto countsPerSecond = GetCosmicIntensityInCountsPerSecond() * scalingFactor;
1031 const auto seconds = double(fNEvents) / countsPerSecond;
1032
1033 return seconds;
1034}
1035
1036void TRestGeant4Metadata::ReadBiasing() {
1037 TiXmlElement* biasingDefinition = GetElement("biasing");
1038 if (biasingDefinition == nullptr) {
1039 fNBiasingVolumes = 0;
1040 return;
1041 }
1042 TString biasEnabled = GetFieldValue("value", biasingDefinition);
1043 TString biasType = GetFieldValue("type", biasingDefinition);
1044
1045 RESTDebug << "Bias: " << biasEnabled << RESTendl;
1046
1047 if (biasEnabled == "on" || biasEnabled == "ON" || biasEnabled == "On" || biasEnabled == "oN") {
1048 RESTInfo << "Biasing is enabled" << RESTendl;
1049
1050 TiXmlElement* biasVolumeDefinition = GetElement("biasingVolume", biasingDefinition);
1051 Int_t n = 0;
1052 while (biasVolumeDefinition) {
1053 TRestGeant4BiasingVolume biasVolume;
1054 RESTDebug << "Def: " << biasVolumeDefinition << RESTendl;
1055
1056 biasVolume.SetBiasingVolumePosition(
1057 Get3DVectorParameterWithUnits("position", biasVolumeDefinition));
1058 biasVolume.SetBiasingFactor(StringToDouble(GetParameter("factor", biasVolumeDefinition)));
1059 biasVolume.SetBiasingVolumeSize(GetDblParameterWithUnits("size", biasVolumeDefinition));
1060 biasVolume.SetEnergyRange(Get2DVectorParameterWithUnits("energyRange", biasVolumeDefinition));
1061 biasVolume.SetBiasingVolumeType(biasType); // For the moment all the volumes should be same type
1062
1063 /* TODO check that values are right if not printBiasingVolume with
1064 getchar() biasVolume.PrintBiasingVolume(); getchar();
1065 */
1066
1067 fBiasingVolumes.push_back(biasVolume);
1068 biasVolumeDefinition = GetNextElement(biasVolumeDefinition);
1069 n++;
1070 }
1071 fNBiasingVolumes = n;
1072 }
1073}
1074
1100 // TODO if some fields are defined in the generator but not finally used
1101 // i.e. <generator type="volume" from="gasTarget" position="(100,0,-100)
1102 // here position is irrelevant since the event will be generated from the
1103 // volume defined in the geometry we should take care of these values so they
1104 // are not stored in metadata (to avoid future confusion) In the particular
1105 // case of position, the value is overwritten in DetectorConstruction by the
1106 // center of the volume (i.e. gasTarget) but if i.e rotation or side are
1107 // defined and not relevant we should set it to -1
1108
1109 TiXmlElement* generatorDefinition = GetElement("generator");
1110
1112 SpatialGeneratorTypesToString(StringToSpatialGeneratorTypes(GetParameter(
1113 "type", generatorDefinition, SpatialGeneratorTypesToString(SpatialGeneratorTypes::VOLUME))));
1115 SpatialGeneratorShapesToString(StringToSpatialGeneratorShapes(GetParameter(
1116 "shape", generatorDefinition, SpatialGeneratorShapesToString(SpatialGeneratorShapes::BOX))));
1117 fGeant4PrimaryGeneratorInfo.fSpatialGeneratorFrom = GetParameter("from", generatorDefinition);
1118 if (fGeant4PrimaryGeneratorInfo.fSpatialGeneratorFrom != PARAMETER_NOT_FOUND_STR) {
1120 SpatialGeneratorShapesToString(SpatialGeneratorShapes::GDML);
1121 }
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);
1131 GetParameter("densityFunc", generatorDefinition, "1");
1132
1133 TiXmlElement* sourceDefinition = GetElement("source", generatorDefinition);
1134 while (sourceDefinition) {
1135 string use = GetParameter("use", sourceDefinition, "");
1136
1137 TRestGeant4ParticleSource* source = TRestGeant4ParticleSource::instantiate(use);
1138 ReadParticleSource(source, sourceDefinition);
1139 AddParticleSource(source);
1140
1141 if (string(source->GetName()) == "TRestGeant4ParticleSourceCosmics") {
1142 TRestGeant4ParticleSourceCosmics::SetSeed(GetSeed());
1143 }
1144
1145 sourceDefinition = GetNextElement(sourceDefinition);
1146 }
1147
1148 // check if the generator is valid.
1149 if (GetNumberOfSources() == 0) {
1150 RESTError << "No sources are added inside generator!" << RESTendl;
1151 exit(1);
1152 }
1153}
1154
1159 TiXmlElement* sourceDefinition = definition;
1160
1161 source->SetParticleName(GetParameter("particle", sourceDefinition));
1162 source->SetExcitationLevel(StringToDouble(GetParameter("excitedLevel", sourceDefinition)));
1163 source->SetParticleCharge(StringToInteger(GetParameter("charge", sourceDefinition, "0")));
1164
1165 TString fullChain = GetParameter("fullChain", sourceDefinition);
1166 SetFullChain(false);
1167 if (fullChain.EqualTo("on", TString::ECaseCompare::kIgnoreCase)) {
1168 SetFullChain(true);
1169 }
1170
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();
1176 fFullChainStopIsotopes.insert(isotope.Data());
1177 }
1178 }
1179
1180 // Angular distribution parameters
1181 TiXmlElement* angularDefinition = GetElement("angular", sourceDefinition);
1182 if (angularDefinition == nullptr) {
1183 angularDefinition = GetElement("angularDist", sourceDefinition); // old name
1184 }
1185 source->SetAngularDistributionType(GetParameter(
1186 "type", angularDefinition, AngularDistributionTypesToString(AngularDistributionTypes::FLUX)));
1187 if ((StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1188 AngularDistributionTypes::TH1D) ||
1189 (StringToAngularDistributionTypes(source->GetAngularDistributionType().Data()) ==
1190 AngularDistributionTypes::TH2D)) {
1191 source->SetAngularDistributionFilename(SearchFile(GetParameter("file", angularDefinition)));
1192 auto name = GetParameter("name", angularDefinition);
1193 if (name == "NO_SUCH_PARA") {
1194 name = GetParameter("spctName", angularDefinition); // old name
1195 }
1196 source->SetAngularDistributionNameInFile(name);
1197 }
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));
1203 // We cannot use an angular range bigger than the range of the formula
1204 const auto function = source->GetAngularDistributionFunction();
1205 if (source->GetAngularDistributionRangeMin() < function->GetXaxis()->GetXmin()) {
1206 source->SetAngularDistributionRange(
1207 {function->GetXaxis()->GetXmin(), source->GetAngularDistributionRangeMax()});
1208 }
1209 if (source->GetAngularDistributionRangeMax() > function->GetXaxis()->GetXmax()) {
1210 source->SetAngularDistributionRange(
1211 {source->GetAngularDistributionRangeMin(), function->GetXaxis()->GetXmax()});
1212 }
1213 }
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())));
1220 }
1221 if (GetNumberOfSources() == 0 &&
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));
1227 }
1228 source->SetDirection(StringTo3DVector(GetParameter("direction", angularDefinition, "(1,0,0)")));
1229
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);
1235 }
1236 // Energy distribution parameters
1237 TiXmlElement* energyDefinition = GetElement("energy", sourceDefinition);
1238 if (energyDefinition == nullptr) {
1239 energyDefinition = GetElement("energyDist", sourceDefinition); // old name
1240 }
1241 source->SetEnergyDistributionType(GetParameter(
1242 "type", energyDefinition, EnergyDistributionTypesToString(EnergyDistributionTypes::MONO)));
1243 if ((StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1244 EnergyDistributionTypes::TH1D) ||
1245 (StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1246 EnergyDistributionTypes::TH2D)) {
1247 source->SetEnergyDistributionFilename(SearchFile(GetParameter("file", energyDefinition)));
1248 auto name = GetParameter("name", energyDefinition);
1249 if (name == "NO_SUCH_PARA") {
1250 name = GetParameter("spctName", energyDefinition); // old name
1251 }
1252 source->SetEnergyDistributionNameInFile(name);
1253 }
1254 source->SetEnergyDistributionRange(Get2DVectorParameterWithUnits("range", energyDefinition, {0, 1E20}));
1255 if (StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1256 EnergyDistributionTypes::MONO) {
1257 Double_t energy;
1258 energy = GetDblParameterWithUnits("energy", energyDefinition, 0);
1259 source->SetEnergyDistributionRange({energy, energy});
1260 source->SetEnergy(energy);
1261 }
1262 if (StringToEnergyDistributionTypes(source->GetEnergyDistributionType().Data()) ==
1263 EnergyDistributionTypes::FORMULA) {
1264 source->SetEnergyDistributionFormula(GetParameter("name", energyDefinition));
1265 // We cannot use an energy range bigger than the range of the formula
1266 const auto function = source->GetEnergyDistributionFunction();
1267 if (source->GetEnergyDistributionRangeMin() < function->GetXaxis()->GetXmin()) {
1268 source->SetEnergyDistributionRange(
1269 {function->GetXaxis()->GetXmin(), source->GetEnergyDistributionRangeMax()});
1270 }
1271 if (source->GetEnergyDistributionRangeMax() > function->GetXaxis()->GetXmax()) {
1272 source->SetEnergyDistributionRange(
1273 {source->GetEnergyDistributionRangeMin(), function->GetXaxis()->GetXmax()});
1274 }
1275 }
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())));
1282 }
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);
1290
1291 if (energyDistName == empty && angularDistName == empty) {
1292 RESTError << "No name specified for energy and angular distribution" << RESTendl;
1293 exit(1);
1294 }
1295 if (energyDistName == empty) {
1296 angularDistName = energyDistName;
1297 RESTWarning << "No name specified for energy distribution. Using angular distribution name: "
1298 << angularDistName << RESTendl;
1299 }
1300 if (angularDistName == empty) {
1301 energyDistName = energyDistName;
1302 RESTWarning << "No name specified for angular distribution. Using energy distribution name: "
1303 << energyDistName << RESTendl;
1304 }
1305
1306 if (energyDistName == empty || angularDistName == empty) {
1307 // we should never enter here, just leave this as a check
1308 RESTError << "When using 'formula2' the name of energy and angular dist must match" << RESTendl;
1309 exit(1);
1310 }
1311 const auto energyAndAngularDistName = energyDistName;
1312 source->SetEnergyAndAngularDistributionFormula(energyAndAngularDistName);
1313
1314 const auto function = source->GetEnergyAndAngularDistributionFunction();
1315
1316 // Set energy range
1317 if (source->GetEnergyDistributionRangeMin() < function->GetXaxis()->GetXmin()) {
1318 source->SetEnergyDistributionRange(
1319 {function->GetXaxis()->GetXmin(), source->GetEnergyDistributionRangeMax()});
1320 }
1321 if (source->GetEnergyDistributionRangeMax() > function->GetXaxis()->GetXmax()) {
1322 source->SetEnergyDistributionRange(
1323 {source->GetEnergyDistributionRangeMin(), function->GetXaxis()->GetXmax()});
1324 }
1325
1326 // Set angular range
1327 if (source->GetAngularDistributionRangeMin() < function->GetYaxis()->GetXmin()) {
1328 source->SetAngularDistributionRange(
1329 {function->GetYaxis()->GetXmin(), source->GetAngularDistributionRangeMax()});
1330 }
1331 if (source->GetAngularDistributionRangeMax() > function->GetYaxis()->GetXmax()) {
1332 source->SetAngularDistributionRange(
1333 {source->GetAngularDistributionRangeMin(), function->GetYaxis()->GetXmax()});
1334 }
1335 }
1336 // allow custom configuration from the class
1337 source->LoadConfigFromElement(sourceDefinition, fElementGlobal, fVariables);
1338 // AddParticleSource(source);
1339}
1340
1342 for (auto source : fParticleSource) {
1343 delete source;
1344 }
1345 fParticleSource.clear();
1346}
1347
1349 fParticleSource.push_back(src);
1350}
1351
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;
1371 exit(1);
1372 }
1373
1374 const bool activateAllVolumes =
1375 StringToBool(GetParameter("activateAllVolumes", detectorDefinition, "true"));
1376 RESTInfo << "TRestGeant4Metadata: Setting 'fActivateAllVolumes' to " << fActivateAllVolumes << RESTendl;
1377 fActivateAllVolumes = activateAllVolumes;
1378
1379 TiXmlElement* removeUnwantedTracksDefinition = GetElement("removeUnwantedTracks", detectorDefinition);
1380 if (removeUnwantedTracksDefinition != nullptr) {
1381 fRemoveUnwantedTracks = StringToBool(GetParameter("enabled", removeUnwantedTracksDefinition, "true"));
1383 StringToBool(GetParameter("keepZeroEnergyTracks", removeUnwantedTracksDefinition, "false"));
1384 RESTInfo << "TRestGeant4Metadata: Setting 'fRemoveUnwantedTracks' to " << fRemoveUnwantedTracks
1385 << " with 'keepZeroEnergyTracks' option set to " << fRemoveUnwantedTracksKeepZeroEnergyTracks
1386 << RESTendl;
1387 }
1388
1389 Double_t defaultStep = GetDblParameterWithUnits("maxStepSize", detectorDefinition);
1390 if (defaultStep < 0) {
1391 defaultStep = 0;
1392 }
1393
1394 TiXmlElement* volumeDefinition = GetElement("volume", detectorDefinition);
1395 while (volumeDefinition != nullptr) {
1396 string name = GetFieldValue("name", volumeDefinition);
1397 if (name.empty() || name == "Not defined") {
1398 RESTError << "volume inside detector section defined without name" << RESTendl;
1399 exit(1);
1400 }
1401 vector<string> physicalVolumes;
1402 if (!fGeant4GeometryInfo.IsValidGdmlName(name)) {
1404 RESTDebug << "Volume name '" << name << "' is a valid logical volume. "
1405 << "Inserting all physical volumes from it." << RESTendl;
1406 for (const auto& physical : fGeant4GeometryInfo.GetAllPhysicalVolumesFromLogical(name)) {
1407 for (const auto& altPhysical :
1409 physicalVolumes.emplace_back(altPhysical);
1410 }
1411 }
1412 }
1413 // does not match a explicit (gdml) physical name or a logical name, perhaps its a regular exp
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 << "'"
1420 << RESTendl;
1421 physicalVolumes.emplace_back(physical);
1422 }
1423 }
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;
1428 for (const auto& logical : fGeant4GeometryInfo.GetAllLogicalVolumesMatchingExpression(name)) {
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);
1436 }
1437 }
1438 }
1439 }
1440 } else {
1441 RESTDebug << "Volume name '" << name << "' is a valid physical volume." << RESTendl;
1442 physicalVolumes.push_back(name);
1443 }
1444
1445 if (physicalVolumes.empty()) {
1446 RESTError
1447 << "volume '" << name
1448 << "' is not defined in the geometry. Could not match to a physical, logical volume or regex"
1449 << RESTendl;
1450 exit(1);
1451 }
1452
1453 bool isSensitive = false;
1454 const string isSensitiveValue = GetFieldValue("sensitive", volumeDefinition);
1455 if (isSensitiveValue != "Not defined") {
1456 isSensitive = StringToBool(isSensitiveValue);
1457 }
1458
1459 bool isKeepTracks = isSensitive;
1460 const string isKeepTracksValue = GetFieldValue("keepTracks", volumeDefinition);
1461 if (isKeepTracksValue != "Not defined") {
1462 isKeepTracks = StringToBool(isKeepTracksValue);
1463 }
1464
1465 bool isKill = false;
1466 const string isKillValue = GetFieldValue("kill", volumeDefinition);
1467 if (isKillValue != "Not defined") {
1468 isKill = StringToBool(isKillValue);
1469 }
1470
1471 Double_t chance = StringToDouble(GetFieldValue("chance", volumeDefinition));
1472 if (chance == -1 || chance < 0) {
1473 chance = 1.0;
1474 }
1475 Double_t maxStep = GetDblParameterWithUnits("maxStepSize", volumeDefinition);
1476 if (maxStep < 0) {
1477 maxStep = defaultStep;
1478 }
1479
1480 for (const auto& physical : physicalVolumes) {
1481 RESTInfo << "Adding " << (isSensitive ? "sensitive" : "active") << " volume from RML: '"
1482 << physical << "'" << (chance != 1 ? " with chance: " + to_string(chance) : " ")
1483 << RESTendl;
1484 SetActiveVolume(physical, chance, maxStep);
1485 if (isSensitive) {
1486 InsertSensitiveVolume(physical);
1487 }
1488 if (fRemoveUnwantedTracks && isKeepTracks) {
1489 fRemoveUnwantedTracksVolumesToKeep.insert(physical);
1490 }
1491 if (isKill) {
1492 fKillVolumes.insert(physical);
1493 }
1494 }
1495 volumeDefinition = GetNextElement(volumeDefinition);
1496 }
1497
1498 if (fSensitiveVolumes.empty()) {
1499 cout << "No sensitive volumes defined in detector section. Adding 'gas' as sensitive volume" << endl;
1500 InsertSensitiveVolume("gas");
1501 }
1502
1503 fEnergyRangeStored = Get2DVectorParameterWithUnits("energyRange", detectorDefinition, fEnergyRangeStored);
1504 // TODO: Place this as a generic method
1505 if (fEnergyRangeStored.X() < 0) {
1507 }
1508 if (fEnergyRangeStored.Y() < 0) {
1510 }
1511 if (fEnergyRangeStored.Y() > fEnergyRangeStored.Y()) {
1513 }
1514 if (fEnergyRangeStored.Y() <= 0) {
1515 RESTError << "Energy range is not valid: (" << fEnergyRangeStored.X() << ", "
1516 << fEnergyRangeStored.Y() << ") keV" << RESTendl;
1517 exit(1);
1518 }
1519
1520 auto gdml = new TRestGDMLParser();
1521 gdml->Load(GetGdmlFilename().Data());
1522
1523 fGeant4GeometryInfo.PopulateFromGdml(gdml->GetOutputGDMLFile());
1524
1525 // If the user did not add explicitly any volume to the storage section we understand
1526 // the user wants to register all the volumes
1527 if (fActivateAllVolumes) {
1528 for (const auto& name : fGeant4GeometryInfo.GetAllPhysicalVolumes()) {
1529 if (!IsActiveVolume(name)) {
1530 SetActiveVolume(name, 1, defaultStep);
1531 RESTInfo << "Automatically adding active volume: '" << name << "' with chance: " << 1
1532 << RESTendl;
1533 }
1534 }
1535 }
1536
1537 if (GetNumberOfActiveVolumes() == 0) {
1538 RESTError << "No active volumes defined. Please check the detector section" << RESTendl;
1539 exit(1);
1540 }
1541}
1542
1549
1550 RESTMetadata << "Geant4 version: " << GetGeant4Version() << RESTendl;
1551 RESTMetadata << "Random seed: " << GetSeed() << RESTendl;
1552 RESTMetadata << "GDML geometry: " << GetGdmlReference() << RESTendl;
1553 RESTMetadata << "GDML materials reference: " << GetMaterialsReference() << RESTendl;
1554 RESTMetadata << "Sub-event time delay: " << GetSubEventTimeDelay() << " us" << RESTendl;
1555
1556 if (isGlobalTimeReset()) {
1557 RESTMetadata << "Reset global time: enabled" << RESTendl;
1558 RESTMetadata << "Reset Time precision " << GetResetTimePrecision() << " us" << RESTendl;
1559 } else {
1560 RESTMetadata << "Reset global time: disabled" << RESTendl;
1561 }
1562
1563 Double_t mx = GetMagneticField().X();
1564 Double_t my = GetMagneticField().Y();
1565 Double_t mz = GetMagneticField().Z();
1566 RESTMetadata << "Magnetic field: (" << mx << ", " << my << ", " << mz << ") T" << RESTendl;
1567 if (fSaveAllEvents) RESTMetadata << "Save all events was enabled!" << RESTendl;
1569 RESTMetadata << "Register empty tracks was enabled" << RESTendl;
1570 } else {
1571 RESTMetadata << "Register empty tracks was NOT enabled" << RESTendl;
1572 }
1573
1574 RESTMetadata << " " << RESTendl;
1575 RESTMetadata << " ++++++++++ Generator +++++++++++ " << RESTendl;
1576 RESTMetadata << "Number of generated events: " << GetNumberOfEvents() << RESTendl;
1578
1579 for (int i = 0; i < GetNumberOfSources(); i++) GetParticleSource(i)->PrintMetadata();
1580
1581 RESTMetadata << " " << RESTendl;
1582 RESTMetadata << " ++++++++++ Detector +++++++++++ " << RESTendl;
1583 RESTMetadata << "Energy range (keV): (" << GetMinimumEnergyStored() << ", " << GetMaximumEnergyStored()
1584 << ")" << RESTendl;
1585 RESTMetadata << "Number of sensitive volumes: " << GetNumberOfSensitiveVolumes() << RESTendl;
1586 for (const auto& sensitiveVolume : fSensitiveVolumes) {
1587 RESTMetadata << "Sensitive volume: " << sensitiveVolume << RESTendl;
1588 }
1589 RESTMetadata << "Number of active volumes: " << GetNumberOfActiveVolumes() << RESTendl;
1590 for (unsigned int n = 0; n < GetNumberOfActiveVolumes(); n++) {
1591 const auto name = GetActiveVolumeName(n);
1592 RESTMetadata << "Name: " << name << ", ID: " << fGeant4GeometryInfo.GetIDFromVolume(name)
1593 << ", maxStep: " << GetMaxStepSize(name) << "mm "
1594 << ", chance: " << GetStorageChance(name) << RESTendl;
1595 }
1596
1597 for (unsigned int n = 0; n < GetNumberOfBiasingVolumes(); n++) {
1598 GetBiasingVolume(n).PrintBiasingVolume();
1599 }
1600
1601 if (GetRemoveUnwantedTracks()) {
1602 RESTMetadata << "removeUnwantedTracks is enabled "
1603 << (fRemoveUnwantedTracksKeepZeroEnergyTracks ? "with" : "without")
1604 << " keeping zero energy tracks" << RESTendl;
1605
1606 /*
1607 RESTMetadata << "keep volumes for removeUnwantedTracks:" << RESTendl;
1608 for (const auto& volume : fRemoveUnwantedTracksVolumesToKeep) {
1609 RESTMetadata << "\t" << volume << RESTendl;
1610 }
1611 */
1612 }
1613
1614 RESTMetadata << "+++++" << RESTendl;
1615}
1616
1619Int_t TRestGeant4Metadata::GetActiveVolumeID(const TString& name) {
1620 Int_t id;
1621 for (id = 0; id < (Int_t)fActiveVolumes.size(); id++) {
1622 if (fActiveVolumes[id] == name) return id;
1623 }
1624 return -1;
1625}
1626
1641void TRestGeant4Metadata::SetActiveVolume(const TString& name, Double_t chance, Double_t maxStep) {
1642 for (size_t i = 0; i < fActiveVolumes.size(); i++) {
1643 const auto activeVolumeName = fActiveVolumes[i];
1644 if (name == activeVolumeName) {
1645 fChance[i] = chance;
1646 fMaxStepSize[i] = maxStep;
1647 return;
1648 }
1649 }
1650 fActiveVolumes.push_back(name);
1651 fChance.push_back(chance);
1652 fMaxStepSize.push_back(maxStep);
1653 fActiveVolumesSet.insert(name.Data());
1654}
1655
1656double TRestGeant4Metadata::GetGeneratorSurfaceCm2() const {
1659
1660 if (type == "surface" && shape == "circle") {
1661 const auto radius = fGeant4PrimaryGeneratorInfo.GetSpatialGeneratorSize().X();
1662 return TMath::Pi() * radius * radius * 0.01; // cm2
1663 } else if (type == "cosmic") {
1665 }
1666
1667 throw std::runtime_error(
1668 "TRestGeant4Metadata::GetGeneratorSurfaceCm2: Can only be called for 'cosmic' and 'surface/circle' "
1669 "generators");
1670}
1671
1676Bool_t TRestGeant4Metadata::isVolumeStored(const TString& volume) const {
1677 for (unsigned int n = 0; n < GetNumberOfActiveVolumes(); n++) {
1678 if (GetActiveVolumeName(n) == volume) {
1679 return true;
1680 }
1681 }
1682
1683 return false;
1684}
1685
1689Double_t TRestGeant4Metadata::GetStorageChance(const TString& volume) {
1690 for (auto id = 0; id < (Int_t)fActiveVolumes.size(); id++) {
1691 {
1692 if (fActiveVolumes[id] == volume) {
1693 return fChance[id];
1694 }
1695 }
1696 }
1697 RESTWarning << "TRestGeant4Metadata::GetStorageChance. Volume " << volume << " not found" << RESTendl;
1698
1699 return 0;
1700}
1701
1705Double_t TRestGeant4Metadata::GetMaxStepSize(const TString& volume) {
1706 for (Int_t i = 0; i < (Int_t)fActiveVolumes.size(); i++) {
1707 if (volume.EqualTo(fActiveVolumes[i], TString::kIgnoreCase)) {
1708 return fMaxStepSize[i];
1709 }
1710 }
1711 RESTWarning << "TRestGeant4Metadata::GetMaxStepSize. Volume " << volume << " not found" << RESTendl;
1712
1713 return 0;
1714}
1715
1716size_t TRestGeant4Metadata::GetGeant4VersionMajor() const {
1717 TString majorVersion = "";
1718 for (int i = 0; i < fGeant4Version.Length(); i++) {
1719 auto c = fGeant4Version[i];
1720 if (c == '.') {
1721 break;
1722 }
1723 majorVersion += c;
1724 }
1725 return std::stoi(majorVersion.Data());
1726}
1727
1728void TRestGeant4Metadata::Merge(const TRestGeant4Metadata& metadata) {
1729 fIsMerge = true;
1730 fSeed = 0; // seed makes no sense in a merged file
1731
1732 fNEvents += metadata.fNEvents;
1734 fSimulationTime += metadata.fSimulationTime;
1735}
1736
1738 *this = metadata;
1739}
1740
1741TRestGeant4Metadata& TRestGeant4Metadata::operator=(const TRestGeant4Metadata& metadata) {
1742 fIsMerge = metadata.fIsMerge;
1746 fGeant4Version = metadata.fGeant4Version;
1747 fGdmlReference = metadata.fGdmlReference;
1750 fActiveVolumes = metadata.fActiveVolumes;
1751 fChance = metadata.fChance;
1752 fMaxStepSize = metadata.fMaxStepSize;
1753 // fParticleSource = metadata.fParticleSource; // segfaults (pointers!)
1760 fFullChain = metadata.fFullChain;
1762 fNEvents = metadata.fNEvents;
1764 fStoreTracks = metadata.fStoreTracks;
1766 fSeed = metadata.fSeed;
1767 fSaveAllEvents = metadata.fSaveAllEvents;
1771 fKillVolumes = metadata.fKillVolumes;
1773 fMagneticField = metadata.fMagneticField;
1774 return *this;
1775}
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.
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 detector (old 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.
Double_t fResetTimePrecision
Time precision, in us, to determine if the global time has to be reset or not.
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.
Bool_t isGlobalTimeReset() const
Returns true in case global time is reset for long radioactive decays.
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 fResetGlobalTime
Reset global time in case of a long radioactive decay, the global time of the decay is stored in the ...
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:772
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).