From 646864f9330cfa85af59f6cb79dd5ffb6e7118e9 Mon Sep 17 00:00:00 2001 From: Karol Krizka Date: Sat, 3 Aug 2024 20:15:27 +0200 Subject: [PATCH] Loading of layer description from JSON. --- ACTSTracking/ACTSProcBase.hxx | 5 +- data/MuColl_v1.json | 307 ++++++++++++++++++++++++++++++ src/ACTSProcBase.cxx | 347 ++++++---------------------------- 3 files changed, 368 insertions(+), 291 deletions(-) create mode 100644 data/MuColl_v1.json diff --git a/ACTSTracking/ACTSProcBase.hxx b/ACTSTracking/ACTSProcBase.hxx index ad939c2..25b6162 100644 --- a/ACTSTracking/ACTSProcBase.hxx +++ b/ACTSTracking/ACTSProcBase.hxx @@ -61,7 +61,10 @@ class ACTSProcBase : public marlin::Processor { std::string _matFile{}; //! Path to tracker geometry file - std::string _tgeoFile{}; + std::string _tgeoFile = "data/MuColl_v1.root"; + + //! Path to tracker geometry json file + std::string _tgeodescFile = "data/MuColl_v1.json"; std::shared_ptr geoIDMappingTool() const; diff --git a/data/MuColl_v1.json b/data/MuColl_v1.json new file mode 100644 index 0000000..106489b --- /dev/null +++ b/data/MuColl_v1.json @@ -0,0 +1,307 @@ +{ + "geo-tgeo-unit-scalor": 10.0, + "geo-tgeo-build-beampipe": false, + "geo-tgeo-beampipe-parameters": [ + 0.0, + 0.0, + 0.0 + ], + "Volumes": [ + { + "geo-tgeo-volume-name": "Vertex", + "geo-tgeo-sfbin-r-tolerance": { + "lower": 5.0, + "upper": 5.0 + }, + "geo-tgeo-sfbin-z-tolerance": { + "lower": 5.0, + "upper": 5.0 + }, + "geo-tgeo-sfbin-phi-tolerance": { + "lower": 0.025, + "upper": 0.025 + }, + "geo-tgeo-volume-layers": { + "negative": true, + "central": true, + "positive": true + }, + "geo-tgeo-subvolume-names": { + "negative": "VertexEndcap*", + "central": "VertexBarrel*", + "positive": "VertexEndcap*" + }, + "geo-tgeo-sensitive-names": { + "negative": ["sensor*"], + "central": ["VertexBarrel_layer*_sens"], + "positive": ["sensor*"] + }, + "geo-tgeo-sensitive-axes": { + "negative": "xZy", + "central": "YZX", + "positive": "xZy" + }, + "geo-tgeo-layer-r-ranges": { + "negative": { + "lower": 0.0, + "upper": 120.0 + }, + "central": { + "lower": 0.0, + "upper": 120.0 + }, + "positive": { + "lower": 0.0, + "upper": 120.0 + } + }, + "geo-tgeo-layer-z-ranges": { + "negative": { + "lower": -285.0, + "upper": -70.0 + }, + "central": { + "lower": -70.0, + "upper": 70.0 + }, + "positive": { + "lower": 70.0, + "upper": 285.0 + } + }, + "geo-tgeo-layer-r-split": { + "negative": -1.0, + "central": 0.1, + "positive": -1.0 + }, + "geo-tgeo-layer-z-split": { + "negative": 1.0, + "central": -1.0, + "positive": 1.0 + }, + "geo-tgeo-cyl-disc-split": false + }, + { + "geo-tgeo-volume-name": "InnerTrackers", + "geo-tgeo-sfbin-r-tolerance": { + "lower": 5.0, + "upper": 5.0 + }, + "geo-tgeo-sfbin-z-tolerance": { + "lower": 5.0, + "upper": 5.0 + }, + "geo-tgeo-sfbin-phi-tolerance": { + "lower": 0.025, + "upper": 0.025 + }, + "geo-tgeo-volume-layers": { + "negative": true, + "central": true, + "positive": true + }, + "geo-tgeo-subvolume-names": { + "negative": "InnerTrackerEndcap*", + "central": "InnerTrackerBarrel*", + "positive": "InnerTrackerEndcap*" + }, + "geo-tgeo-sensitive-names": { + "negative": ["sensor*"], + "central": ["sensor*"], + "positive": ["sensor*"] + }, + "geo-tgeo-sensitive-axes": { + "negative": "XYZ", + "central": "XYZ", + "positive": "XYZ" + }, + "geo-tgeo-layer-r-ranges": { + "negative": { + "lower": 50.0, + "upper": 500.0 + }, + "central": { + "lower": 120.0, + "upper": 500.0 + }, + "positive": { + "lower": 50.0, + "upper": 500.0 + } + }, + "geo-tgeo-layer-z-ranges": { + "negative": { + "lower": -600.0, + "upper": -500.0 + }, + "central": { + "lower": -500.0, + "upper": 500.0 + }, + "positive": { + "lower": 500.0, + "upper": 600.0 + } + }, + "geo-tgeo-layer-r-split": { + "negative": -1.0, + "central": 10, + "positive": -1.0 + }, + "geo-tgeo-layer-z-split": { + "negative": 10.0, + "central": -1.0, + "positive": 10.0 + }, + "geo-tgeo-cyl-disc-split": false + }, + { + "geo-tgeo-volume-name": "OuterInnerTrackers", + "geo-tgeo-sfbin-r-tolerance": { + "lower": 5.0, + "upper": 5.0 + }, + "geo-tgeo-sfbin-z-tolerance": { + "lower": 5.0, + "upper": 5.0 + }, + "geo-tgeo-sfbin-phi-tolerance": { + "lower": 0.025, + "upper": 0.025 + }, + "geo-tgeo-volume-layers": { + "negative": true, + "central": true, + "positive": true + }, + "geo-tgeo-subvolume-names": { + "negative": "InnerTrackerEndcap*", + "central": "InnerTrackerBarrel*", + "positive": "InnerTrackerEndcap*" + }, + "geo-tgeo-sensitive-names": { + "negative": ["sensor*"], + "central": ["sensor*"], + "positive": ["sensor*"] + }, + "geo-tgeo-sensitive-axes": { + "negative": "XYZ", + "central": "XYZ", + "positive": "XYZ" + }, + "geo-tgeo-layer-r-ranges": { + "negative": { + "lower": 120.0, + "upper": 600.0 + }, + "central": { + "lower": 500.0, + "upper": 600.0 + }, + "positive": { + "lower": 120.0, + "upper": 600.0 + } + }, + "geo-tgeo-layer-z-ranges": { + "negative": { + "lower": -2210.0, + "upper": -750.0 + }, + "central": { + "lower": -750.0, + "upper": 750.0 + }, + "positive": { + "lower": 750.0, + "upper": 2210.0 + } + }, + "geo-tgeo-layer-r-split": { + "negative": -1.0, + "central": 10, + "positive": -1.0 + }, + "geo-tgeo-layer-z-split": { + "negative": 10.0, + "central": -1.0, + "positive": 10.0 + }, + "geo-tgeo-cyl-disc-split": false + }, + { + "geo-tgeo-volume-name": "OuterTrackers", + "geo-tgeo-sfbin-r-tolerance": { + "lower": 5.0, + "upper": 5.0 + }, + "geo-tgeo-sfbin-z-tolerance": { + "lower": 5.0, + "upper": 5.0 + }, + "geo-tgeo-sfbin-phi-tolerance": { + "lower": 0.025, + "upper": 0.025 + }, + "geo-tgeo-volume-layers": { + "negative": true, + "central": true, + "positive": true + }, + "geo-tgeo-subvolume-names": { + "negative": "OuterTrackerEndcap*", + "central": "OuterTrackerBarrel*", + "positive": "OuterTrackerEndcap*" + }, + "geo-tgeo-sensitive-names": { + "negative": ["sensor*"], + "central": ["sensor*"], + "positive": ["sensor*"] + }, + "geo-tgeo-sensitive-axes": { + "negative": "XYZ", + "central": "XYZ", + "positive": "XYZ" + }, + "geo-tgeo-layer-r-ranges": { + "negative": { + "lower": 570.0, + "upper": 1550.0 + }, + "central": { + "lower": 600.0, + "upper": 1550.0 + }, + "positive": { + "lower": 570.0, + "upper": 1550.0 + } + }, + "geo-tgeo-layer-z-ranges": { + "negative": { + "lower": -2210.0, + "upper": -1300.0 + }, + "central": { + "lower": -1300.0, + "upper": 1300.0 + }, + "positive": { + "lower": 1300.0, + "upper": 2210.0 + } + }, + "geo-tgeo-layer-r-split": { + "negative": -1.0, + "central": 10, + "positive": -1.0 + }, + "geo-tgeo-layer-z-split": { + "negative": 10.0, + "central": -1.0, + "positive": 10.0 + }, + "geo-tgeo-cyl-disc-split": false + } + ] +} diff --git a/src/ACTSProcBase.cxx b/src/ACTSProcBase.cxx index 2985ab3..e6e56d0 100644 --- a/src/ACTSProcBase.cxx +++ b/src/ACTSProcBase.cxx @@ -30,9 +30,14 @@ ACTSProcBase::ACTSProcBase(const std::string& procname) : Processor(procname) { // configuration registerProcessorParameter( "MatFile", "Path to the material description JSON file. Can be empty.", - _matFile, std::string("")); + _matFile, _matFile); + registerProcessorParameter("TGeoFile", "Path to the tracker geometry file.", - _tgeoFile, std::string("")); + _tgeoFile, _tgeoFile); + + registerProcessorParameter("TGeoDescFile", "Path to the JSON file describing the subdetectors.", + _tgeodescFile, _tgeodescFile); + } std::shared_ptr ACTSProcBase::geoIDMappingTool() const { @@ -71,6 +76,7 @@ void ACTSProcBase::init() { // Parse parameters _matFile = findFile(_matFile); _tgeoFile = findFile(_tgeoFile); + _tgeodescFile = findFile(_tgeodescFile); // Print the initial parameters printParameters(); @@ -208,320 +214,81 @@ void ACTSProcBase::buildDetector() { // Detector definition std::vector layerBuilderConfigs; - // TODO: Make this configurable from a file - { // Vertex - Acts::TGeoLayerBuilder::Config layerBuilderConfig; - layerBuilderConfig.configurationName = "Vertex"; - layerBuilderConfig.unit = 1 * Acts::UnitConstants::cm; - layerBuilderConfig.autoSurfaceBinning = true; - - // AutoBinning - std::vector> binTolerances{(int)Acts::binValues, - {0., 0.}}; - binTolerances[Acts::binR] = {5, 5}; - binTolerances[Acts::binZ] = {5, 5}; - binTolerances[Acts::binPhi] = {0.025, 0.025}; - layerBuilderConfig.surfaceBinMatcher = - Acts::SurfaceBinningMatcher(binTolerances); - - { // negative endcap - // Create the layer config object and fill it - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.volumeName = "VertexEndcap*"; - lConfig.sensorNames = {"sensor*"}; - lConfig.localAxes = "xZy"; - lConfig.envelope = std::pair( - 0.1 * Acts::UnitConstants::mm, 0.1 * Acts::UnitConstants::mm); - - // Fill the parsing restrictions in r - lConfig.parseRanges.push_back({Acts::binR, {0, 120}}); - - // Fill the parsing restrictions in z - lConfig.parseRanges.push_back({Acts::binZ, {-285, -70}}); - - // Fill the layer splitting parameters in z - lConfig.splitConfigs.push_back({Acts::binZ, 1}); - - // Save - layerBuilderConfig.layerConfigurations[0].push_back(lConfig); - } - - { // barrel - // Create the layer config object and fill it - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.volumeName = "VertexBarrel*"; - lConfig.sensorNames = {"VertexBarrel_layer*_sens"}; - lConfig.localAxes = "YZX"; - lConfig.envelope = std::pair( - 0.1 * Acts::UnitConstants::mm, 0.1 * Acts::UnitConstants::mm); - - // Fill the parsing restrictions in r - lConfig.parseRanges.push_back({Acts::binR, {0, 120}}); - - // Fill the layer splitting parameters in r - lConfig.splitConfigs.push_back({Acts::binR, 0.1}); - - // Fill the parsing restrictions in z - lConfig.parseRanges.push_back({Acts::binZ, {-70, 70}}); - - // Save - layerBuilderConfig.layerConfigurations[1].push_back(lConfig); - } - - { // positive endcap - // Create the layer config object and fill it - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.volumeName = "VertexEndcap*"; - lConfig.sensorNames = {"sensor*"}; - lConfig.localAxes = "xZy"; - lConfig.envelope = std::pair( - 0.1 * Acts::UnitConstants::mm, 0.1 * Acts::UnitConstants::mm); - - // Fill the parsing restrictions in r - lConfig.parseRanges.push_back({Acts::binR, {0, 120}}); - - // Fill the parsing restrictions in z - lConfig.parseRanges.push_back({Acts::binZ, {70, 285}}); - - // Fill the layer splitting parameters in z - lConfig.splitConfigs.push_back({Acts::binZ, 1}); - - // Save - layerBuilderConfig.layerConfigurations[2].push_back(lConfig); - } - - // Save - layerBuilderConfigs.push_back(layerBuilderConfig); + // Check if the geometry has been defined + if (_tgeodescFile.empty()) { + throw std::runtime_error("Required geometry description file (TGeoDescFile) missing."); } - { // InnerTracker - Acts::TGeoLayerBuilder::Config layerBuilderConfig; - layerBuilderConfig.configurationName = "InnerTrackers"; - layerBuilderConfig.autoSurfaceBinning = true; - - // AutoBinning - std::vector> binTolerances{(int)Acts::binValues, - {0., 0.}}; - binTolerances[Acts::binR] = {5, 5}; - binTolerances[Acts::binZ] = {5, 5}; - binTolerances[Acts::binPhi] = {0.025, 0.025}; - layerBuilderConfig.surfaceBinMatcher = - Acts::SurfaceBinningMatcher(binTolerances); - - { // negative endcap - // Create the layer config object and fill it - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.volumeName = "InnerTrackerEndcap*"; - lConfig.sensorNames = {"sensor*"}; - lConfig.localAxes = "XYZ"; - - // Fill the parsing restrictions in r - lConfig.parseRanges.push_back({Acts::binR, {50, 500}}); - - // Fill the parsing restrictions in z - lConfig.parseRanges.push_back({Acts::binZ, {-600, -500}}); - - // Fill the layer splitting parameters in z - lConfig.splitConfigs.push_back({Acts::binZ, 10}); - - // Save - layerBuilderConfig.layerConfigurations[0].push_back(lConfig); - } - - { // barrel - // Create the layer config object and fill it - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.volumeName = "InnerTrackerBarrel*"; - lConfig.sensorNames = {"sensor*"}; - lConfig.localAxes = "XYZ"; - - // Fill the parsing restrictions in r - lConfig.parseRanges.push_back({Acts::binR, {120, 500}}); - - // Fill the layer splitting parameters in r - lConfig.splitConfigs.push_back({Acts::binR, 10}); - - // Fill the parsing restrictions in z - lConfig.parseRanges.push_back({Acts::binZ, {-500, 500}}); - - // Save - layerBuilderConfig.layerConfigurations[1].push_back(lConfig); - } - - { // positive endcap - // Create the layer config object and fill it - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.volumeName = "InnerTrackerEndcap*"; - lConfig.sensorNames = {"sensor*"}; - lConfig.localAxes = "XYZ"; - - // Fill the parsing restrictions in r - lConfig.parseRanges.push_back({Acts::binR, {50, 500}}); - - // Fill the parsing restrictions in z - lConfig.parseRanges.push_back({Acts::binZ, {500, 600}}); - - // Fill the layer splitting parameters in z - lConfig.splitConfigs.push_back({Acts::binZ, 10}); - - // Save - layerBuilderConfig.layerConfigurations[2].push_back(lConfig); - } - - // Save - layerBuilderConfigs.push_back(layerBuilderConfig); + // Open the description + nlohmann::json tgeodesc; + std::ifstream tgeodescFile(_tgeodescFile, std::ifstream::in | std::ifstream::binary); + if(!tgeodescFile.is_open()) { + throw std::runtime_error("Unable to open TGeo description file: "+_tgeodescFile); } + tgeodescFile >> tgeodesc; - { // OuterInnerTracker - Acts::TGeoLayerBuilder::Config layerBuilderConfig; - layerBuilderConfig.configurationName = "OuterInnerTrackers"; - layerBuilderConfig.autoSurfaceBinning = true; - - // AutoBinning - std::vector> binTolerances{(int)Acts::binValues, - {0., 0.}}; - binTolerances[Acts::binR] = {5, 5}; - binTolerances[Acts::binZ] = {5, 5}; - binTolerances[Acts::binPhi] = {0.025, 0.025}; - layerBuilderConfig.surfaceBinMatcher = - Acts::SurfaceBinningMatcher(binTolerances); - - { // negative endcap - // Create the layer config object and fill it - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.volumeName = "InnerTrackerEndcap*"; - lConfig.sensorNames = {"sensor*"}; - lConfig.localAxes = "XYZ"; - - // Fill the parsing restrictions in r - lConfig.parseRanges.push_back({Acts::binR, {120, 600}}); - - // Fill the parsing restrictions in z - lConfig.parseRanges.push_back({Acts::binZ, {-2210, -750}}); - - // Fill the layer splitting parameters in z - lConfig.splitConfigs.push_back({Acts::binZ, 10}); - - // Save - layerBuilderConfig.layerConfigurations[0].push_back(lConfig); - } - - { // barrel - // Create the layer config object and fill it - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.volumeName = "InnerTrackerBarrel*"; - lConfig.sensorNames = {"sensor*"}; - lConfig.localAxes = "XYZ"; - - // Fill the parsing restrictions in r - lConfig.parseRanges.push_back({Acts::binR, {500, 600}}); - - // Fill the layer splitting parameters in r - lConfig.splitConfigs.push_back({Acts::binR, 10}); - - // Fill the parsing restrictions in z - lConfig.parseRanges.push_back({Acts::binZ, {-750, 750}}); - - // Save - layerBuilderConfig.layerConfigurations[1].push_back(lConfig); - } - - { // positive endcap - // Create the layer config object and fill it - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.volumeName = "InnerTrackerEndcap*"; - lConfig.sensorNames = {"sensor*"}; - lConfig.localAxes = "XYZ"; - - // Fill the parsing restrictions in r - lConfig.parseRanges.push_back({Acts::binR, {120, 600}}); - - // Fill the parsing restrictions in z - lConfig.parseRanges.push_back({Acts::binZ, {750, 2210}}); - - // Fill the layer splitting parameters in z - lConfig.splitConfigs.push_back({Acts::binZ, 10}); - - // Save - layerBuilderConfig.layerConfigurations[2].push_back(lConfig); - } - - // Save - layerBuilderConfigs.push_back(layerBuilderConfig); - } + // Helper parsing functions + auto range_from_json = [](const nlohmann::json& jsonpair) -> std::pair { + return { + jsonpair["lower"], + jsonpair["upper"] + }; + }; - { // OuterTracker + // Loop over volumes to define sub-detectors + for(const auto& volume : tgeodesc["Volumes"]) { + // Volume information Acts::TGeoLayerBuilder::Config layerBuilderConfig; - layerBuilderConfig.configurationName = "OuterTrackers"; + layerBuilderConfig.configurationName = volume["geo-tgeo-volume-name"]; + layerBuilderConfig.unit = 1 * Acts::UnitConstants::cm; layerBuilderConfig.autoSurfaceBinning = true; // AutoBinning std::vector> binTolerances{(int)Acts::binValues, {0., 0.}}; - binTolerances[Acts::binR] = {5, 5}; - binTolerances[Acts::binZ] = {5, 5}; - binTolerances[Acts::binPhi] = {0.025, 0.025}; + binTolerances[Acts::binR] = range_from_json(volume["geo-tgeo-sfbin-r-tolerance"]); + binTolerances[Acts::binZ] = range_from_json(volume["geo-tgeo-sfbin-z-tolerance"]); + binTolerances[Acts::binPhi] = range_from_json(volume["geo-tgeo-sfbin-phi-tolerance"]); layerBuilderConfig.surfaceBinMatcher = Acts::SurfaceBinningMatcher(binTolerances); - { // negative endcap - // Create the layer config object and fill it - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.volumeName = "OuterTrackerEndcap*"; - lConfig.sensorNames = {"sensor*"}; - lConfig.localAxes = "XYZ"; - - // Fill the parsing restrictions in r - lConfig.parseRanges.push_back({Acts::binR, {570, 1550}}); - - // Fill the parsing restrictions in z - lConfig.parseRanges.push_back({Acts::binZ, {-2210, -1300}}); - - // Fill the layer splitting parameters in z - lConfig.splitConfigs.push_back({Acts::binZ, 10}); - - // Save - layerBuilderConfig.layerConfigurations[0].push_back(lConfig); - } + // Loop over subvolumes (two endcaps and one barrel) + std::array subvolumeNames = {"negative","central","positive"}; // List of possible subvolume names. Order corresponds to layerConfigurations. + for(std::size_t idx = 0; idx < 3; idx++) { + const std::string& subvolumeName = subvolumeNames[idx]; + if(!volume["geo-tgeo-volume-layers"][subvolumeName]) { + // Skip disabled volume + continue; + } - { // barrel // Create the layer config object and fill it Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.volumeName = "OuterTrackerBarrel*"; - lConfig.sensorNames = {"sensor*"}; - lConfig.localAxes = "XYZ"; + lConfig.volumeName = volume["geo-tgeo-subvolume-names"][subvolumeName]; + lConfig.sensorNames = volume["geo-tgeo-sensitive-names"][subvolumeName]; + lConfig.localAxes = volume["geo-tgeo-sensitive-axes"][subvolumeName]; + lConfig.envelope = std::pair( + 0.1 * Acts::UnitConstants::mm, 0.1 * Acts::UnitConstants::mm); // Fill the parsing restrictions in r - lConfig.parseRanges.push_back({Acts::binR, {600, 1550}}); - - // Fill the layer splitting parameters in r - lConfig.splitConfigs.push_back({Acts::binR, 10}); + lConfig.parseRanges.push_back({Acts::binR, range_from_json(volume["geo-tgeo-layer-r-ranges"][subvolumeName])}); // Fill the parsing restrictions in z - lConfig.parseRanges.push_back({Acts::binZ, {-1300, 1300}}); - - // Save - layerBuilderConfig.layerConfigurations[1].push_back(lConfig); - } - - { // positive endcap - // Create the layer config object and fill it - Acts::TGeoLayerBuilder::LayerConfig lConfig; - lConfig.volumeName = "OuterTrackerEndcap*"; - lConfig.sensorNames = {"sensor*"}; - lConfig.localAxes = "XYZ"; + lConfig.parseRanges.push_back({Acts::binZ, range_from_json(volume["geo-tgeo-layer-z-ranges"][subvolumeName])}); - // Fill the parsing restrictions in r - lConfig.parseRanges.push_back({Acts::binR, {570, 1550}}); - - // Fill the parsing restrictions in z - lConfig.parseRanges.push_back({Acts::binZ, {1300, 2210}}); + // Fill the layer splitting parameters in z + float rsplit = volume["geo-tgeo-layer-r-split"][subvolumeName]; + if(rsplit > 0) { + lConfig.splitConfigs.push_back({Acts::binR, rsplit}); + } // Fill the layer splitting parameters in z - lConfig.splitConfigs.push_back({Acts::binZ, 10}); + float zsplit = volume["geo-tgeo-layer-z-split"][subvolumeName]; + if(zsplit > 0) { + lConfig.splitConfigs.push_back({Acts::binZ, zsplit}); + } // Save - layerBuilderConfig.layerConfigurations[2].push_back(lConfig); + layerBuilderConfig.layerConfigurations[idx].push_back(lConfig); } // Save