diff --git a/Algorithms/CMakeLists.txt b/Algorithms/CMakeLists.txt index 164852425bab8e28c138eb214ee8afe78adb5607..cb73a2e35c638c02777d1e621d5d018aaa45935b 100644 --- a/Algorithms/CMakeLists.txt +++ b/Algorithms/CMakeLists.txt @@ -1,5 +1,5 @@ add_subdirectory(Digitization) add_subdirectory(Fatras) add_subdirectory(Generators) -#add_subdirectory_if(MaterialMapping USE_GEANT4) +add_subdirectory(MaterialMapping) add_subdirectory(Propagation) diff --git a/Algorithms/Digitization/src/DigitizationAlgorithm.cpp b/Algorithms/Digitization/src/DigitizationAlgorithm.cpp index 94a8d6f392b31602f36a99e4bca1552f11d5efca..d8713f6c88ba1bdcc966106ec1b02513f5172ba8 100644 --- a/Algorithms/Digitization/src/DigitizationAlgorithm.cpp +++ b/Algorithms/Digitization/src/DigitizationAlgorithm.cpp @@ -67,16 +67,18 @@ FW::DigitizationAlgorithm::execute(const AlgorithmContext& context) const // now digitise for (auto& vData : simHits) { auto volumeKey = vData.first; - ACTS_DEBUG("- Processing Volume Data collection for volume with ID " - << volumeKey); + ACTS_VERBOSE("- Processing Volume Data collection for volume with ID " + << volumeKey); for (auto& lData : vData.second) { auto layerKey = lData.first; - ACTS_DEBUG("-- Processing Layer Data collection for layer with ID " - << layerKey); + ACTS_VERBOSE("-- Processing Layer Data collection for layer with ID " + << layerKey); for (auto& sData : lData.second) { auto moduleKey = sData.first; - ACTS_DEBUG("-- Processing Module Data collection for module with ID " - << moduleKey); + ACTS_VERBOSE("-- Processing Module Data collection for module with ID " + << moduleKey); + ACTS_VERBOSE("-- Recieved " << sData.second.size() + << " input data objects."); // get the hit parameters for (auto& hit : sData.second) { // get the surface @@ -105,7 +107,7 @@ FW::DigitizationAlgorithm::execute(const AlgorithmContext& context) const Acts::Vector2D localIntersection(localIntersect3D.x(), localIntersect3D.y()); Acts::Vector3D localDirection(invTransfrom.linear() - * hit.direction); + * hit.direction.normalized()); // now calculate the steps through the silicon std::vector<Acts::DigitizationStep> dSteps = m_cfg.planarModuleStepper->cellSteps(context.geoContext, @@ -113,7 +115,10 @@ FW::DigitizationAlgorithm::execute(const AlgorithmContext& context) const localIntersection, localDirection); // everything under threshold or edge effects - if (!dSteps.size()) continue; + if (!dSteps.size()) { + ACTS_VERBOSE("No steps returned from stepper."); + continue; + } /// let' create a cluster - centroid method double localX = 0.; double localY = 0.; @@ -156,7 +161,6 @@ FW::DigitizationAlgorithm::execute(const AlgorithmContext& context) const geoID.add(volumeKey, Acts::GeometryID::volume_mask); geoID.add(layerKey, Acts::GeometryID::layer_mask); geoID.add(moduleKey, Acts::GeometryID::sensitive_mask); - geoID.add(binSerialized, Acts::GeometryID::channel_mask); // create the planar cluster Acts::PlanarModuleCluster pCluster( diff --git a/Algorithms/Generators/CMakeLists.txt b/Algorithms/Generators/CMakeLists.txt index 158cd86407bb8c6997c55f14c1fcfbbbc6826114..41b31be8338722244637543ece3957d4061b06d0 100644 --- a/Algorithms/Generators/CMakeLists.txt +++ b/Algorithms/Generators/CMakeLists.txt @@ -11,3 +11,4 @@ target_link_libraries(ActsFrameworkGenerators PUBLIC ActsCore ACTFramework ${Boost_PROGRAM_OPTIONS_LIBRARY}) install(TARGETS ActsFrameworkGenerators LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + diff --git a/Algorithms/MaterialMapping/CMakeLists.txt b/Algorithms/MaterialMapping/CMakeLists.txt index 43885f5ebdaa1ab4cf6c5842dcfb622a31c28cc1..63f151b27fbac81ca97d2b67070a74bac52f6cdc 100644 --- a/Algorithms/MaterialMapping/CMakeLists.txt +++ b/Algorithms/MaterialMapping/CMakeLists.txt @@ -1,11 +1,16 @@ -include(${Geant4_USE_FILE}) - -file(GLOB_RECURSE src_files "src/*.cpp" "include/*.*pp") +file(GLOB_RECURSE src_files "src/MaterialMapping.cpp") +if (USE_GEANT4) + SET(src_files "src/GeantinoRecording.cpp" ${src_files}) + include(${Geant4_USE_FILE}) +endif() add_library(ACTFWMaterialMapping SHARED ${src_files}) target_include_directories(ACTFWMaterialMapping PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/> $<INSTALL_INTERFACE:include>) target_link_libraries(ACTFWMaterialMapping PUBLIC ActsCore ActsMaterialMappingPlugin) -target_link_libraries(ACTFWMaterialMapping PUBLIC ACTFramework ACTFWGeant4Plugin) +target_link_libraries(ACTFWMaterialMapping PUBLIC ACTFramework) +if (USE_GEANT4) + target_link_libraries(ACTFWMaterialMapping PUBLIC ACTFWGeant4Plugin ACTFWGeometryInterfaces) +endif() install(TARGETS ACTFWMaterialMapping LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(DIRECTORY include/ACTFW DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/GeantinoRecording.hpp b/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/GeantinoRecording.hpp index 7f0e0a5255e8123a09e99ecf8f31a885636d2e2e..64b433c0bc07c2e1eb23d3856c8cdf530f7caddb 100644 --- a/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/GeantinoRecording.hpp +++ b/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/GeantinoRecording.hpp @@ -6,24 +6,32 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef ACTW_ALGORITHMS_MATERIALMAPPING_GEANTINORECORDING_H -#define ACTW_ALGORITHMS_MATERIALMAPPING_GEANTINORECORDING_H +#pragma once #include <memory> #include "ACTFW/Framework/BareAlgorithm.hpp" #include "ACTFW/Framework/ProcessCode.hpp" #include "ACTFW/GeometryInterfaces/IGeant4Service.hpp" -#include "ACTFW/Writers/IWriterT.hpp" -#include "Acts/Plugins/MaterialMapping/MaterialTrack.hpp" +#include "Acts/Extrapolator/MaterialInteractor.hpp" +#include "Acts/Utilities/Definitions.hpp" #include "Acts/Utilities/Logger.hpp" #include "G4RunManager.hh" -namespace FW { -class WhiteBoard; +namespace Acts { +// Using some short hands for Recorded Material +using RecordedMaterial = MaterialInteractor::result_type; + +// And recorded material track +// - this is start: position, start momentum +// and the Recorded material +using RecordedMaterialTrack + = std::pair<std::pair<Acts::Vector3D, Acts::Vector3D>, RecordedMaterial>; } namespace FW { +class WhiteBoard; + /// @class GeantinoRecording /// /// @brief records the simulation geometry by using geantinos @@ -40,16 +48,17 @@ public: /// @class Config struct Config { - /// The writer writing out the MaterialTrack entities - std::shared_ptr<FW::IWriterT<Acts::MaterialTrack>> materialTrackWriter - = nullptr; + std::string geantMaterialCollection = "geant-material-tracks"; + /// The service possibly providing the Geant4 geometry (optional) /// @note If this is not set, the geometry should be given by gdml file std::shared_ptr<FW::IGeant4Service> geant4Service = nullptr; + /// The possible gmdl input (optional) std::string gdmlFile; /// The number of tracks per event size_t tracksPerEvent = 0; + /// random number seed 1 int seed1 = 12345; /// random number seed 2 @@ -70,5 +79,3 @@ private: std::unique_ptr<G4RunManager> m_runManager; }; } - -#endif // ACTW_ALGORITHMS_GEANTINORECORDING_H diff --git a/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/IMaterialWriter.hpp b/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/IMaterialWriter.hpp new file mode 100644 index 0000000000000000000000000000000000000000..98fab012d3cb51880f7ad7413270ff9177e0941c --- /dev/null +++ b/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/IMaterialWriter.hpp @@ -0,0 +1,74 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include <map> +#include "Acts/Utilities/GeometryID.hpp" + +namespace Acts { + +class ISurfaceMaterial; +class IVolumeMaterial; + +using SurfaceMaterialMap + = std::map<GeometryID, std::shared_ptr<const ISurfaceMaterial>>; + +using VolumeMaterialMap + = std::map<GeometryID, std::shared_ptr<const IVolumeMaterial>>; + +using DetectorMaterialMaps = std::pair<SurfaceMaterialMap, VolumeMaterialMap>; +} + +namespace FW { + +/// @class IMaterialWriter +/// +/// Interface definition for material writing +class IMaterialWriter +{ +public: + /// Virtual Destructor + virtual ~IMaterialWriter() = default; + + /// The single wirter class + /// + /// @param detMaterial the detector material maps + virtual void + writeMaterial(const Acts::DetectorMaterialMaps& detMaterial) + = 0; +}; + +/// @class MaterialWriterT +/// +/// @tparam writer_t is the actual implementation +template <typename writer_t> +class MaterialWriterT : virtual public IMaterialWriter +{ +public: + /// Constructor + /// + /// @tparam writer_t the templated writer implementation + /// + /// @param impl the actaul implementation of the writer + MaterialWriterT(writer_t impl) : m_impl(std::move(impl)) {} + + /// The single wirter class + /// + /// @param detMaterial the detector material maps + void + writeMaterial(const Acts::DetectorMaterialMaps& detMaterial) + { + m_impl.write(detMaterial); + } + +private: + /// The writer implementation + writer_t m_impl; +}; +} diff --git a/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/MaterialMapping.hpp b/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/MaterialMapping.hpp index ecd719027f05c99f94de1b78a5a6fd431fd3c472..c5d3dbe69254678ee7e95e9d96b6182f7353eb23 100644 --- a/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/MaterialMapping.hpp +++ b/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/MaterialMapping.hpp @@ -1,47 +1,55 @@ // This file is part of the Acts project. // -// Copyright (C) 2017 Acts project team +// Copyright (C) 2017-2019 Acts project team // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef ACTFW_ALGORITHMS_MATERIALMAPPING_MATERIALMAPPING_H -#define ACTFW_ALGORITHMS_MATERIALMAPPING_MATERIALMAPPING_H +#pragma once #include <climits> #include <memory> +#include <mutex> #include "ACTFW/Framework/BareAlgorithm.hpp" #include "ACTFW/Framework/ProcessCode.hpp" -#include "ACTFW/Readers/IReaderT.hpp" -#include "ACTFW/Writers/IWriterT.hpp" -#include "Acts/Layers/Layer.hpp" -#include "Acts/Material/SurfaceMaterial.hpp" -#include "Acts/Plugins/MaterialMapping/MaterialMapper.hpp" -#include "Acts/Plugins/MaterialMapping/MaterialTrack.hpp" +#include "ACTFW/MaterialMapping/IMaterialWriter.hpp" +#include "Acts/Plugins/MaterialMapping/SurfaceMaterialMapper.hpp" #include "Acts/Utilities/Logger.hpp" -namespace FW { -class WhiteBoard; -} - namespace Acts { + class TrackingGeometry; +class ISurfaceMaterial; +class IVolumeMaterial; + +using SurfaceMaterialMap + = std::map<GeometryID, std::shared_ptr<const ISurfaceMaterial>>; + +using VolumeMaterialMap + = std::map<GeometryID, std::shared_ptr<const IVolumeMaterial>>; + +using DetectorMaterialMaps = std::pair<SurfaceMaterialMap, VolumeMaterialMap>; } namespace FW { /// @class MaterialMapping /// -/// @brief Initiates material mapping +/// @brief Initiates and executes material mapping /// /// The MaterialMapping reads in the MaterialTrack with a dedicated /// reader and uses the material mapper to project the material onto /// the tracking geometry /// -/// In a final step, the material maps are written out for further usage - +/// By construction, the material mapping needs inter-event information +/// to build the material maps of accumulated single particle views. +/// However, running it in one single event, puts enormous pressure onto +/// the I/O structure. +/// +/// It therefore saves the mapping state/cache as a private member variable +/// and is designed to be executed in a single threaded mode. class MaterialMapping : public FW::BareAlgorithm { public: @@ -49,36 +57,53 @@ public: /// of the MaterialMapping algorithm struct Config { - public: - /// The reader to read in the MaterialTrack entities - std::shared_ptr<FW::IReaderT<Acts::MaterialTrack>> materialTrackReader - = nullptr; - /// The ACTS material mapper - std::shared_ptr<Acts::MaterialMapper> materialMapper = nullptr; - /// The validation writer of the material - std::shared_ptr<FW::IWriterT<Acts::MaterialTrack>> materialTrackWriter - = nullptr; + /// Constructor with geometry and magnetic field contexts + Config(std::reference_wrapper<const Acts::GeometryContext> gctx, + std::reference_wrapper<const Acts::MagneticFieldContext> mctx) + : geoContext(gctx), magFieldContext(mctx) + { + } + + /// Input collection + std::string collection = "material-tracks"; + + /// The ACTS surface material mapper + std::shared_ptr<Acts::SurfaceMaterialMapper> materialMapper = nullptr; + /// The writer of the material - std::shared_ptr<FW::IWriterT<Acts::IndexedSurfaceMaterial>> - indexedMaterialWriter = nullptr; + std::vector<std::shared_ptr<IMaterialWriter>> materialWriters; + /// The TrackingGeometry to be mapped on std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry = nullptr; - /// mapping conditions - size_t maximumTrackRecords = std::numeric_limits<size_t>::infinity(); + + // Geometry context for the state creation + std::reference_wrapper<const Acts::GeometryContext> geoContext; + + // MagneticField context for the state creation + std::reference_wrapper<const Acts::MagneticFieldContext> magFieldContext; }; /// Constructor + /// + /// @param cfg The configuration struct carrying the used tools + /// @param level The output logging level MaterialMapping(const Config& cfg, Acts::Logging::Level level = Acts::Logging::INFO); + /// Destructor + /// - it also writes out the file + ~MaterialMapping(); + /// Framework execute method + /// + /// @param context The algorithm context for event consistency FW::ProcessCode execute(const AlgorithmContext& context) const final override; private: - Config m_cfg; + Config m_cfg; //!< internal config object + Acts::SurfaceMaterialMapper::State + m_mappingState; //!< Material mapping state }; } // namespace FW - -#endif // ACTFW_ALGORITHMS_MATERIALMAPPING_MATERIALMAPPING_H diff --git a/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/MaterialMappingOptions.hpp b/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/MaterialMappingOptions.hpp new file mode 100644 index 0000000000000000000000000000000000000000..84239ea5f94f29f4a3c735e02a1ffd807ff63964 --- /dev/null +++ b/Algorithms/MaterialMapping/include/ACTFW/MaterialMapping/MaterialMappingOptions.hpp @@ -0,0 +1,57 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include <iostream> +#include "ACTFW/Utilities/Options.hpp" +#include "Acts/Utilities/Units.hpp" + +namespace po = boost::program_options; + +namespace FW { + +namespace Options { + + /// @brief Material mapping options, specially added + /// + /// @tparam aopt_t Type of the options object (API bound to boost) + /// + /// @param [in] opt_t The options object where the specific digitization + /// options are attached to + template <typename aopt_t> + void + addMaterialMappingOptions(aopt_t& opt) + { + opt.add_options()( + "mat-mapping-collection", + po::value<std::string>()->default_value("material-tracks"), + "Collection name of the material tracks for reading."); + } + + ///@brief Read the digitization options and return a Config object + /// + ///@tparam omap_t Type of the options map + ///@param vm the options map to be read out + // template <typename omap_t> + // DigitizationAlgorithm::Config + // readDigitizationConfig(const omap_t& vm) + //{ + // // create a config + // DigitizationAlgorithm::Config digiConfig; + // digiConfig.spacePointCollection + // = vm["digi-spacepoints"].template as<std::string>(); + // digiConfig.clusterCollection + // = vm["digi-clusters"].template as<std::string>(); + // digiConfig.resolutionFile + // = vm["digi-resolution-file"].template as<std::string>(); + // // and return the config + // return digiConfig; + //} +} // namespace Options +} // namespace FW \ No newline at end of file diff --git a/Algorithms/MaterialMapping/src/GeantinoRecording.cpp b/Algorithms/MaterialMapping/src/GeantinoRecording.cpp index a1ae1d92161ce8ab1eec5b5db1a79e6b346d010f..e46731f9a853bf377ad595156262784a8ceff1bb 100644 --- a/Algorithms/MaterialMapping/src/GeantinoRecording.cpp +++ b/Algorithms/MaterialMapping/src/GeantinoRecording.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017 Acts project team +// Copyright (C) 2017-2018 Acts project team // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,6 +9,7 @@ #include "ACTFW/MaterialMapping/GeantinoRecording.hpp" #include <iostream> #include <stdexcept> +#include "ACTFW/Framework/WhiteBoard.hpp" #include "ACTFW/Plugins/Geant4/MMDetectorConstruction.hpp" #include "ACTFW/Plugins/Geant4/MMEventAction.hpp" #include "ACTFW/Plugins/Geant4/MMPrimaryGeneratorAction.hpp" @@ -23,11 +24,6 @@ FW::GeantinoRecording::GeantinoRecording( , m_cfg(cnf) , m_runManager(std::make_unique<G4RunManager>()) { - /// Make sure that a writer was provided in the configuration - if (!m_cfg.materialTrackWriter) { - throw std::invalid_argument("Missing material track writer"); - } - /// Check if the geometry should be accessed over the geant4 service if (m_cfg.geant4Service) { m_runManager->SetUserInitialization(m_cfg.geant4Service->geant4Geometry()); @@ -35,8 +31,8 @@ FW::GeantinoRecording::GeantinoRecording( /// Access the geometry from the gdml file ACTS_INFO( "received Geant4 geometry from GDML file: " << m_cfg.gdmlFile.c_str()); - FW::G4::MMDetectorConstruction* detConstruction - = new FW::G4::MMDetectorConstruction(); + FW::Geant4::MMDetectorConstruction* detConstruction + = new FW::Geant4::MMDetectorConstruction(); detConstruction->setGdmlInput(m_cfg.gdmlFile.c_str()); m_runManager->SetUserInitialization( detConstruction); // constructs detector (calls Construct in @@ -47,30 +43,30 @@ FW::GeantinoRecording::GeantinoRecording( /// Now set up the Geant4 simulation m_runManager->SetUserInitialization(new FTFP_BERT); - m_runManager->SetUserAction(new FW::G4::MMPrimaryGeneratorAction( + m_runManager->SetUserAction(new FW::Geant4::MMPrimaryGeneratorAction( "geantino", 1000., m_cfg.seed1, m_cfg.seed2)); - FW::G4::MMRunAction* runaction = new FW::G4::MMRunAction(); + FW::Geant4::MMRunAction* runaction = new FW::Geant4::MMRunAction(); m_runManager->SetUserAction(runaction); - m_runManager->SetUserAction(new FW::G4::MMEventAction()); - m_runManager->SetUserAction(new FW::G4::MMSteppingAction()); + m_runManager->SetUserAction(new FW::Geant4::MMEventAction()); + m_runManager->SetUserAction(new FW::Geant4::MMSteppingAction()); m_runManager->Initialize(); } FW::ProcessCode -FW::GeantinoRecording::execute(const FW::AlgorithmContext&) const +FW::GeantinoRecording::execute(const FW::AlgorithmContext& context) const { - /// Begin with the simulation + // Begin with the simulation m_runManager->BeamOn(m_cfg.tracksPerEvent); - /// - std::vector<Acts::MaterialTrack> mtrecords - = FW::G4::MMEventAction::Instance()->MaterialTracks(); - ACTS_INFO("Received " << mtrecords.size() + // Retrieve the track material tracks from Geant4 + auto recordedMaterial + = FW::Geant4::MMEventAction::Instance()->MaterialTracks(); + ACTS_INFO("Received " << recordedMaterial.size() << " MaterialTracks. Writing them now onto file..."); - // write to the file - for (auto& record : mtrecords) { - m_cfg.materialTrackWriter->write(record); - } + + // Write the recorded material to the event store + context.eventStore.add(m_cfg.geantMaterialCollection, + std::move(recordedMaterial)); return FW::ProcessCode::SUCCESS; } diff --git a/Algorithms/MaterialMapping/src/MaterialMapping.cpp b/Algorithms/MaterialMapping/src/MaterialMapping.cpp index 791ff6600d1e379a85fb68697021881959911e73..9954eab9c598553600ee2d96a51aeba116204da5 100644 --- a/Algorithms/MaterialMapping/src/MaterialMapping.cpp +++ b/Algorithms/MaterialMapping/src/MaterialMapping.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017 Acts project team +// Copyright (C) 2017-2019 Acts project team // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -10,78 +10,66 @@ // MaterialMapping.cpp /////////////////////////////////////////////////////////////////// +#include "ACTFW/MaterialMapping/MaterialMapping.hpp" #include <iostream> #include <stdexcept> - -#include <TTree.h> - -#include "ACTFW/MaterialMapping/MaterialMapping.hpp" -#include "Acts/Plugins/MaterialMapping/MaterialTrack.hpp" -#include "Acts/Plugins/MaterialMapping/SurfaceMaterialRecord.hpp" +#include "ACTFW/Framework/WhiteBoard.hpp" FW::MaterialMapping::MaterialMapping(const FW::MaterialMapping::Config& cnf, Acts::Logging::Level level) - : FW::BareAlgorithm("MaterialMapping", level), m_cfg(cnf) + : FW::BareAlgorithm("MaterialMapping", level) + , m_cfg(cnf) + , m_mappingState(cnf.geoContext, cnf.magFieldContext) { - if (!m_cfg.materialTrackReader) { - throw std::invalid_argument("Missing material track reader"); - } else if (!m_cfg.materialMapper) { + if (!m_cfg.materialMapper) { throw std::invalid_argument("Missing material mapper"); - } else if (!m_cfg.materialTrackWriter) { - throw std::invalid_argument("Missing material track writer"); - } else if (!m_cfg.indexedMaterialWriter) { - throw std::invalid_argument("Missing indexed material writer"); } else if (!m_cfg.trackingGeometry) { throw std::invalid_argument("Missing tracking geometry"); } + + ACTS_INFO("This algorithm requires inter-event information, " + << "run in single-threaded mode!"); + + // Generate and retrieve the central cache object + m_mappingState = m_cfg.materialMapper->createState( + m_cfg.geoContext, m_cfg.magFieldContext, *m_cfg.trackingGeometry); } -FW::ProcessCode - FW::MaterialMapping::execute(FW::AlgorithmContext /*context*/) const +FW::MaterialMapping::~MaterialMapping() { - // retrive a cache object - Acts::MaterialMapper::Cache mCache - = m_cfg.materialMapper->materialMappingCache(*m_cfg.trackingGeometry); - // access the tree and read the records - Acts::MaterialTrack inputTrack; + // Finalize all the maps using the cached state + m_cfg.materialMapper->finalizeMaps(m_mappingState); - for (size_t itc = 0; - m_cfg.materialTrackReader->read(inputTrack) != FW::ProcessCode::ABORT; - ++itc) { - ACTS_VERBOSE("Read MaterialTrack " << itc << " from file, it has " - << inputTrack.materialSteps().size() - << " steps."); + Acts::DetectorMaterialMaps detectorMaterial; - // some screen output to know what is going on - ACTS_VERBOSE("These will be mapped onto " - << mCache.surfaceMaterialRecords.size() - << " surfaces."); + // Loop over the state, and collect the maps for surfaces + for (auto & [ key, value ] : m_mappingState.surfaceMaterial) { + detectorMaterial.first.insert({key, std::move(value)}); + } - // perform the mapping - auto mappedTrack - = m_cfg.materialMapper->mapMaterialTrack(mCache, inputTrack); + // Loop over the available writers and write the maps + for (auto& imw : m_cfg.materialWriters) { + imw->writeMaterial(detectorMaterial); + } +} - // write out the material for validation purpose - m_cfg.materialTrackWriter->write(mappedTrack); +FW::ProcessCode +FW::MaterialMapping::execute(const FW::AlgorithmContext& context) const +{ - // break if configured - if (m_cfg.maximumTrackRecords > 0 && itc > m_cfg.maximumTrackRecords) { - ACTS_VERBOSE("Maximum track records reached. Stopping."); - break; - } - } - /// get the maps back - std::map<Acts::GeometryID, Acts::SurfaceMaterial*> sMaterialMaps - = m_cfg.materialMapper->createSurfaceMaterial(mCache); + // Write to the collection to the EventStore + const auto& mtrackCollection + = context.eventStore.get<std::vector<Acts::RecordedMaterialTrack>>( + m_cfg.collection); + + // To make it work with the framework needs a lock guard + auto mappingState + = const_cast<Acts::SurfaceMaterialMapper::State*>(&m_mappingState); - //// write the maps out to a file - ACTS_INFO("Writing out the material maps for " << sMaterialMaps.size() - << " material surfaces"); - // loop over the material maps - for (auto& sMap : sMaterialMaps) { - // write out map by map - m_cfg.indexedMaterialWriter->write(sMap); + for (auto mTrack : mtrackCollection) { + // Map this one onto the geometry + m_cfg.materialMapper->mapMaterialTrack(*mappingState, mTrack); } return FW::ProcessCode::SUCCESS; diff --git a/Algorithms/Propagation/include/ACTFW/Propagation/PropagationAlgorithm.hpp b/Algorithms/Propagation/include/ACTFW/Propagation/PropagationAlgorithm.hpp index 8020b10d836eeedf2376eeb8fcadcf3a16d45787..903e5487e31b70023f1bcd6eea10f81e60a65867 100644 --- a/Algorithms/Propagation/include/ACTFW/Propagation/PropagationAlgorithm.hpp +++ b/Algorithms/Propagation/include/ACTFW/Propagation/PropagationAlgorithm.hpp @@ -12,24 +12,39 @@ #include <limits> #include <memory> -#include <Acts/EventData/NeutralParameters.hpp> -#include <Acts/EventData/TrackParameters.hpp> -#include <Acts/Extrapolator/Navigator.hpp> -#include <Acts/Propagator/AbortList.hpp> -#include <Acts/Propagator/ActionList.hpp> -#include <Acts/Propagator/Propagator.hpp> -#include <Acts/Propagator/detail/DebugOutputActor.hpp> -#include <Acts/Propagator/detail/StandardAborters.hpp> -#include <Acts/Propagator/detail/SteppingLogger.hpp> -#include <Acts/Surfaces/PerigeeSurface.hpp> -#include <Acts/Utilities/Definitions.hpp> -#include <Acts/Utilities/Helpers.hpp> -#include <Acts/Utilities/Units.hpp> - #include "ACTFW/Framework/BareAlgorithm.hpp" #include "ACTFW/Framework/ProcessCode.hpp" #include "ACTFW/Framework/WhiteBoard.hpp" #include "ACTFW/Random/RandomNumbersSvc.hpp" +#include "Acts/EventData/NeutralParameters.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/Extrapolator/MaterialInteractor.hpp" +#include "Acts/Extrapolator/Navigator.hpp" +#include "Acts/Propagator/AbortList.hpp" +#include "Acts/Propagator/ActionList.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Propagator/detail/DebugOutputActor.hpp" +#include "Acts/Propagator/detail/StandardAborters.hpp" +#include "Acts/Propagator/detail/SteppingLogger.hpp" +#include "Acts/Surfaces/PerigeeSurface.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/Helpers.hpp" +#include "Acts/Utilities/Units.hpp" + +namespace FW { + +/// Using some short hands for Recorded Material +using RecordedMaterial = Acts::MaterialInteractor::result_type; + +/// And recorded material track +/// - this is start: position, start momentum +/// and the Recorded material +using RecordedMaterialTrack + = std::pair<std::pair<Acts::Vector3D, Acts::Vector3D>, RecordedMaterial>; + +/// Finally the output of the propagation test +using PropagationOutput + = std::pair<std::vector<Acts::detail::Step>, RecordedMaterial>; /// @brief this test algorithm performs test propagation /// within the Acts::Propagator @@ -38,8 +53,6 @@ /// also be used to test the Extrapolator within the geomtetry /// /// @tparam propagator_t Type of the Propagator to be tested -namespace FW { - template <typename propagator_t> class PropagationAlgorithm : public BareAlgorithm { @@ -59,6 +72,13 @@ public: int mode = 0; /// debug output bool debugOutput = false; + /// Modify the behavior of the material interaction: energy loss + bool energyLoss = false; + /// Modify the behavior of the material interaction: scattering + bool multipleScattering = false; + /// Modify the behavior of the material interaction: record + bool recordMaterialInteractions = false; + /// number of particles size_t ntests = 100; /// d0 gaussian sigma @@ -81,6 +101,9 @@ public: /// the step collection to be stored std::string propagationStepCollection = "PropagationSteps"; + /// The material collection to be stored + std::string propagationMaterialCollection = "RecordedMaterialTracks"; + /// covariance transport bool covarianceTransport = true; @@ -123,7 +146,7 @@ private: /// /// @return collection of Propagation steps for further analysis template <typename parameters_t> - std::vector<Acts::detail::Step> + PropagationOutput executeTest(const AlgorithmContext& context, const parameters_t& startParameters, double pathLength = std::numeric_limits<double>::max()) const; diff --git a/Algorithms/Propagation/include/ACTFW/Propagation/PropagationAlgorithm.ipp b/Algorithms/Propagation/include/ACTFW/Propagation/PropagationAlgorithm.ipp index 1da718276199b24d6387431ef75a1f1325be4a67..98280a2d0778763f6e9cb49671e8c5ef83a9ab0f 100644 --- a/Algorithms/Propagation/include/ACTFW/Propagation/PropagationAlgorithm.ipp +++ b/Algorithms/Propagation/include/ACTFW/Propagation/PropagationAlgorithm.ipp @@ -43,10 +43,12 @@ PropagationAlgorithm<propagator_t>::PropagationAlgorithm( /// Templated execute test method for /// charged and netural particles +/// @param [in] context is the contextual data of this event /// @param [in] startParameters the start parameters +/// @param [in] pathLength the maximal path length to go template <typename propagator_t> template <typename parameters_t> -std::vector<Acts::detail::Step> +PropagationOutput PropagationAlgorithm<propagator_t>::executeTest( const AlgorithmContext& context, const parameters_t& startParameters, @@ -55,16 +57,20 @@ PropagationAlgorithm<propagator_t>::executeTest( ACTS_DEBUG("Test propagation/extrapolation starts"); + PropagationOutput pOutput; + // This is the outside in mode if (m_cfg.mode == 0) { // The step length logger for testing & end of world aborter - using SteppingLogger = Acts::detail::SteppingLogger; - using DebugOutput = Acts::detail::DebugOutputActor; - using EndOfWorld = Acts::detail::EndOfWorldReached; + using MaterialInteractor = Acts::MaterialInteractor; + using SteppingLogger = Acts::detail::SteppingLogger; + using DebugOutput = Acts::detail::DebugOutputActor; + using EndOfWorld = Acts::detail::EndOfWorldReached; // Action list and abort list - using ActionList = Acts::ActionList<SteppingLogger, DebugOutput>; + using ActionList + = Acts::ActionList<SteppingLogger, MaterialInteractor, DebugOutput>; using AbortList = Acts::AbortList<EndOfWorld>; using PropagatorOptions = Acts::PropagatorOptions<ActionList, AbortList>; @@ -77,6 +83,12 @@ PropagationAlgorithm<propagator_t>::executeTest( = (Acts::VectorHelpers::perp(startParameters.momentum()) < m_cfg.ptLoopers); + // Switch the material interaction on/off & eventually into logging mode + auto& mInteractor = options.actionList.get<MaterialInteractor>(); + mInteractor.multipleScattering = m_cfg.multipleScattering; + mInteractor.energyLoss = m_cfg.energyLoss; + mInteractor.recordInteractions = m_cfg.recordMaterialInteractions; + // Set a maximum step size options.maxStepSize = m_cfg.maxStepSize; @@ -85,14 +97,22 @@ PropagationAlgorithm<propagator_t>::executeTest( = m_cfg.propagator.propagate(startParameters, options).value(); auto steppingResults = result.template get<SteppingLogger::result_type>(); - if (m_cfg.debugOutput) { - auto debugOutput = result.template get<DebugOutput::result_type>(); - ACTS_VERBOSE(debugOutput.debugString); + // Set the stepping result + pOutput.first = std::move(steppingResults.steps); + // Also set the material recording result - if configured + if (m_cfg.recordMaterialInteractions) { + auto materialResult + = result.template get<MaterialInteractor::result_type>(); + pOutput.second = std::move(materialResult); } - return steppingResults.steps; + // screen output if requested + if (m_cfg.debugOutput) { + auto& debugResult = result.template get<DebugOutput::result_type>(); + ACTS_VERBOSE(debugResult.debugString); + } } - return std::vector<Acts::detail::Step>(); + return pOutput; } template <typename propagator_t> @@ -118,9 +138,16 @@ PropagationAlgorithm<propagator_t>::execute( = Acts::Surface::makeShared<Acts::PerigeeSurface>( Acts::Vector3D(0., 0., 0.)); + // Output : the propagation steps std::vector<std::vector<Acts::detail::Step>> propagationSteps; propagationSteps.reserve(m_cfg.ntests); + // Output (optional): the recorded material + std::vector<RecordedMaterialTrack> recordedMaterial; + if (m_cfg.recordMaterialInteractions) { + recordedMaterial.reserve(m_cfg.ntests); + } + // loop over number of particles for (size_t it = 0; it < m_cfg.ntests; ++it) { /// get the d0 and z0 @@ -139,27 +166,53 @@ PropagationAlgorithm<propagator_t>::execute( // some screen output std::unique_ptr<Acts::ActsSymMatrixD<5>> cov = nullptr; + Acts::Vector3D sPosition(0., 0., 0.); + Acts::Vector3D sMomentum(0., 0., 0.); + // execute the test for charged particles - std::vector<Acts::detail::Step> testSteps; + PropagationOutput pOutput; if (charge) { // charged extrapolation - with hit recording Acts::BoundParameters startParameters( context.geoContext, std::move(cov), std::move(pars), surface); - testSteps = executeTest<Acts::TrackParameters>(context, startParameters); + sPosition = startParameters.position(); + sMomentum = startParameters.momentum(); + pOutput = executeTest<Acts::TrackParameters>(context, startParameters); } else { // execute the test for neeutral particles Acts::NeutralBoundParameters neutralParameters( context.geoContext, std::move(cov), std::move(pars), surface); - testSteps + sPosition = neutralParameters.position(); + sMomentum = neutralParameters.momentum(); + pOutput = executeTest<Acts::NeutralParameters>(context, neutralParameters); } - propagationSteps.push_back(testSteps); + // Record the propagator steps + propagationSteps.push_back(std::move(pOutput.first)); + if (m_cfg.recordMaterialInteractions + && pOutput.second.materialInteractions.size()) { + // Create a recorded material track + RecordedMaterialTrack rmTrack; + // Start position + rmTrack.first.first = std::move(sPosition); + // Start momentum + rmTrack.first.second = std::move(sMomentum); + // The material + rmTrack.second = std::move(pOutput.second); + // push it it + recordedMaterial.push_back(std::move(rmTrack)); + } } - // write simulated data to the event store - // - the simulated particles + // Write the propagation step data to the event store context.eventStore.add(m_cfg.propagationStepCollection, std::move(propagationSteps)); + // Write the recorded material to the event store + if (m_cfg.recordMaterialInteractions) { + context.eventStore.add(m_cfg.propagationMaterialCollection, + std::move(recordedMaterial)); + } + return ProcessCode::SUCCESS; } diff --git a/Algorithms/Propagation/include/ACTFW/Propagation/PropagationOptions.hpp b/Algorithms/Propagation/include/ACTFW/Propagation/PropagationOptions.hpp index 581b8611f2b6a98f5a8e29b3d1440c04fa27281f..71745d434e0645956af673187f3e97fcc0daf490 100644 --- a/Algorithms/Propagation/include/ACTFW/Propagation/PropagationOptions.hpp +++ b/Algorithms/Propagation/include/ACTFW/Propagation/PropagationOptions.hpp @@ -50,6 +50,12 @@ namespace Options { "prop-scattering", po::value<bool>()->default_value(true), "Apply scattering correction - in extrapolation mode only.")( + "prop-record-material", + po::value<bool>()->default_value(true), + "Record the material interaction and - in extrapolation mode only.")( + "prop-material-collection", + po::value<std::string>()->default_value("propagation-material"), + "Propagation material collection.")( "prop-ntests", po::value<size_t>()->default_value(1000), "Number of tests performed.")( @@ -70,7 +76,7 @@ namespace Options { {100. * au::_MeV, 100. * au::_GeV}), "Transverse momentum range for proprapolated tracks [in GeV].")( "prop-max-stepsize", - po::value<double>()->default_value(1 * au::_m), + po::value<double>()->default_value(10 * au::_m), "Maximum step size for the propagation [in mm].")( "prop-pt-loopers", po::value<double>()->default_value(0.3 * au::_GeV), @@ -99,6 +105,12 @@ namespace Options { read_range ietar = vm["prop-eta-range"].template as<read_range>(); read_range iptr = vm["prop-pt-range"].template as<read_range>(); + /// Material interaction behavior + pAlgConfig.energyLoss = vm["prop-energyloss"].template as<bool>(); + pAlgConfig.multipleScattering = vm["prop-scattering"].template as<bool>(); + pAlgConfig.recordMaterialInteractions + = vm["prop-record-material"].template as<bool>(); + /// Create the config for the Extrapoaltion algorithm pAlgConfig.debugOutput = vm["prop-debug"].template as<bool>(); pAlgConfig.ntests = vm["prop-ntests"].template as<size_t>(); @@ -115,6 +127,8 @@ namespace Options { pAlgConfig.propagationStepCollection = vm["prop-step-collection"].template as<std::string>(); + pAlgConfig.propagationMaterialCollection + = vm["prop-material-collection"].template as<std::string>(); return pAlgConfig; } diff --git a/CMakeLists.txt b/CMakeLists.txt index f0b8eea6353807049c9bb7cb52cc95c8db6ad4d4..ad63bc8dc7d6802d765e928620b72b27db9fa219 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,7 @@ if(BUILD_ACTS) set(ACTS_BUILD_DD4HEP_PLUGIN ${USE_DD4HEP} CACHE BOOL "Build Acts DD4HEP plugin") set(ACTS_BUILD_MATERIAL_PLUGIN ON CACHE BOOL "Build Acts Material plugin") set(ACTS_BUILD_DIGITIZATION_PLUGIN ON CACHE BOOL "Build Acts Digitization plugin") + set(ACTS_BUILD_JSON_PLUGIN ON CACHE BOOL "Build Acts Json plugin") set(ACTS_BUILD_TGEO_PLUGIN ${USE_TGEO} CACHE BOOL "Build Acts TGeo plugin") set(ACTS_BUILD_IDENTIFICATION_PLUGIN ON CACHE BOOL "Build Acts Identification plugin") add_subdirectory(external/acts-core) diff --git a/Core/include/ACTFW/Random/RandomNumbersSvc.hpp b/Core/include/ACTFW/Random/RandomNumbersSvc.hpp index d199914dba9bc75ae04d6933c1679680ea907da2..2550327f7f07f6228485df5eb8511e8385db6ce9 100644 --- a/Core/include/ACTFW/Random/RandomNumbersSvc.hpp +++ b/Core/include/ACTFW/Random/RandomNumbersSvc.hpp @@ -74,7 +74,7 @@ public: RandomEngine spawnGenerator(const AlgorithmContext& context) const; - const unsigned int + unsigned int generateSeed(const AlgorithmContext& context) const; /// Ask for the seed diff --git a/Core/include/ACTFW/Utilities/Paths.hpp b/Core/include/ACTFW/Utilities/Paths.hpp index 41d00712cb8e287ce55f67d7c7ec1301d29c6497..f0757883b5adf2c700f6ffb17f337c403c94b1cd 100644 --- a/Core/include/ACTFW/Utilities/Paths.hpp +++ b/Core/include/ACTFW/Utilities/Paths.hpp @@ -6,13 +6,10 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file -/// @date 2017-08-03 -/// @author Moritz Kiehnn <msmk@cern.ch> - #pragma once #include <string> +#include <vector> namespace FW { @@ -28,4 +25,11 @@ joinPaths(const std::string& dir, const std::string& name); std::string perEventFilepath(const std::string& dir, const std::string& name, size_t event); +/// Brief split a file list into a vector of file names to add +/// +/// @param files The joint file list +/// @param tag The splitting tag +std::vector<std::string> +splitByDelimiter(const std::string& files, char delim); + } // namespace FW diff --git a/Core/src/Random/RandomNumbersSvc.cpp b/Core/src/Random/RandomNumbersSvc.cpp index d1b812d469808d39009661459c8da499e88a6ce3..d528eb3612509bbb5b82b764b8d9240755199bdc 100644 --- a/Core/src/Random/RandomNumbersSvc.cpp +++ b/Core/src/Random/RandomNumbersSvc.cpp @@ -35,7 +35,7 @@ FW::RandomNumbersSvc::spawnGenerator(const AlgorithmContext& context) const return RandomEngine(generateSeed(context)); } -const unsigned int +unsigned int FW::RandomNumbersSvc::generateSeed(const AlgorithmContext& context) const { // use Cantor pairing function to generate a unique generator id from diff --git a/Core/src/Utilities/Paths.cpp b/Core/src/Utilities/Paths.cpp index ec81deda8401421a2d484bb2f104acd5b21dcbda..ac6ef521c2826e692a509aaf99cfcced590002a7 100644 --- a/Core/src/Utilities/Paths.cpp +++ b/Core/src/Utilities/Paths.cpp @@ -9,6 +9,8 @@ #include "ACTFW/Utilities/Paths.hpp" #include <cstdio> +#include <iostream> +#include <sstream> std::string FW::joinPaths(const std::string& dir, const std::string& name) @@ -35,3 +37,16 @@ FW::perEventFilepath(const std::string& dir, return dir + '/' + prefix + name; } } + +std::vector<std::string> +FW::splitByDelimiter(const std::string& files, char delim) +{ + std::vector<std::string> fileList; + + std::stringstream ss(files); + std::string token; + while (getline(ss, token, delim)) { + fileList.push_back(token); + } + return fileList; +} diff --git a/Detectors/ContextualDetector/include/ACTFW/ContextualDetector/AlignedDetector.hpp b/Detectors/ContextualDetector/include/ACTFW/ContextualDetector/AlignedDetector.hpp index e4f109e3e42e82b5f9426764112fe1bbf1af5f12..5553846a830c02c43be4135e6575e0e6062dc355 100644 --- a/Detectors/ContextualDetector/include/ACTFW/ContextualDetector/AlignedDetector.hpp +++ b/Detectors/ContextualDetector/include/ACTFW/ContextualDetector/AlignedDetector.hpp @@ -86,12 +86,15 @@ struct AlignedGeometry /// optionally the geometry context decorator(s) /// /// @tparam variable_map_t Type of the variable map template for parameters + /// @tparam material_decorator_t Type of the material decorator + /// /// @param vm the parameter map object + /// @param mdecorator the actual material decorator /// /// @return a TrackingGeometry object, and optional context decorator(s) - template <typename variable_map_t> + template <typename variable_map_t, typename material_decorator_t> std::pair<TrackingGeometryPtr, ContextDecorators> - operator()(variable_map_t& vm) + operator()(variable_map_t& vm, material_decorator_t mdecorator) { // -------------------------------------------------------------------------------- DetectorElement::ContextType nominalContext; @@ -105,11 +108,16 @@ struct AlignedGeometry Acts::Logging::Level volumeLogLevel = Acts::Logging::Level(vm["geo-volume-loglevel"].template as<size_t>()); - /// return the generic detector + bool buildProto + = (vm["mat-input-type"].template as<std::string>() == "proto"); + + /// return the generic detector - with aligned context decorator TrackingGeometryPtr aTrackingGeometry = FW::Generic::buildDetector<DetectorElement>(nominalContext, detectorStore, buildLevel, + std::move(mdecorator), + buildProto, surfaceLogLevel, layerLogLevel, volumeLogLevel); diff --git a/Detectors/ContextualDetector/include/ACTFW/ContextualDetector/PayloadDetector.hpp b/Detectors/ContextualDetector/include/ACTFW/ContextualDetector/PayloadDetector.hpp index 13d705ab90b4e649d5afacc86ebcebe9ebe94f72..3d2c72ca20c4d6f911f86f1ab587d1ea8e4d5884 100644 --- a/Detectors/ContextualDetector/include/ACTFW/ContextualDetector/PayloadDetector.hpp +++ b/Detectors/ContextualDetector/include/ACTFW/ContextualDetector/PayloadDetector.hpp @@ -63,12 +63,15 @@ struct PayloadGeometry /// optionally the geometry context decorator(s) /// /// @tparam variable_map_t Type of the variable map template for parameters + /// @tparam material_decorator_t Type of the material decorator + /// /// @param vm the parameter map object + /// @param mdecorator the actual material decorator /// /// @return a TrackingGeometry object, and optional context decorator(s) - template <typename variable_map_t> + template <typename variable_map_t, typename material_decorator_t> std::pair<TrackingGeometryPtr, ContextDecorators> - operator()(variable_map_t& vm) + operator()(variable_map_t& vm, material_decorator_t mdecorator) { // -------------------------------------------------------------------------------- DetectorElement::ContextType nominalContext; @@ -80,11 +83,16 @@ struct PayloadGeometry Acts::Logging::Level volumeLogLevel = Acts::Logging::Level(vm["geo-volume-loglevel"].template as<size_t>()); - /// return the generic detector + bool buildProto + = (vm["mat-input-type"].template as<std::string>() == "proto"); + + /// return the generic detector - with payload context decorator TrackingGeometryPtr pTrackingGeometry = FW::Generic::buildDetector<DetectorElement>(nominalContext, detectorStore, 0, + std::move(mdecorator), + buildProto, surfaceLogLevel, layerLogLevel, volumeLogLevel); diff --git a/Detectors/DD4hepDetector/include/ACTFW/DD4hepDetector/DD4hepDetector.hpp b/Detectors/DD4hepDetector/include/ACTFW/DD4hepDetector/DD4hepDetector.hpp index 45a441871a6cd97c2e068328dce54289299049b9..55563c5f347df06588ec7905686ea5f46fea90c6 100644 --- a/Detectors/DD4hepDetector/include/ACTFW/DD4hepDetector/DD4hepDetector.hpp +++ b/Detectors/DD4hepDetector/include/ACTFW/DD4hepDetector/DD4hepDetector.hpp @@ -38,12 +38,15 @@ struct DD4hepGeometry /// optionally the geometry context decorator(s) /// /// @tparam variable_map_t Type of the variable map template for parameters + /// @tparam material_decorator_t Type of the material decorator + /// /// @param vm the parameter map object + /// @param mdecorator the actual material decorator /// /// @return a TrackingGeometry object, and optional context decorator(s) - template <typename variable_map_t> + template <typename variable_map_t, typename material_decorator_t> std::pair<TrackingGeometryPtr, ContextDecorators> - operator()(variable_map_t& vm) + operator()(variable_map_t& vm, material_decorator_t /*mdecorator*/) { Acts::GeometryContext dd4HepContext; // read the detector config & dd4hep detector diff --git a/Detectors/GenericDetector/include/ACTFW/GenericDetector/BuildGenericDetector.hpp b/Detectors/GenericDetector/include/ACTFW/GenericDetector/BuildGenericDetector.hpp index fa7e9d259173b0f340ea2a2d81632bdf69b42f71..f9c7774522a6212b29a0c8739455f2d8c840c483 100644 --- a/Detectors/GenericDetector/include/ACTFW/GenericDetector/BuildGenericDetector.hpp +++ b/Detectors/GenericDetector/include/ACTFW/GenericDetector/BuildGenericDetector.hpp @@ -19,6 +19,7 @@ #include "Acts/Detector/TrackingGeometry.hpp" #include "Acts/Material/HomogeneousSurfaceMaterial.hpp" #include "Acts/Material/Material.hpp" +#include "Acts/Material/ProtoSurfaceMaterial.hpp" #include "Acts/Tools/CylinderVolumeBuilder.hpp" #include "Acts/Tools/CylinderVolumeHelper.hpp" #include "Acts/Tools/LayerArrayCreator.hpp" @@ -27,6 +28,7 @@ #include "Acts/Tools/SurfaceArrayCreator.hpp" #include "Acts/Tools/TrackingGeometryBuilder.hpp" #include "Acts/Tools/TrackingVolumeArrayCreator.hpp" +#include "Acts/Utilities/BinUtility.hpp" #include "Acts/Utilities/Definitions.hpp" #include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/Units.hpp" @@ -90,22 +92,28 @@ namespace Generic { /// element, each derivative of a GenericDetectorElement can be used /// /// @param gctx is the detector element dependent geometry context - /// @param surfaceLLevel is the surface building logging level - /// @param layerLLevel is the layer building logging level - /// @param volumeLLevel is the volume building logging level /// @param detectorStore is the store for the detector element + /// @param matDecorator is an optional decorator for the material /// @param level is the detector building level /// 0 - pixel barrel only /// 1 - pixel detector only /// 2 - full barrel only /// 3 - full detector (without stereo modules) + /// @param matDecorator is the source for material decoration + /// @param protoMaterial is a flag to steer proto material to be loaded + /// @param surfaceLLevel is the surface building logging level + /// @param layerLLevel is the layer building logging level + /// @param volumeLLevel is the volume building logging level /// return a unique vector to the tracking geometry template <typename detector_element_t> std::unique_ptr<const Acts::TrackingGeometry> buildDetector(const typename detector_element_t::ContextType& gctx, std::vector<std::vector<std::shared_ptr<detector_element_t>>>& - detectorStore, - size_t level, + detectorStore, + size_t level, + std::shared_ptr<const Acts::IMaterialDecorator> matDecorator + = nullptr, + bool protoMaterial = false, Acts::Logging::Level surfaceLLevel = Acts::Logging::INFO, Acts::Logging::Level layerLLevel = Acts::Logging::INFO, Acts::Logging::Level volumeLLevel = Acts::Logging::INFO) @@ -148,18 +156,40 @@ namespace Generic { std::vector<std::shared_ptr<const Acts::ITrackingVolumeBuilder>> volumeBuilders; + // Prepare the proto material - in case it's desinged to do so + // - cylindrical + Acts::BinUtility pCylinderUtility(10, -1, 1, Acts::closed, Acts::binPhi); + pCylinderUtility += Acts::BinUtility(10, -1, 1, Acts::open, Acts::binZ); + auto pCylinderMaterial + = std::make_shared<const Acts::ProtoSurfaceMaterial>(pCylinderUtility); + // - disc + Acts::BinUtility pDiscUtility(10, 0, 1, Acts::open, Acts::binR); + pDiscUtility += Acts::BinUtility(10, -1, 1, Acts::closed, Acts::binPhi); + auto pDiscMaterial + = std::make_shared<const Acts::ProtoSurfaceMaterial>(pDiscUtility); + // - plane + Acts::BinUtility pPlaneUtility(1, -1, 1, Acts::open, Acts::binX); + auto pPlaneMaterial + = std::make_shared<const Acts::ProtoSurfaceMaterial>(pPlaneUtility); + //------------------------------------------------------------------------------------- // Beam Pipe //------------------------------------------------------------------------------------- + // BeamPipe material + std::shared_ptr<const Acts::ISurfaceMaterial> beamPipeMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + Acts::MaterialProperties(352.8, 407., 9.012, 4., 1.848e-3, 0.8)); + if (protoMaterial) { + beamPipeMaterial = pCylinderMaterial; + } + // configure the beam pipe layer builder Acts::PassiveLayerBuilder::Config bplConfig; bplConfig.layerIdentification = "BeamPipe"; bplConfig.centralLayerRadii = std::vector<double>(1, 19.); bplConfig.centralLayerHalflengthZ = std::vector<double>(1, 3000.); bplConfig.centralLayerThickness = std::vector<double>(1, 0.8); - bplConfig.centralLayerMaterial - = {std::make_shared<Acts::HomogeneousSurfaceMaterial>( - Acts::MaterialProperties(352.8, 407., 9.012, 4., 1.848e-3, 0.8))}; + bplConfig.centralLayerMaterial = {beamPipeMaterial}; auto beamPipeBuilder = std::make_shared<const Acts::PassiveLayerBuilder>( bplConfig, Acts::getDefaultLogger("BeamPipeLayerBuilder", layerLLevel)); // create the volume for the beam pipe @@ -184,13 +214,44 @@ namespace Generic { // some prep work // envelope for layers std::pair<double, double> pcEnvelope(2., 2.); - // Module material - X0, L0, A, Z, Rho - Acts::Material pcMaterial(95.7, 465.2, 28.03, 14., 2.32e-3); + + double pCentralModuleT = 0.15; + double pEndcapModuleT = 0.15; + + // Module material properties - X0, L0, A, Z, Rho + Acts::Material pcMaterial(95.7, 465.2, 28.03, 14., 2.32e-3); + Acts::MaterialProperties pcModuleMaterial( + 95.7, 465.2, 28.03, 14., 2.32e-3, pCentralModuleT); + + Acts::MaterialProperties peModuleMaterial( + 95.7, 465.2, 28.03, 14., 2.32e-3, pEndcapModuleT); + // Layer material properties - thickness, X0, L0, A, Z, Rho Acts::MaterialProperties pcmbProperties( 95.7, 465.2, 28.03, 14., 2.32e-3, 1.5 * Acts::units::_mm); Acts::MaterialProperties pcmecProperties( 95.7, 465.2, 28.03, 14., 2.32e-3, 1.5 * Acts::units::_mm); + + // Module, central and disc material + std::shared_ptr<const Acts::ISurfaceMaterial> pCentralMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + pcmbProperties); + std::shared_ptr<const Acts::ISurfaceMaterial> pEndcapMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + pcmecProperties); + std::shared_ptr<const Acts::ISurfaceMaterial> pCentralModuleMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + pcModuleMaterial); + std::shared_ptr<const Acts::ISurfaceMaterial> pEndcapModuleMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + peModuleMaterial); + if (protoMaterial) { + pCentralMaterial = pCylinderMaterial; + pCentralModuleMaterial = pPlaneMaterial; + pEndcapMaterial = pDiscMaterial; + pEndcapModuleMaterial = pPlaneMaterial; + } + // configure the pixel proto layer builder typename ProtoLayerCreator::Config pplConfig; // standard, an approach envelope @@ -204,12 +265,15 @@ namespace Generic { = {pcEnvelope, pcEnvelope, pcEnvelope, pcEnvelope}; pplConfig.centralModuleBinningSchema = {{16, 14}, {32, 14}, {52, 14}, {78, 14}}; - pplConfig.centralModuleTiltPhi = {0.14, 0.14, 0.14, 0.14}; - pplConfig.centralModuleHalfX = {8.4, 8.4, 8.4, 8.4}; - pplConfig.centralModuleHalfY = {36., 36., 36., 36.}; - pplConfig.centralModuleThickness = {0.15, 0.15, 0.15, 0.15}; - pplConfig.centralModuleMaterial - = {pcMaterial, pcMaterial, pcMaterial, pcMaterial}; + pplConfig.centralModuleTiltPhi = {0.14, 0.14, 0.14, 0.14}; + pplConfig.centralModuleHalfX = {8.4, 8.4, 8.4, 8.4}; + pplConfig.centralModuleHalfY = {36., 36., 36., 36.}; + pplConfig.centralModuleThickness + = {pCentralModuleT, pCentralModuleT, pCentralModuleT, pCentralModuleT}; + pplConfig.centralModuleMaterial = {pCentralModuleMaterial, + pCentralModuleMaterial, + pCentralModuleMaterial, + pCentralModuleMaterial}; // pitch definitions pplConfig.centralModuleReadoutBinsX = {336, 336, 336, 336}; pplConfig.centralModuleReadoutBinsY = {1280, 1280, 1280, 1280}; @@ -252,15 +316,17 @@ namespace Generic { 1. * Acts::units::_mm, 1. * Acts::units::_mm, 1. * Acts::units::_mm}; - std::vector<double> perHX = {8.4, 8.4}; // half length x - std::vector<double> perHY = {36., 36.}; // half length y - std::vector<size_t> perBP = {40, 68}; // bins in phi - std::vector<double> perT = {0.15, 0.15}; // module thickness - std::vector<size_t> perBX = {336, 336}; // bins in x - std::vector<size_t> perBY = {1280, 1280}; // bins in y - std::vector<int> perRS = {-1, -1}; // readout side - std::vector<double> perLA = {0., 0.}; // lorentz angle - std::vector<Acts::Material> perM = {pcMaterial, pcMaterial}; // material + std::vector<double> perHX = {8.4, 8.4}; // half length x + std::vector<double> perHY = {36., 36.}; // half length y + std::vector<size_t> perBP = {40, 68}; // bins in phi + std::vector<double> perT + = {pEndcapModuleT, pEndcapModuleT}; // module thickness + std::vector<size_t> perBX = {336, 336}; // bins in x + std::vector<size_t> perBY = {1280, 1280}; // bins in y + std::vector<int> perRS = {-1, -1}; // readout side + std::vector<double> perLA = {0., 0.}; // lorentz angle + std::vector<std::shared_ptr<const Acts::ISurfaceMaterial>> perM + = {pEndcapModuleMaterial, pEndcapModuleMaterial}; // material pplConfig.posnegModuleMinHalfX = std::vector<std::vector<double>>(7, perHX); pplConfig.posnegModuleMaxHalfX = {}; @@ -274,8 +340,9 @@ namespace Generic { pplConfig.posnegModuleReadoutSide = std::vector<std::vector<int>>(7, perRS); pplConfig.posnegModuleLorentzAngle = std::vector<std::vector<double>>(7, perLA); - pplConfig.posnegModuleMaterial - = std::vector<std::vector<Acts::Material>>(7, perM); + pplConfig.posnegModuleMaterial = std:: + vector<std::vector<std::shared_ptr<const Acts::ISurfaceMaterial>>>( + 7, perM); // no frontside/backside pplConfig.posnegModuleFrontsideStereo = {}; @@ -310,19 +377,19 @@ namespace Generic { plbConfig.centralProtoLayers = pplCreator.centralProtoLayers(gctx, detectorStore); plbConfig.centralLayerMaterialConcentration = {1, 1, 1, 1}; - plbConfig.centralLayerMaterialProperties - = {pcmbProperties, pcmbProperties, pcmbProperties, pcmbProperties}; + plbConfig.centralLayerMaterial = { + pCentralMaterial, pCentralMaterial, pCentralMaterial, pCentralMaterial}; if (level > 0) { // material concentration is always behind the layer in the pixels plbConfig.posnegLayerMaterialConcentration = std::vector<int>(7, 0); // layer structure surface has pixel material properties - plbConfig.posnegLayerMaterialProperties = {pcmecProperties, - pcmecProperties, - pcmecProperties, - pcmecProperties, - pcmecProperties, - pcmecProperties, - pcmecProperties}; + plbConfig.posnegLayerMaterial = {pEndcapMaterial, + pEndcapMaterial, + pEndcapMaterial, + pEndcapMaterial, + pEndcapMaterial, + pEndcapMaterial, + pEndcapMaterial}; // negative proto layers plbConfig.negativeProtoLayers = pplCreator.negativeProtoLayers(gctx, detectorStore); @@ -353,14 +420,21 @@ namespace Generic { //------------------------------------------------------------------------------------- // Pixel Support Tybe (PST) //------------------------------------------------------------------------------------- + // Material + std::shared_ptr<const Acts::ISurfaceMaterial> pstMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + Acts::MaterialProperties(352.8, 407., 9.012, 4., 1.848e-3, 1.8)); + if (protoMaterial) { + pstMaterial = pCylinderMaterial; + } + + // Configuration Acts::PassiveLayerBuilder::Config pstConfig; pstConfig.layerIdentification = "PST"; pstConfig.centralLayerRadii = std::vector<double>(1, 200.); pstConfig.centralLayerHalflengthZ = std::vector<double>(1, 2800.); pstConfig.centralLayerThickness = std::vector<double>(1, 1.8); - pstConfig.centralLayerMaterial - = {std::make_shared<Acts::HomogeneousSurfaceMaterial>( - Acts::MaterialProperties(352.8, 407., 9.012, 4., 1.848e-3, 1.8))}; + pstConfig.centralLayerMaterial = {pstMaterial}; auto pstBuilder = std::make_shared<const Acts::PassiveLayerBuilder>( pstConfig, Acts::getDefaultLogger("PSTBuilder", layerLLevel)); // create the volume for the beam pipe @@ -386,16 +460,46 @@ namespace Generic { // fill necessary vectors for configuration //------------------------------------------------------------------------------------- // some prep work + + double ssCentralModuleT = 0.25; + double ssEndcapModuleT = 0.25; // envelope double std::pair<double, double> ssEnvelope(2., 2.); + + // Module material properties - X0, L0, A, Z, Rho + Acts::Material sscMaterial(95.7, 465.2, 28.03, 14., 2.32e-3); + Acts::MaterialProperties sscModuleMaterial( + 95.7, 465.2, 28.03, 14., 2.32e-3, ssCentralModuleT); + + Acts::MaterialProperties sseModuleMaterial( + 95.7, 465.2, 28.03, 14., 2.32e-3, ssEndcapModuleT); + // Layer material properties - thickness, X0, L0, A, Z, Rho Acts::MaterialProperties ssbmProperties( 95.7, 465.2, 28.03, 14., 2.32e-3, 2. * Acts::units::_mm); Acts::MaterialProperties ssecmProperties( 95.7, 465.2, 28.03, 14., 2.32e-3, 2.5 * Acts::units::_mm); - // Module material - X0, L0, A, Z, Rho - Acts::Material ssMaterial(95.7, 465.2, 28.03, 14., 2.32e-3); + // Module, central and disc material + std::shared_ptr<const Acts::ISurfaceMaterial> ssCentralMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + ssbmProperties); + std::shared_ptr<const Acts::ISurfaceMaterial> ssEndcapMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + ssecmProperties); + std::shared_ptr<const Acts::ISurfaceMaterial> ssCentralModuleMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + sscModuleMaterial); + std::shared_ptr<const Acts::ISurfaceMaterial> ssEndcapModuleMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + sseModuleMaterial); + if (protoMaterial) { + ssCentralMaterial = pCylinderMaterial; + ssCentralModuleMaterial = pPlaneMaterial; + ssEndcapMaterial = pDiscMaterial; + ssEndcapModuleMaterial = pPlaneMaterial; + } + // ---------------------------------------------------------------------------- // Configure the short strip proto layer builder typename ProtoLayerCreator::Config ssplConfig; @@ -410,7 +514,10 @@ namespace Generic { ssplConfig.centralModuleTiltPhi = {-0.15, -0.15, -0.15, -0.15}; ssplConfig.centralModuleHalfX = {24., 24., 24., 24.}; ssplConfig.centralModuleHalfY = {54., 54., 54., 54.}; - ssplConfig.centralModuleThickness = {0.25, 0.25, 0.25, 0.25}; + ssplConfig.centralModuleThickness = {ssCentralModuleT, + ssCentralModuleT, + ssCentralModuleT, + ssCentralModuleT}; ssplConfig.centralModuleReadoutBinsX = {600, 600, 600, 600}; // 80 um pitch @@ -419,8 +526,10 @@ namespace Generic { ssplConfig.centralModuleReadoutSide = {1, 1, 1, 1}; ssplConfig.centralModuleLorentzAngle = {0.12, 0.12, 0.12, 0.12}; - ssplConfig.centralModuleMaterial - = {ssMaterial, ssMaterial, ssMaterial, ssMaterial}; + ssplConfig.centralModuleMaterial = {ssCentralModuleMaterial, + ssCentralModuleMaterial, + ssCentralModuleMaterial, + ssCentralModuleMaterial}; ssplConfig.centralModuleFrontsideStereo = {}; ssplConfig.centralModuleBacksideStereo = {}; ssplConfig.centralModuleBacksideGap = {}; @@ -449,10 +558,13 @@ namespace Generic { std::vector<int> mrReadoutSide = {1, 1, 1}; std::vector<double> mrLorentzAngle = {0., 0., 0.}; - std::vector<size_t> mPhiBins = {54, 56, 60}; - std::vector<double> mThickness = {0.25, 0.25, 0.25}; - std::vector<Acts::Material> mMaterial - = {ssMaterial, ssMaterial, ssMaterial}; + std::vector<size_t> mPhiBins = {54, 56, 60}; + std::vector<double> mThickness + = {ssEndcapModuleT, ssEndcapModuleT, ssEndcapModuleT}; + std::vector<std::shared_ptr<const Acts::ISurfaceMaterial>> mMaterial + = {ssEndcapModuleMaterial, + ssEndcapModuleMaterial, + ssEndcapModuleMaterial}; ssplConfig.posnegLayerBinMultipliers = {1, 2}; @@ -481,8 +593,9 @@ namespace Generic { ssplConfig.posnegModuleLorentzAngle = std::vector<std::vector<double>>(nposnegs, mrLorentzAngle); - ssplConfig.posnegModuleMaterial - = std::vector<std::vector<Acts::Material>>(nposnegs, mMaterial); + ssplConfig.posnegModuleMaterial = std:: + vector<std::vector<std::shared_ptr<const Acts::ISurfaceMaterial>>>( + nposnegs, mMaterial); ssplConfig.posnegModuleFrontsideStereo = {}; ssplConfig.posnegModuleBacksideStereo = {}; @@ -517,8 +630,10 @@ namespace Generic { sslbConfig.centralProtoLayers = ssplCreator.centralProtoLayers(gctx, detectorStore); sslbConfig.centralLayerMaterialConcentration = {-1, -1, -1, -1}; - sslbConfig.centralLayerMaterialProperties - = {ssbmProperties, ssbmProperties, ssbmProperties, ssbmProperties}; + sslbConfig.centralLayerMaterial = {ssCentralMaterial, + ssCentralMaterial, + ssCentralMaterial, + ssCentralMaterial}; if (level > 2) { sslbConfig.negativeProtoLayers @@ -528,8 +643,9 @@ namespace Generic { sslbConfig.posnegLayerMaterialConcentration = std::vector<int>(nposnegs, 0); - sslbConfig.posnegLayerMaterialProperties - = std::vector<Acts::MaterialProperties>(nposnegs, ssecmProperties); + sslbConfig.posnegLayerMaterial + = std::vector<std::shared_ptr<const Acts::ISurfaceMaterial>>( + nposnegs, ssEndcapMaterial); } // define the builder @@ -558,16 +674,47 @@ namespace Generic { //------------------------------------------------------------------------------------- // fill necessary vectors for configuration //------------------------------------------------------------------------------------- + // some prep work // envelope double std::pair<double, double> lsEnvelope(2., 2.); + + double lsCentralModuleT = 0.35; + double lsEndcapModuleT = 0.35; + + // Module material properties - X0, L0, A, Z, Rho + Acts::Material lsMaterial(95.7, 465.2, 28.03, 14., 2.32e-3); + Acts::MaterialProperties lscModuleMaterial( + 95.7, 465.2, 28.03, 14., 2.32e-3, lsCentralModuleT); + + Acts::MaterialProperties lseModuleMaterial( + 95.7, 465.2, 28.03, 14., 2.32e-3, lsEndcapModuleT); + // Layer material properties - thickness, X0, L0, A, Z, Rho - barrel Acts::MaterialProperties lsbmProperties( 95.7, 465.2, 28.03, 14., 2.32e-3, 2.5 * Acts::units::_mm); Acts::MaterialProperties lsecmProperties( 95.7, 465.2, 28.03, 14., 2.32e-3, 3.5 * Acts::units::_mm); - // Module material - X0, L0, A, Z, Rho - Acts::Material lsMaterial(95.7, 465.2, 28.03, 14., 2.32e-3); + + // Module, central and disc material + std::shared_ptr<const Acts::ISurfaceMaterial> lsCentralMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + lsbmProperties); + std::shared_ptr<const Acts::ISurfaceMaterial> lsEndcapMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + lsecmProperties); + std::shared_ptr<const Acts::ISurfaceMaterial> lsCentralModuleMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + lscModuleMaterial); + std::shared_ptr<const Acts::ISurfaceMaterial> lsEndcapModuleMaterial + = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + lseModuleMaterial); + if (protoMaterial) { + lsCentralMaterial = pCylinderMaterial; + lsCentralModuleMaterial = pPlaneMaterial; + lsEndcapMaterial = pDiscMaterial; + lsEndcapModuleMaterial = pPlaneMaterial; + } // The proto layer creator typename ProtoLayerCreator::Config lsplConfig; @@ -581,8 +728,9 @@ namespace Generic { lsplConfig.centralModuleTiltPhi = {-0.15, -0.15}; lsplConfig.centralModuleHalfX = {24., 24.}; lsplConfig.centralModuleHalfY = {54., 54.}; - lsplConfig.centralModuleThickness = {0.35, 0.35}; - lsplConfig.centralModuleMaterial = {lsMaterial, lsMaterial}; + lsplConfig.centralModuleThickness = {lsCentralModuleT, lsCentralModuleT}; + lsplConfig.centralModuleMaterial + = {lsCentralModuleMaterial, lsCentralModuleMaterial}; lsplConfig.centralModuleReadoutBinsX = {400, 400}; // 120 um pitch lsplConfig.centralModuleReadoutBinsY = {10, 10}; // 10 strips = 10.8 mm @@ -611,8 +759,8 @@ namespace Generic { mrMaxHx = {64.2, 72.}; mrHy = {78., 78.}; mPhiBins = {48, 50}; - mThickness = {0.35, 0.35}; - mMaterial = {lsMaterial, lsMaterial}; + mThickness = {lsEndcapModuleT, lsEndcapModuleT}; + mMaterial = {lsEndcapModuleMaterial, lsEndcapModuleMaterial}; mrReadoutBinsX = {1070, 1200}; // 120 um pitch mrReadoutBinsY = {15, 15}; // 15 strips - 10.2 mm @@ -646,8 +794,9 @@ namespace Generic { lsplConfig.posnegModuleLorentzAngle = std::vector<std::vector<double>>(nposnegs, mrLorentzAngle); - lsplConfig.posnegModuleMaterial - = std::vector<std::vector<Acts::Material>>(nposnegs, mMaterial); + lsplConfig.posnegModuleMaterial = std:: + vector<std::vector<std::shared_ptr<const Acts::ISurfaceMaterial>>>( + nposnegs, mMaterial); lsplConfig.posnegModuleFrontsideStereo = {}; lsplConfig.posnegModuleBacksideStereo = {}; lsplConfig.posnegModuleBacksideGap = {}; @@ -678,16 +827,16 @@ namespace Generic { lslbConfig.layerCreator = layerCreator; lslbConfig.layerIdentification = "LStrip"; lslbConfig.centralLayerMaterialConcentration = {-1, -1}; - lslbConfig.centralLayerMaterialProperties - = {lsbmProperties, lsbmProperties}; + lslbConfig.centralLayerMaterial = {lsCentralMaterial, lsCentralMaterial}; lslbConfig.centralProtoLayers = lsplCreator.centralProtoLayers(gctx, detectorStore); if (level > 2) { lslbConfig.posnegLayerMaterialConcentration = std::vector<int>(nposnegs, 0); - lslbConfig.posnegLayerMaterialProperties - = std::vector<Acts::MaterialProperties>(nposnegs, lsecmProperties); + lslbConfig.posnegLayerMaterial + = std::vector<std::shared_ptr<const Acts::ISurfaceMaterial>>( + nposnegs, lsEndcapMaterial); lslbConfig.negativeProtoLayers = lsplCreator.negativeProtoLayers(gctx, detectorStore); lslbConfig.positiveProtoLayers @@ -721,10 +870,11 @@ namespace Generic { for (auto& vb : volumeBuilders) { tgConfig.trackingVolumeBuilders.push_back( [=](const auto& context, const auto& inner, const auto&) { - return vb->trackingVolume(gctx, inner); + return vb->trackingVolume(context, inner); }); } tgConfig.trackingVolumeHelper = cylinderVolumeHelper; + tgConfig.materialDecorator = matDecorator; auto cylinderGeometryBuilder = std::make_shared<const Acts::TrackingGeometryBuilder>( diff --git a/Detectors/GenericDetector/include/ACTFW/GenericDetector/GenericDetector.hpp b/Detectors/GenericDetector/include/ACTFW/GenericDetector/GenericDetector.hpp index 1bbcbce80b85c9b15d419c54001262f81d8ff83b..2649435be0c5c004dac5681a6bd8566ae8347caa 100644 --- a/Detectors/GenericDetector/include/ACTFW/GenericDetector/GenericDetector.hpp +++ b/Detectors/GenericDetector/include/ACTFW/GenericDetector/GenericDetector.hpp @@ -47,12 +47,15 @@ struct GenericGeometry /// optionally the geometry context decorator(s) /// /// @tparam variable_map_t Type of the variable map template for parameters + /// @tparam material_decorator_t Type of the material decorator + /// /// @param vm the parameter map object + /// @param mdecorator the actual material decorator /// /// @return a TrackingGeometry object, and optional context decorator(s) - template <typename variable_map_t> + template <typename variable_map_t, typename material_decorator_t> std::pair<TrackingGeometryPtr, ContextDecorators> - operator()(variable_map_t& vm) + operator()(variable_map_t& vm, material_decorator_t mdecorator) { // -------------------------------------------------------------------------------- DetectorElement::ContextType nominalContext; @@ -65,11 +68,17 @@ struct GenericGeometry = Acts::Logging::Level(vm["geo-layer-loglevel"].template as<size_t>()); Acts::Logging::Level volumeLogLevel = Acts::Logging::Level(vm["geo-volume-loglevel"].template as<size_t>()); - /// return the generic detector + + bool buildProto + = (vm["mat-input-type"].template as<std::string>() == "proto"); + + /// Return the generic detector TrackingGeometryPtr gGeometry = FW::Generic::buildDetector<DetectorElement>(nominalContext, detectorStore, buildLevel, + std::move(mdecorator), + buildProto, surfaceLogLevel, layerLogLevel, volumeLogLevel); diff --git a/Detectors/GenericDetector/include/ACTFW/GenericDetector/GenericDetectorElement.hpp b/Detectors/GenericDetector/include/ACTFW/GenericDetector/GenericDetectorElement.hpp index 55dcb77e8afb3b4de2fe8fc920e908bbac2d304e..3d816d6feafbe039da1433fc55436a0674a167f6 100644 --- a/Detectors/GenericDetector/include/ACTFW/GenericDetector/GenericDetectorElement.hpp +++ b/Detectors/GenericDetector/include/ACTFW/GenericDetector/GenericDetectorElement.hpp @@ -18,7 +18,7 @@ namespace Acts { class Surface; class PlanarBounds; class DiscBounds; -class SurfaceMaterial; +class ISurfaceMaterial; class DigitizationModule; } @@ -50,7 +50,7 @@ namespace Generic { std::shared_ptr<const Acts::Transform3D> transform, std::shared_ptr<const Acts::PlanarBounds> pBounds, double thickness, - std::shared_ptr<const Acts::SurfaceMaterial> material = nullptr, + std::shared_ptr<const Acts::ISurfaceMaterial> material = nullptr, std::shared_ptr<const Acts::DigitizationModule> digitzationModule = nullptr); @@ -67,7 +67,7 @@ namespace Generic { std::shared_ptr<const Acts::Transform3D> transform, std::shared_ptr<const Acts::DiscBounds> dBounds, double thickness, - std::shared_ptr<const Acts::SurfaceMaterial> material = nullptr, + std::shared_ptr<const Acts::ISurfaceMaterial> material = nullptr, std::shared_ptr<const Acts::DigitizationModule> digitzationModule = nullptr); diff --git a/Detectors/GenericDetector/include/ACTFW/GenericDetector/LayerBuilderT.hpp b/Detectors/GenericDetector/include/ACTFW/GenericDetector/LayerBuilderT.hpp index c7fd62a9fc5edb9d4021815bea8300210e9843b1..129e030bf7b53d345897ec893a6395724e9e9355 100644 --- a/Detectors/GenericDetector/include/ACTFW/GenericDetector/LayerBuilderT.hpp +++ b/Detectors/GenericDetector/include/ACTFW/GenericDetector/LayerBuilderT.hpp @@ -57,8 +57,9 @@ namespace Generic { /// the material concentration: -1 inner, 0 central, 1 outer std::vector<int> centralLayerMaterialConcentration; - /// the assigned material propertis @todo change to surface material - std::vector<Acts::MaterialProperties> centralLayerMaterialProperties; + /// The assigned surface material + std::vector<std::shared_ptr<const Acts::ISurfaceMaterial>> + centralLayerMaterial; /// The pre-produced proto layers for the negative part std::vector<ProtoLayerSurfaces> negativeProtoLayers; @@ -66,18 +67,19 @@ namespace Generic { /// The pre-produced proto layers for the positive part std::vector<ProtoLayerSurfaces> positiveProtoLayers; - /// the material concentration: -1 inner, 0 central, 1 outer + /// The material concentration: -1 inner, 0 central, 1 outer std::vector<int> posnegLayerMaterialConcentration; - /// the material prooperties @todo change to surface material - std::vector<Acts::MaterialProperties> posnegLayerMaterialProperties; + /// The surface material + std::vector<std::shared_ptr<const Acts::ISurfaceMaterial>> + posnegLayerMaterial; - /// helper tools: layer creator + /// Helper tools: layer creator std::shared_ptr<const Acts::LayerCreator> layerCreator = nullptr; - /// helper tools: central passive layer builder + /// Helper tools: central passive layer builder std::shared_ptr<const Acts::ILayerBuilder> centralPassiveLayerBuilder = nullptr; - /// helper tools: p/n passive layer builder + /// Helper tools: p/n passive layer builder std::shared_ptr<const Acts::ILayerBuilder> posnegPassiveLayerBuilder = nullptr; }; @@ -142,16 +144,13 @@ namespace Generic { gctx, cpl.surfaces, cpl.bins0, cpl.bins1, cpl.protoLayer); // the layer is built let's see if it needs material - if (m_cfg.centralLayerMaterialProperties.size()) { - // get the material from configuration - Acts::MaterialProperties layerMaterialProperties - = m_cfg.centralLayerMaterialProperties.at(icl); - std::shared_ptr<const Acts::SurfaceMaterial> layerMaterialPtr( - new Acts::HomogeneousSurfaceMaterial(layerMaterialProperties)); + if (m_cfg.centralLayerMaterial.size()) { + std::shared_ptr<const Acts::ISurfaceMaterial> layerMaterialPtr + = m_cfg.centralLayerMaterial.at(icl); // central material if (m_cfg.centralLayerMaterialConcentration.at(icl) == 0.) { // the layer surface is the material surface - cLayer->surfaceRepresentation().setAssociatedMaterial( + cLayer->surfaceRepresentation().assignSurfaceMaterial( layerMaterialPtr); ACTS_VERBOSE("- and material at central layer surface."); } else { @@ -163,12 +162,12 @@ namespace Generic { if (m_cfg.centralLayerMaterialConcentration.at(icl) > 0) { auto mutableOuterSurface = const_cast<Acts::Surface*>(approachSurfaces.at(1)); - mutableOuterSurface->setAssociatedMaterial(layerMaterialPtr); + mutableOuterSurface->assignSurfaceMaterial(layerMaterialPtr); ACTS_VERBOSE("- and material at outer approach surface"); } else { auto mutableInnerSurface = const_cast<Acts::Surface*>(approachSurfaces.at(0)); - mutableInnerSurface->setAssociatedMaterial(layerMaterialPtr); + mutableInnerSurface->assignSurfaceMaterial(layerMaterialPtr); ACTS_VERBOSE("- and material at inner approach surface"); } } @@ -228,15 +227,14 @@ namespace Generic { gctx, ple.surfaces, ple.bins0, ple.bins1, ple.protoLayer); // the layer is built let's see if it needs material - if (m_cfg.posnegLayerMaterialProperties.size()) { - std::shared_ptr<const Acts::SurfaceMaterial> layerMaterialPtr( - new Acts::HomogeneousSurfaceMaterial( - m_cfg.posnegLayerMaterialProperties[ipnl])); + if (m_cfg.posnegLayerMaterial.size()) { + std::shared_ptr<const Acts::ISurfaceMaterial> layerMaterialPtr + = m_cfg.posnegLayerMaterial[ipnl]; // central material if (m_cfg.posnegLayerMaterialConcentration.at(ipnl) == 0.) { // assign the surface material - the layer surface is the material // surface - eLayer->surfaceRepresentation().setAssociatedMaterial( + eLayer->surfaceRepresentation().assignSurfaceMaterial( layerMaterialPtr); ACTS_VERBOSE("- and material at central layer surface."); } else { @@ -249,13 +247,13 @@ namespace Generic { int sf = side < 0 ? 0 : 1; auto mutableInnerSurface = const_cast<Acts::Surface*>(approachSurfaces.at(sf)); - mutableInnerSurface->setAssociatedMaterial(layerMaterialPtr); + mutableInnerSurface->assignSurfaceMaterial(layerMaterialPtr); ACTS_VERBOSE("- and material at outer approach surfaces."); } else { int sf = side < 0 ? 1 : 0; auto mutableOuterSurface = const_cast<Acts::Surface*>(approachSurfaces.at(sf)); - mutableOuterSurface->setAssociatedMaterial(layerMaterialPtr); + mutableOuterSurface->assignSurfaceMaterial(layerMaterialPtr); ACTS_VERBOSE("- and material at inner approach surfaces."); } } diff --git a/Detectors/GenericDetector/include/ACTFW/GenericDetector/ProtoLayerCreatorT.hpp b/Detectors/GenericDetector/include/ACTFW/GenericDetector/ProtoLayerCreatorT.hpp index 1a0375f2d625314984361c6eced5891a6c9df68d..dc900895a3918ee45ea7c94da3e36da71c9010ed 100644 --- a/Detectors/GenericDetector/include/ACTFW/GenericDetector/ProtoLayerCreatorT.hpp +++ b/Detectors/GenericDetector/include/ACTFW/GenericDetector/ProtoLayerCreatorT.hpp @@ -14,9 +14,7 @@ #include "Acts/Detector/DetectorElementBase.hpp" #include "Acts/Layers/ApproachDescriptor.hpp" #include "Acts/Layers/ProtoLayer.hpp" -#include "Acts/Material/HomogeneousSurfaceMaterial.hpp" -#include "Acts/Material/Material.hpp" -#include "Acts/Material/MaterialProperties.hpp" +#include "Acts/Material/ISurfaceMaterial.hpp" #include "Acts/Plugins/Digitization/CartesianSegmentation.hpp" #include "Acts/Plugins/Digitization/DigitizationModule.hpp" #include "Acts/Surfaces/PlanarBounds.hpp" @@ -103,8 +101,9 @@ namespace Generic { std::vector<int> centralModuleReadoutSide; /// the central volume readout schema std::vector<double> centralModuleLorentzAngle; - /// the module material @todo change to surface material - std::vector<Acts::Material> centralModuleMaterial; + /// the module material + std::vector<std::shared_ptr<const Acts::ISurfaceMaterial>> + centralModuleMaterial; /// the module front side stereo (if exists) std::vector<double> centralModuleFrontsideStereo; /// the module back side stereo (if exists) @@ -140,8 +139,9 @@ namespace Generic { std::vector<std::vector<int>> posnegModuleReadoutSide; /// the central volume readout schema std::vector<std::vector<double>> posnegModuleLorentzAngle; - /// the module material @todo change to surface material - std::vector<std::vector<Acts::Material>> posnegModuleMaterial; + /// the module material + std::vector<std::vector<std::shared_ptr<const Acts::ISurfaceMaterial>>> + posnegModuleMaterial; /// the module front side stereo (if exists) std::vector<std::vector<double>> posnegModuleFrontsideStereo; /// the module back side stereo (if exists) @@ -282,23 +282,18 @@ namespace Generic { moduleDigitizationPtr = std::make_shared<const Acts::DigitizationModule>( moduleSegmentation, - m_cfg.centralModuleThickness.at(icl), + 0.5 * m_cfg.centralModuleThickness.at(icl), m_cfg.centralModuleReadoutSide.at(icl), m_cfg.centralModuleLorentzAngle.at(icl)); } // prepartation : // create the Module material from input - std::shared_ptr<const Acts::SurfaceMaterial> moduleMaterialPtr + std::shared_ptr<const Acts::ISurfaceMaterial> moduleMaterialPtr = nullptr; if (m_cfg.centralModuleMaterial.size()) { // get the sensor material from configuration - Acts::Material moduleMaterial = m_cfg.centralModuleMaterial.at(icl); - Acts::MaterialProperties moduleMaterialProperties(moduleMaterial, - moduleThickness); - // create a new surface material - moduleMaterialPtr = std::shared_ptr<const Acts::SurfaceMaterial>( - new Acts::HomogeneousSurfaceMaterial(moduleMaterialProperties)); + moduleMaterialPtr = m_cfg.centralModuleMaterial.at(icl); } // confirm @@ -524,20 +519,17 @@ namespace Generic { moduleDigitizationPtr = std::make_shared<const Acts::DigitizationModule>( moduleSegmentation, - moduleThickness, + 0.5 * moduleThickness, m_cfg.posnegModuleReadoutSide.at(ipnl).at(ipnR), m_cfg.posnegModuleLorentzAngle.at(ipnl).at(ipnR)); } // (3) module material // create the Module material from input - std::shared_ptr<const Acts::SurfaceMaterial> moduleMaterialPtr + std::shared_ptr<const Acts::ISurfaceMaterial> moduleMaterialPtr = nullptr; if (m_cfg.posnegModuleMaterial.size()) { - Acts::MaterialProperties moduleMaterialProperties( - m_cfg.posnegModuleMaterial.at(ipnl).at(ipnR), moduleThickness); // and create the shared pointer - moduleMaterialPtr = std::shared_ptr<const Acts::SurfaceMaterial>( - new Acts::HomogeneousSurfaceMaterial(moduleMaterialProperties)); + moduleMaterialPtr = m_cfg.posnegModuleMaterial.at(ipnl).at(ipnR); } // low loop over the phi positions and build the stuff @@ -572,7 +564,8 @@ namespace Generic { moduleTransform, moduleBounds, moduleThickness, - moduleMaterialPtr); + moduleMaterialPtr, + moduleDigitizationPtr); layerStore.push_back(module); // now deal with the potential backside @@ -605,7 +598,8 @@ namespace Generic { moduleTransform, moduleBounds, moduleThickness, - moduleMaterialPtr); + moduleMaterialPtr, + moduleDigitizationPtr); // Put into the detector store layerStore.push_back(std::move(bsmodule)); // register the backside of the binmembers @@ -630,9 +624,9 @@ namespace Generic { layerBinsR *= m_cfg.posnegLayerBinMultipliers.first; } size_t layerBinsPhi = 0; - // take the maximum phi bins in that layer + // take the minimum phi bins in that layer for (unsigned int phiBins : m_cfg.posnegModulePhiBins.at(ipnl)) { - layerBinsPhi = phiBins > layerBinsPhi ? phiBins : layerBinsPhi; + layerBinsPhi = phiBins < layerBinsPhi ? phiBins : layerBinsPhi; layerBinsPhi *= m_cfg.posnegLayerBinMultipliers.second; } // create the layers with the surface arrays diff --git a/Detectors/GenericDetector/src/GenericDetectorElement.cpp b/Detectors/GenericDetector/src/GenericDetectorElement.cpp index 1648f57b628856f4a3ce585eb5c73ca50cab27d6..dd003ed4736eeafcce1b7783d93c28971cc3002a 100644 --- a/Detectors/GenericDetector/src/GenericDetectorElement.cpp +++ b/Detectors/GenericDetector/src/GenericDetectorElement.cpp @@ -17,7 +17,7 @@ FW::Generic::GenericDetectorElement::GenericDetectorElement( std::shared_ptr<const Acts::Transform3D> transform, std::shared_ptr<const Acts::PlanarBounds> pBounds, double thickness, - std::shared_ptr<const Acts::SurfaceMaterial> material, + std::shared_ptr<const Acts::ISurfaceMaterial> material, std::shared_ptr<const Acts::DigitizationModule> digitizationModule) : Acts::IdentifiedDetectorElement() , m_elementIdentifier(std::move(identifier)) @@ -31,7 +31,7 @@ FW::Generic::GenericDetectorElement::GenericDetectorElement( { auto mutableSurface = std::const_pointer_cast<Acts::Surface>(m_elementSurface); - mutableSurface->setAssociatedMaterial(material); + mutableSurface->assignSurfaceMaterial(material); } FW::Generic::GenericDetectorElement::GenericDetectorElement( @@ -39,7 +39,7 @@ FW::Generic::GenericDetectorElement::GenericDetectorElement( std::shared_ptr<const Acts::Transform3D> transform, std::shared_ptr<const Acts::DiscBounds> dBounds, double thickness, - std::shared_ptr<const Acts::SurfaceMaterial> material, + std::shared_ptr<const Acts::ISurfaceMaterial> material, std::shared_ptr<const Acts::DigitizationModule> digitizationModule) : Acts::IdentifiedDetectorElement() , m_elementIdentifier(std::move(identifier)) @@ -53,5 +53,5 @@ FW::Generic::GenericDetectorElement::GenericDetectorElement( { auto mutableSurface = std::const_pointer_cast<Acts::Surface>(m_elementSurface); - mutableSurface->setAssociatedMaterial(material); + mutableSurface->assignSurfaceMaterial(material); } diff --git a/Detectors/GeometryInterfaces/include/ACTFW/GeometryInterfaces/ITrackingGeometryService.hpp b/Detectors/GeometryInterfaces/include/ACTFW/GeometryInterfaces/ITrackingGeometryService.hpp index ab6735c66a4e892a18135628209f9cf47a1ce9a3..73e4223a93e60ac5433dd74dbb132119f265b414 100644 --- a/Detectors/GeometryInterfaces/include/ACTFW/GeometryInterfaces/ITrackingGeometryService.hpp +++ b/Detectors/GeometryInterfaces/include/ACTFW/GeometryInterfaces/ITrackingGeometryService.hpp @@ -10,7 +10,7 @@ // ITrackingGeometryService.hpp /////////////////////////////////////////////////////////////////// -#pragma +#pragma once #include <memory> #include "ACTFW/Framework/IService.hpp" diff --git a/Detectors/TGeoDetector/include/ACTFW/TGeoDetector/TGeoDetector.hpp b/Detectors/TGeoDetector/include/ACTFW/TGeoDetector/TGeoDetector.hpp index ac2e8394d296d9d382eb3e5005488c8b07fc6d0b..00a5102e8c7c60646bef1f2a785ab361d7594d75 100644 --- a/Detectors/TGeoDetector/include/ACTFW/TGeoDetector/TGeoDetector.hpp +++ b/Detectors/TGeoDetector/include/ACTFW/TGeoDetector/TGeoDetector.hpp @@ -42,12 +42,15 @@ struct TGeoGeometry /// optionally the geometry context decorator(s) /// /// @tparam variable_map_t Type of the variable map template for parameters + /// @tparam material_decorator_t Type of the material decorator + /// /// @param vm the parameter map object + /// @param mdecorator the actual material decorator /// /// @return a TrackingGeometry object, and optional context decorator(s) - template <typename variable_map_t> + template <typename variable_map_t, typename material_decorator_t> std::pair<TrackingGeometryPtr, ContextDecorators> - operator()(variable_map_t& vm) + operator()(variable_map_t& vm, material_decorator_t /*mdecorator*/) { Acts::GeometryContext tGeoContext; TrackingGeometryPtr tgeoTrackingGeometry diff --git a/Examples/BField/src/BFieldAccessExample.cpp b/Examples/BField/src/BFieldAccessExample.cpp index aa9f1c42a62944a63e6b261a50b8c349b3c3ccc1..0fef5a1ec6d861688d5aff80734077c36c0ec66c 100644 --- a/Examples/BField/src/BFieldAccessExample.cpp +++ b/Examples/BField/src/BFieldAccessExample.cpp @@ -124,7 +124,7 @@ accessRandom(field_t& bField, << " mismatches" << std::endl; } -/// @brief Main executable +/// @brief main executable /// /// @param argc The argument count /// @param argv The argument list diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index 91179efea14f1e50a372e0163dcf9e088673b59f..8a2265ba7e287da791a7aead9a4b4a3c9c5923f4 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -6,7 +6,7 @@ add_subdirectory(EventGenerator) add_subdirectory_if(Fatras USE_PYTHIA8) add_subdirectory(Geometry) add_subdirectory(HelloWorld) -#add_subdirectory_if(MaterialMapping USE_DD4HEP AND USE_GEANT4) +add_subdirectory(MaterialMapping) add_subdirectory(Propagation) add_subdirectory(RandomNumbers) add_subdirectory(WhiteBoard) diff --git a/Examples/Common/ACTFW/Geometry/CommonGeometry.hpp b/Examples/Common/ACTFW/Geometry/CommonGeometry.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ad88a025a891cc4acb6f868c42793e61eaf60e49 --- /dev/null +++ b/Examples/Common/ACTFW/Geometry/CommonGeometry.hpp @@ -0,0 +1,66 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include <string> + +#include <Acts/Material/IMaterialDecorator.hpp> +#include <Acts/Utilities/Logger.hpp> +#include "ACTFW/Geometry/MaterialWiper.hpp" +#include "ACTFW/Plugins/Json/JsonGeometryConverter.hpp" +#include "ACTFW/Plugins/Json/JsonMaterialDecorator.hpp" +#include "ACTFW/Plugins/Root/RootMaterialDecorator.hpp" + +namespace FW { +namespace Geometry { + + /// @brief helper method to setup the geometry + /// + /// @tparam options_map_t Type of the options to be read + /// @tparam geometry_setupt_t Type of the callable geometry setup + /// + /// @param vm the parsed options map + /// @param geometrySetup the callable geometry setup + /// + /// @return a pair of TrackingGeometry and context decorators + template <typename options_map_t, typename geometry_setup_t> + auto + build(const options_map_t& vm, geometry_setup_t& geometrySetup) + { + + // Material decoration + std::shared_ptr<const Acts::IMaterialDecorator> matDeco = nullptr; + auto matType = vm["mat-input-type"].template as<std::string>(); + if (matType == "none") { + matDeco = std::make_shared<const Acts::MaterialWiper>(); + } else if (matType == "file") { + // Retrieve the filename + auto fileName = vm["mat-input-file"].template as<std::string>(); + // json or root based decorator + if (fileName.find(".json") != std::string::npos) { + // Set up the converter first + FW::Json::JsonGeometryConverter::Config jsonGeoConvConfig; + // Set up the json-based decorator + matDeco = std::make_shared<const FW::Json::JsonMaterialDecorator>( + jsonGeoConvConfig, fileName); + } else if (fileName.find(".root") != std::string::npos) { + // Set up the root-based decorator + FW::Root::RootMaterialDecorator::Config rootMatDecConfig; + rootMatDecConfig.fileName = fileName; + matDeco = std::make_shared<const FW::Root::RootMaterialDecorator>( + rootMatDecConfig); + } + } + + /// Return the geometry and context decorators + return geometrySetup(vm, matDeco); + } + +} // namespace +} // namespace diff --git a/Examples/Common/ACTFW/Geometry/MaterialWiper.hpp b/Examples/Common/ACTFW/Geometry/MaterialWiper.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8d8a7269536ce17ba334b3defc302970b79336af --- /dev/null +++ b/Examples/Common/ACTFW/Geometry/MaterialWiper.hpp @@ -0,0 +1,48 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/////////////////////////////////////////////////////////////////// +// MaterialWiper.hpp, Acts project +/////////////////////////////////////////////////////////////////// + +#pragma once + +#include "Acts/Detector/TrackingVolume.hpp" +#include "Acts/Material/IMaterialDecorator.hpp" +#include "Acts/Surfaces/Surface.hpp" + +// @note This file will go into the acts-core +namespace Acts { + +/// @class MaterialWiper +/// +/// This decorator sets the nulls-material +/// +class MaterialWiper : public IMaterialDecorator +{ +public: + /// Decorate a surface + /// + /// @param surface the non-cost surface that is decorated + void + decorate(Surface& surface) const final + { + surface.assignSurfaceMaterial(nullptr); + } + + /// Decorate a TrackingVolume + /// + /// @param volume the non-cost volume that is decorated + virtual void + decorate(TrackingVolume& volume) const final + { + volume.assignVolumeMaterial(nullptr); + } +}; + +} // namespace \ No newline at end of file diff --git a/Examples/Common/ACTFW/Options/CommonOptions.cpp b/Examples/Common/ACTFW/Options/CommonOptions.cpp index 8ad2632beab5ef6f11742fb3affec71b0d9cd3fc..a7aaed2ad74aa84660b2e158d4dca8a197899c76 100644 --- a/Examples/Common/ACTFW/Options/CommonOptions.cpp +++ b/Examples/Common/ACTFW/Options/CommonOptions.cpp @@ -62,6 +62,40 @@ FW::Options::addGeometryOptions( "Sub detectors for the output writing"); } +void +FW::Options::addMaterialOptions( + boost::program_options::options_description& opt) +{ + opt.add_options()( + "mat-input-type", + value<std::string>()->default_value("build"), + "The way material is loaded: 'none', 'build', 'proto', 'file'.")( + "mat-input-file", + value<std::string>()->default_value(""), + "Name of the material map input file, supported: '.json' or '.root'.")( + "mat-output-file", + value<std::string>()->default_value(""), + "Name of the material map output file (without extension).")( + "mat-output-sensitives", + value<bool>()->default_value(true), + "Write material information of sensitive surfaces.")( + "mat-output-approaches", + value<bool>()->default_value(true), + "Write material information of approach surfaces.")( + "mat-output-representing", + value<bool>()->default_value(true), + "Write material information of representing surfaces.")( + "mat-output-boundaries", + value<bool>()->default_value(true), + "Write material information of boundary surfaces.")( + "mat-output-volumes", + value<bool>()->default_value(true), + "Write material information of dense volumes.")( + "mat-output-data", + value<bool>()->default_value(true), + "Output the data field(s)."); +} + void FW::Options::addOutputOptions(boost::program_options::options_description& opt) { @@ -83,6 +117,28 @@ FW::Options::addOutputOptions(boost::program_options::options_description& opt) "Switch on to write '.json' ouput file(s)."); } +void +FW::Options::addInputOptions(boost::program_options::options_description& opt) +{ + // Add specific options for this example + opt.add_options()("input-dir", + value<std::string>()->default_value(""), + "Input directory location.")( + "input-files", + value<read_strings>()->multitoken()->default_value({}), + "Input files, space separated.")("input-root", + value<bool>()->default_value(false), + "Switch on to read '.root' file(s).")( + "input-csv", + value<bool>()->default_value(false), + "Switch on to read '.csv' file(s).")("input-obj", + value<bool>()->default_value(false), + "Switch on to read '.obj' file(s).")( + "input-json", + value<bool>()->default_value(false), + "Switch on to read '.json' file(s)."); +} + boost::program_options::variables_map FW::Options::parse(const boost::program_options::options_description& opt, int argc, diff --git a/Examples/Common/ACTFW/Options/CommonOptions.hpp b/Examples/Common/ACTFW/Options/CommonOptions.hpp index 4f5f2a3178b72903cf49555be166afafad07f660..1cdff661f2356358603f7db1d6d1b5d0356a5ec8 100644 --- a/Examples/Common/ACTFW/Options/CommonOptions.hpp +++ b/Examples/Common/ACTFW/Options/CommonOptions.hpp @@ -12,7 +12,6 @@ #include <Acts/Utilities/Logger.hpp> #include <boost/program_options.hpp> - #include "ACTFW/Framework/Sequencer.hpp" namespace FW { @@ -32,6 +31,14 @@ namespace Options { void addGeometryOptions(boost::program_options::options_description& opt); + /// Add common material-related options. + void + addMaterialOptions(boost::program_options::options_description& opt); + + /// Add common input-related options. + void + addInputOptions(boost::program_options::options_description& opt); + /// Add common output-related options. void addOutputOptions(boost::program_options::options_description& opt); diff --git a/Examples/Common/CMakeLists.txt b/Examples/Common/CMakeLists.txt index ea361ef06e6d5665547044e9288c1b11a47746f7..2f5b8d33794bcdfa78d295817120674c11bafacb 100644 --- a/Examples/Common/CMakeLists.txt +++ b/Examples/Common/CMakeLists.txt @@ -1,3 +1,4 @@ add_library(ACTFWExamplesCommon STATIC ACTFW/Options/CommonOptions.cpp) target_include_directories(ACTFWExamplesCommon PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>) target_link_libraries(ACTFWExamplesCommon PUBLIC ActsCore ACTFramework) +target_link_libraries(ACTFWExamplesCommon PUBLIC ACTFWObjPlugin ACTFWCsvPlugin ACTFWJsonPlugin ACTFWRootPlugin) diff --git a/Examples/Fatras/src/detail/FatrasExampleBase.hpp b/Examples/Fatras/src/detail/FatrasExampleBase.hpp index f5a69424474f44cfdb2f5140fdf4a86495afaf02..e0e0114987bf64622f8ccdc7bc09673e21e7c121 100644 --- a/Examples/Fatras/src/detail/FatrasExampleBase.hpp +++ b/Examples/Fatras/src/detail/FatrasExampleBase.hpp @@ -17,6 +17,7 @@ #include "ACTFW/Fatras/FatrasOptions.hpp" #include "ACTFW/Framework/Sequencer.hpp" #include "ACTFW/Framework/WhiteBoard.hpp" +#include "ACTFW/Geometry/CommonGeometry.hpp" #include "ACTFW/Options/CommonOptions.hpp" #include "ACTFW/Options/ParticleGunOptions.hpp" #include "ACTFW/Plugins/BField/BFieldOptions.hpp" @@ -52,6 +53,7 @@ fatrasExample(int argc, auto desc = FW::Options::makeDefaultOptions(); FW::Options::addSequencerOptions(desc); FW::Options::addGeometryOptions(desc); + FW::Options::addMaterialOptions(desc); FW::Options::addParticleGunOptions(desc); FW::Options::addPythia8Options(desc); FW::Options::addRandomNumbersOptions(desc); @@ -87,12 +89,11 @@ fatrasExample(int argc, // Add it to the sequencer sequencer.addService(barcodeSvc); - // Create the geometry and the context decorators - auto geometry = geometrySetup(vm); + // The geometry, material and decoration + auto geometry = FW::Geometry::build(vm, geometrySetup); auto tGeometry = geometry.first; auto contextDecorators = geometry.second; - - // Add it to the sequencer + // Add the decorator to the sequencer for (auto cdr : contextDecorators) { sequencer.addContextDecorator(cdr); } diff --git a/Examples/Fatras/src/detail/FatrasSimulationBase.hpp b/Examples/Fatras/src/detail/FatrasSimulationBase.hpp index 73d2036f10bbf657c0c7c6db82e87e54c4b6cc90..90c65405d0bccacfa29c798111c36aad9375f7fd 100644 --- a/Examples/Fatras/src/detail/FatrasSimulationBase.hpp +++ b/Examples/Fatras/src/detail/FatrasSimulationBase.hpp @@ -72,7 +72,7 @@ struct SurfaceSelector if (selectSensitive && surface.associatedDetectorElement()) { return true; } - if (selectMaterial && surface.associatedMaterial()) { + if (selectMaterial && surface.surfaceMaterial()) { return true; } if (selectPassive) { diff --git a/Examples/Geometry/CMakeLists.txt b/Examples/Geometry/CMakeLists.txt index a52f44ddee5ec1e3f6050f7c5d59f9fe085c22c6..247d09c2a7b8e6753d6bfa7a4a3c4499c476db8b 100644 --- a/Examples/Geometry/CMakeLists.txt +++ b/Examples/Geometry/CMakeLists.txt @@ -1,55 +1,70 @@ -# generic detector -add_executable(ACTFWGenericGeometryExample src/GenericGeometryExample) -target_include_directories(ACTFWGenericGeometryExample PRIVATE ${Boost_INCLUDE_DIRS}) -target_link_libraries(ACTFWGenericGeometryExample PRIVATE ActsCore) -target_link_libraries(ACTFWGenericGeometryExample PRIVATE ACTFramework ACTFWExamplesCommon) -target_link_libraries(ACTFWGenericGeometryExample PRIVATE ACTFWObjPlugin ACTFWCsvPlugin ACTFWGenericDetector) -target_link_libraries(ACTFWGenericGeometryExample PRIVATE ${Boost_LIBRARIES}) +set(_common_libraries + ActsCore + ACTFramework + ACTFWExamplesCommon + ACTFWObjPlugin + ACTFWCsvPlugin + ACTFWJsonPlugin + ACTFWRootPlugin + ${Boost_LIBRARIES}) -install(TARGETS ACTFWGenericGeometryExample RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +# Generic detector +add_executable(ACTFWGenericGeometryExample src/GenericGeometryExample.cpp) +target_include_directories(ACTFWGenericGeometryExample PRIVATE + ${Boost_INCLUDE_DIRS}) +target_link_libraries(ACTFWGenericGeometryExample PRIVATE + ${_common_libraries} + ACTFWGenericDetector) +install( + TARGETS ACTFWGenericGeometryExample + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -# alignable detector - with iov -add_executable(ACTFWAlignedGeometryExample src/AlignedGeometryExample) -target_include_directories(ACTFWAlignedGeometryExample PRIVATE ${Boost_INCLUDE_DIRS}) -target_link_libraries(ACTFWAlignedGeometryExample PRIVATE ActsCore) -target_link_libraries(ACTFWAlignedGeometryExample PRIVATE ACTFramework ACTFWExamplesCommon) -target_link_libraries(ACTFWAlignedGeometryExample PRIVATE ACTFWObjPlugin ACTFWCsvPlugin ACTFWGenericDetector ACTFWContextualDetector) -target_link_libraries(ACTFWAlignedGeometryExample PRIVATE ${Boost_LIBRARIES}) +# Generic detector with IOV based alignment +add_executable(ACTFWAlignedGeometryExample src/AlignedGeometryExample.cpp) +target_include_directories(ACTFWAlignedGeometryExample PRIVATE + ${Boost_INCLUDE_DIRS}) +target_link_libraries(ACTFWAlignedGeometryExample PRIVATE + ${_common_libraries} + ACTFWContextualDetector) +install( + TARGETS ACTFWAlignedGeometryExample + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -install(TARGETS ACTFWAlignedGeometryExample RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - -# alignable detector - with payload -add_executable(ACTFWPayloadGeometryExample src/PayloadGeometryExample) -target_include_directories(ACTFWPayloadGeometryExample PRIVATE ${Boost_INCLUDE_DIRS}) -target_link_libraries(ACTFWPayloadGeometryExample PRIVATE ActsCore) -target_link_libraries(ACTFWPayloadGeometryExample PRIVATE ACTFramework ACTFWExamplesCommon) -target_link_libraries(ACTFWPayloadGeometryExample PRIVATE ACTFWObjPlugin ACTFWCsvPlugin ACTFWGenericDetector ACTFWContextualDetector) -target_link_libraries(ACTFWPayloadGeometryExample PRIVATE ${Boost_LIBRARIES}) - -install(TARGETS ACTFWPayloadGeometryExample RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +# Generic detector with Payload based alignment +add_executable(ACTFWPayloadGeometryExample src/PayloadGeometryExample.cpp) +target_include_directories(ACTFWPayloadGeometryExample PRIVATE + ${Boost_INCLUDE_DIRS}) +target_link_libraries(ACTFWPayloadGeometryExample PRIVATE + ${_common_libraries} + ACTFWContextualDetector) +install( + TARGETS ACTFWPayloadGeometryExample + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) # TGEO based detector if (USE_TGEO) - add_executable(ACTFWTGeoGeometryExample src/TGeoGeometryExample) - target_include_directories(ACTFWTGeoGeometryExample PUBLIC ${Boost_INCLUDE_DIRS}) - target_link_libraries(ACTFWTGeoGeometryExample PRIVATE ActsCore) - target_link_libraries(ACTFWTGeoGeometryExample PRIVATE ACTFramework ACTFWExamplesCommon) - target_link_libraries(ACTFWTGeoGeometryExample PRIVATE ACTFWObjPlugin ACTFWCsvPlugin ACTFWTGeoDetector) - target_link_libraries(ACTFWTGeoGeometryExample PRIVATE ${Boost_LIBRARIES}) - - install(TARGETS ACTFWTGeoGeometryExample RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + add_executable(ACTFWTGeoGeometryExample src/TGeoGeometryExample.cpp) + target_include_directories(ACTFWTGeoGeometryExample PRIVATE + ${Boost_INCLUDE_DIRS}) + target_link_libraries(ACTFWTGeoGeometryExample PRIVATE + ${_common_libraries} + ACTFWTGeoDetector) + install( + TARGETS ACTFWTGeoGeometryExample + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() # DD4hep detector if (USE_DD4HEP) add_executable(ACTFWDD4hepGeometryExample src/DD4hepGeometryExample.cpp) - target_include_directories(ACTFWDD4hepGeometryExample PRIVATE ${DD4hep_INCLUDE_DIRS}) - target_include_directories(ACTFWDD4hepGeometryExample PRIVATE ${Boost_INCLUDE_DIRS}) - target_link_libraries(ACTFWDD4hepGeometryExample PRIVATE ActsCore) - target_link_libraries(ACTFWDD4hepGeometryExample PRIVATE ACTFramework ACTFWExamplesCommon) - target_link_libraries(ACTFWDD4hepGeometryExample PRIVATE ACTFWCsvPlugin ACTFWObjPlugin ACTFWDD4hepDetector) - target_link_libraries(ACTFWDD4hepGeometryExample PRIVATE ${DD4hep_LIBRARIES}) - target_link_libraries(ACTFWDD4hepGeometryExample PRIVATE ${Boost_LIBRARIES}) - - install(TARGETS ACTFWDD4hepGeometryExample RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + target_include_directories(ACTFWDD4hepGeometryExample PRIVATE + ${Boost_INCLUDE_DIRS} + ${DD4hep_INCLUDE_DIRS}) + target_link_libraries(ACTFWDD4hepGeometryExample PRIVATE + ${_common_libraries} + ACTFWDD4hepDetector + ${DD4hep_LIBRARIES}) + install( + TARGETS ACTFWDD4hepGeometryExample + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() diff --git a/Examples/Geometry/src/detail/GeometryExampleBase.hpp b/Examples/Geometry/src/detail/GeometryExampleBase.hpp index cdf59c74b79c3854c655ff6d1471d5cb5952e5e5..bcef73b04ea414cf1aa5351d970ff7864a27417b 100644 --- a/Examples/Geometry/src/detail/GeometryExampleBase.hpp +++ b/Examples/Geometry/src/detail/GeometryExampleBase.hpp @@ -15,18 +15,28 @@ #include "ACTFW/Framework/AlgorithmContext.hpp" #include "ACTFW/Framework/IContextDecorator.hpp" #include "ACTFW/Framework/WhiteBoard.hpp" +#include "ACTFW/Geometry/CommonGeometry.hpp" #include "ACTFW/Options/CommonOptions.hpp" #include "ACTFW/Plugins/Csv/CsvSurfaceWriter.hpp" #include "ACTFW/Plugins/Csv/CsvTrackingGeometryWriter.hpp" #include "ACTFW/Plugins/Csv/CsvWriterOptions.hpp" +#include "ACTFW/Plugins/Json/JsonMaterialWriter.hpp" #include "ACTFW/Plugins/Obj/ObjSurfaceWriter.hpp" #include "ACTFW/Plugins/Obj/ObjTrackingGeometryWriter.hpp" #include "ACTFW/Plugins/Obj/ObjWriterOptions.hpp" +#include "ACTFW/Plugins/Root/RootMaterialWriter.hpp" #include "ACTFW/Utilities/Options.hpp" #include "ACTFW/Utilities/Paths.hpp" #include "Acts/Detector/TrackingGeometry.hpp" #include "Acts/Utilities/GeometryContext.hpp" +/// @brief templated method to process a geometry +/// +/// @tparam options_setup_t callable options setup +/// @tparam geometry_setup_t callable geonmetry setup +/// +/// + template <typename options_setup_t, typename geometry_setup_t> int processGeometry(int argc, @@ -38,6 +48,7 @@ processGeometry(int argc, auto desc = FW::Options::makeDefaultOptions(); FW::Options::addSequencerOptions(desc); FW::Options::addGeometryOptions(desc); + FW::Options::addMaterialOptions(desc); FW::Options::addObjWriterOptions(desc); FW::Options::addOutputOptions(desc); // Add specific options for this geometry @@ -49,10 +60,10 @@ processGeometry(int argc, // Now read the standard options auto logLevel = FW::Options::readLogLevel(vm); - // TODO Check whether this truly needs to be event-based. If yes switch to - // Sequencer-based tool, otherwise remove. - auto nEvents = FW::Options::readSequencerConfig(vm).events; - auto geometry = geometrySetup(vm); + auto nEvents = FW::Options::readSequencerConfig(vm).events; + + // The geometry, material and decoration + auto geometry = FW::Geometry::build(vm, geometrySetup); auto tGeometry = geometry.first; auto contextDecorators = geometry.second; @@ -60,11 +71,11 @@ processGeometry(int argc, read_strings subDetectors = vm["geo-subdetectors"].as<read_strings>(); auto surfaceLogLevel - = Acts::Logging::Level(vm["geo-surface-loglevel"].template as<size_t>()); + = Acts::Logging::Level(vm["geo-surface-loglevel"].as<size_t>()); auto layerLogLevel - = Acts::Logging::Level(vm["geo-layer-loglevel"].template as<size_t>()); + = Acts::Logging::Level(vm["geo-layer-loglevel"].as<size_t>()); auto volumeLogLevel - = Acts::Logging::Level(vm["geo-volume-loglevel"].template as<size_t>()); + = Acts::Logging::Level(vm["geo-volume-loglevel"].as<size_t>()); for (size_t ievt = 0; ievt < nEvents; ++ievt) { @@ -168,6 +179,43 @@ processGeometry(int argc, // Close the file csvStream->close(); } + + // Get the file name from the options + std::string materialFileName = vm["mat-output-file"].as<std::string>(); + + if (!materialFileName.empty() and vm["output-root"].template as<bool>()) { + + // The writer of the indexed material + FW::Root::RootMaterialWriter::Config rmwConfig("MaterialWriter"); + rmwConfig.fileName = materialFileName + ".root"; + FW::Root::RootMaterialWriter rmwImpl(rmwConfig); + rmwImpl.write(*tGeometry); + } + + if (!materialFileName.empty() and vm["output-json"].template as<bool>()) { + /// The name of the output file + std::string fileName = vm["mat-output-file"].template as<std::string>(); + // the material writer + FW::Json::JsonGeometryConverter::Config jmConverterCfg( + "JsonGeometryConverter", Acts::Logging::INFO); + jmConverterCfg.processSensitives + = vm["mat-output-sensitives"].template as<bool>(); + jmConverterCfg.processApproaches + = vm["mat-output-approaches"].template as<bool>(); + jmConverterCfg.processRepresenting + = vm["mat-output-representing"].template as<bool>(); + jmConverterCfg.processBoundaries + = vm["mat-output-boundaries"].template as<bool>(); + jmConverterCfg.processVolumes + = vm["mat-output-volumes"].template as<bool>(); + jmConverterCfg.writeData = vm["mat-output-data"].template as<bool>(); + + // The writer + FW::Json::JsonMaterialWriter jmwImpl(std::move(jmConverterCfg), + materialFileName + ".json"); + + jmwImpl.write(*tGeometry); + } } return 0; diff --git a/Examples/MaterialMapping/CMakeLists.txt b/Examples/MaterialMapping/CMakeLists.txt index 848cc2d1ef1f31c26e7962c3baf8fe94e7f38605..44520405bb867f91cc85ddcaf0794e14c4cae2cc 100644 --- a/Examples/MaterialMapping/CMakeLists.txt +++ b/Examples/MaterialMapping/CMakeLists.txt @@ -1,18 +1,45 @@ -include(${Geant4_USE_FILE}) +set(_common_libraries + ActsCore + ACTFramework + ACTFWExamplesCommon + ${Boost_LIBRARIES}) -file (GLOB_RECURSE src_files "src/*.cpp") +set(_plugin_libraries + ACTFWRootPlugin + ACTFWJsonPlugin + ACTFWBFieldPlugin) -add_executable(ACTFWGeantinoRecordingExample src/GeantinoRecordingExample.cpp) -add_executable(ACTFWMaterialMappingExample src/MaterialMappingExample.cpp) +add_executable(ACTFWGenericMaterialValidationExample src/GenericMaterialValidation.cpp) +target_include_directories(ACTFWGenericMaterialValidationExample PRIVATE + ${Boost_INCLUDE_DIRS}) +target_link_libraries(ACTFWGenericMaterialValidationExample PRIVATE + ${_common_libraries} ${_plugin_libraries}) +target_link_libraries(ACTFWGenericMaterialValidationExample PRIVATE + ACTFWPropagation ACTFWGenericDetector) +install(TARGETS ACTFWGenericMaterialValidationExample RUNTIME DESTINATION + ${CMAKE_INSTALL_BINDIR}) -foreach(_example ACTFWGeantinoRecordingExample ACTFWMaterialMappingExample) - target_include_directories(${_example} PRIVATE ${DD4hep_INCLUDE_DIRS}) - target_link_libraries(${_example} PRIVATE ACTFWDD4hepG4Plugin) - target_link_libraries(${_example} PRIVATE ACTFWExtrapolation) - target_link_libraries(${_example} PRIVATE ACTFWMaterialMapping) - target_link_libraries(${_example} PRIVATE ACTFWRootPlugin) - target_link_libraries(${_example} PRIVATE ${DD4hep_LIBRARIES}) - target_link_libraries(${_example} PRIVATE ${Geant4_LIBRARIES}) - target_link_libraries(${_example} PRIVATE ${Boost_LIBRARIES}) - install(TARGETS ${_example} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -endforeach() +add_executable(ACTFWGenericMaterialMappingExample src/GenericMaterialMapping.cpp) +target_include_directories(ACTFWGenericMaterialMappingExample PRIVATE + ${Boost_INCLUDE_DIRS}) +target_link_libraries(ACTFWGenericMaterialMappingExample PRIVATE + ${_common_libraries} ${_plugin_libraries}) +target_link_libraries(ACTFWGenericMaterialMappingExample PRIVATE + ACTFWMaterialMapping ACTFWGenericDetector) +install(TARGETS ACTFWGenericMaterialMappingExample RUNTIME DESTINATION + ${CMAKE_INSTALL_BINDIR}) + + +if (USE_GEANT4 AND USE_DD4HEP) + include(${Geant4_USE_FILE}) + + add_executable(ACTFWGeantinoRecordingExample src/GeantinoRecordingExample.cpp) + target_include_directories(ACTFWGeantinoRecordingExample PRIVATE + ${Boost_INCLUDE_DIRS} ${DD4hep_INCLUDE_DIRS}) + target_link_libraries(ACTFWGeantinoRecordingExample PRIVATE + ACTFWExamplesCommon ACTFWMaterialMapping ACTFWDD4hepG4Plugin ACTFWRootPlugin) + target_link_libraries(ACTFWGeantinoRecordingExample PRIVATE + ACTFWDD4hepDetector ${DD4hep_LIBRARIES} ${Geant4_LIBRARIES} ${Boost_LIBRARIES}) + + install(TARGETS ACTFWGeantinoRecordingExample RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif() diff --git a/Examples/MaterialMapping/src/GeantinoRecordingExample.cpp b/Examples/MaterialMapping/src/GeantinoRecordingExample.cpp index c7d5a618b24e3d7049304a00fb9991dd6338beeb..ea33e52eab258414f8ed53bebcfd63fa1349736f 100644 --- a/Examples/MaterialMapping/src/GeantinoRecordingExample.cpp +++ b/Examples/MaterialMapping/src/GeantinoRecordingExample.cpp @@ -1,22 +1,23 @@ // This file is part of the Acts project. // -// Copyright (C) 2017 Acts project team +// Copyright (C) 2017-2018 Acts project team // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include <boost/program_options.hpp> -#include "ACTFW/Common/CommonOptions.hpp" +#include "ACTFW/DD4hepDetector/DD4hepDetectorOptions.hpp" +#include "ACTFW/DD4hepDetector/DD4hepGeometryService.hpp" #include "ACTFW/Framework/Sequencer.hpp" #include "ACTFW/MaterialMapping/GeantinoRecording.hpp" -#include "ACTFW/Plugins/DD4hep/DD4hepDetectorOptions.hpp" -#include "ACTFW/Plugins/DD4hep/GeometryService.hpp" +#include "ACTFW/Options/CommonOptions.hpp" #include "ACTFW/Plugins/DD4hepG4/DD4hepToG4Svc.hpp" #include "ACTFW/Plugins/Root/RootMaterialTrackWriter.hpp" #include "ACTFW/Random/RandomNumbersSvc.hpp" -#include "ACTFW/Writers/IWriterT.hpp" +#include "ACTFW/Utilities/Paths.hpp" #include "Acts/Detector/TrackingGeometry.hpp" +#include "Acts/Utilities/GeometryContext.hpp" namespace po = boost::program_options; @@ -24,39 +25,36 @@ int main(int argc, char* argv[]) { // Declare the supported program options. - po::options_description desc("Allowed options"); - // add the standard options - FW::Options::addStandardOptions<po::options_description>(desc, 100, 2); - // add the detector options - FW::Options::addDD4hepOptions<po::options_description>(desc); - po::variables_map vm; - // Get all options from contain line and store it into the map - po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); - // print help if requested - if (vm.count("help")) { - std::cout << desc << std::endl; - return 1; + // Setup and parse options + auto desc = FW::Options::makeDefaultOptions(); + FW::Options::addSequencerOptions(desc); + FW::Options::addOutputOptions(desc); + FW::Options::addDD4hepOptions(desc); + + // Parse the options + auto vm = FW::Options::parse(desc, argc, argv); + if (vm.empty()) { + return EXIT_FAILURE; } - // now read the standard options - auto standardOptions - = FW::Options::readStandardOptions<po::variables_map>(vm); - // @todo update - make program options in separate MR - auto nEvents = standardOptions.first; + + FW::Sequencer g4sequencer(FW::Options::readSequencerConfig(vm)); + size_t nTracks = 100; int randomSeed1 = 536235167; int randomSeed2 = 729237523; + Acts::GeometryContext geoContext; + // DETECTOR: // -------------------------------------------------------------------------------- // DD4Hep detector definition // read the detector config & dd4hep detector auto dd4HepDetectorConfig = FW::Options::readDD4hepConfig<po::variables_map>(vm); - auto geometrySvc - = std::make_shared<FW::DD4hep::GeometryService>(dd4HepDetectorConfig); + auto geometrySvc = std::make_shared<FW::DD4hep::DD4hepGeometryService>( + dd4HepDetectorConfig); std::shared_ptr<const Acts::TrackingGeometry> tGeometry - = geometrySvc->trackingGeometry(); + = geometrySvc->trackingGeometry(geoContext); // DD4Hep to Geant4 conversion // @@ -69,32 +67,36 @@ main(int argc, char* argv[]) // Geant4 JOB: // -------------------------------------------------------------------------------- // set up the writer for - FW::Root::RootMaterialTrackWriter::Config g4WriterConfig( - "MaterialTrackWriter", Acts::Logging::INFO); - g4WriterConfig.fileName = "GeantMaterialTracks.root"; - g4WriterConfig.treeName = "GeantMaterialTracks"; - auto g4TrackRecWriter - = std::make_shared<FW::Root::RootMaterialTrackWriter>(g4WriterConfig); + + // --------------------------------------------------------------------------------- // set up the algorithm writing out the material map FW::GeantinoRecording::Config g4rConfig; - g4rConfig.materialTrackWriter = g4TrackRecWriter; - g4rConfig.geant4Service = dd4hepToG4Svc; - g4rConfig.tracksPerEvent = nTracks; - g4rConfig.seed1 = randomSeed1; - g4rConfig.seed2 = randomSeed2; + g4rConfig.geant4Service = dd4hepToG4Svc; + g4rConfig.tracksPerEvent = nTracks; + g4rConfig.seed1 = randomSeed1; + g4rConfig.seed2 = randomSeed2; // create the geant4 algorithm auto g4rAlgorithm = std::make_shared<FW::GeantinoRecording>(g4rConfig, Acts::Logging::INFO); - // Geant4 job - these can be many Geant4 jobs, indeed - // - // create the config object for the sequencer - FW::Sequencer::Config g4SeqConfig; - // now create the sequencer - FW::Sequencer g4Sequencer(g4SeqConfig); - // the writer is a service as it needs initialize, finalize - g4Sequencer.addService(g4TrackRecWriter); - g4Sequencer.addAlgorithm(g4rAlgorithm); - return g4Sequencer.run(nEvents); + // Output directory + std::string outputDir = vm["output-dir"].template as<std::string>(); + std::string matCollection = g4rConfig.geantMaterialCollection; + + if (vm["output-root"].template as<bool>()) { + // Write the propagation steps as ROOT TTree + FW::Root::RootMaterialTrackWriter::Config matTrackWriterRootConfig; + matTrackWriterRootConfig.collection = matCollection; + matTrackWriterRootConfig.filePath + = FW::joinPaths(outputDir, matCollection + ".root"); + auto matTrackWriterRoot + = std::make_shared<FW::Root::RootMaterialTrackWriter>( + matTrackWriterRootConfig); + g4sequencer.addWriter(matTrackWriterRoot); + } + + // Append the algorithm and run + g4sequencer.addAlgorithm(g4rAlgorithm); + g4sequencer.run(); } diff --git a/Examples/MaterialMapping/src/GenericMaterialMapping.cpp b/Examples/MaterialMapping/src/GenericMaterialMapping.cpp new file mode 100644 index 0000000000000000000000000000000000000000..815e645a76435e5f7096bf679c9620bd6b21ae7c --- /dev/null +++ b/Examples/MaterialMapping/src/GenericMaterialMapping.cpp @@ -0,0 +1,24 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2018-2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "ACTFW/GenericDetector/GenericDetector.hpp" +#include "detail/MaterialMappingBase.hpp" + +/// @brief main executable +/// +/// @param argc The argument count +/// @param argv The argument list +int +main(int argc, char* argv[]) +{ + // -------------------------------------------------------------------------------- + GenericOptions genericOptions; + GenericGeometry genericGeometry; + // now process it + return materialMappingExample(argc, argv, genericOptions, genericGeometry); +} \ No newline at end of file diff --git a/Examples/MaterialMapping/src/GenericMaterialValidation.cpp b/Examples/MaterialMapping/src/GenericMaterialValidation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0cb0678da0f94a1b19971d18fe04995ebbd4935 --- /dev/null +++ b/Examples/MaterialMapping/src/GenericMaterialValidation.cpp @@ -0,0 +1,24 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2018 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "ACTFW/GenericDetector/GenericDetector.hpp" +#include "detail/MaterialValidationBase.hpp" + +/// @brief main executable +/// +/// @param argc The argument count +/// @param argv The argument list +int +main(int argc, char* argv[]) +{ + // -------------------------------------------------------------------------------- + GenericOptions genericOptions; + GenericGeometry genericGeometry; + // now process it + return materialValidationExample(argc, argv, genericOptions, genericGeometry); +} \ No newline at end of file diff --git a/Examples/MaterialMapping/src/detail/MaterialMappingBase.hpp b/Examples/MaterialMapping/src/detail/MaterialMappingBase.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d2748d909765ea408b262c8179fe1991c39a915c --- /dev/null +++ b/Examples/MaterialMapping/src/detail/MaterialMappingBase.hpp @@ -0,0 +1,176 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2018 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include <boost/program_options.hpp> +#include <memory> +#include "ACTFW/Framework/Sequencer.hpp" +#include "ACTFW/Geometry/CommonGeometry.hpp" +#include "ACTFW/MaterialMapping/MaterialMapping.hpp" +#include "ACTFW/MaterialMapping/MaterialMappingOptions.hpp" +#include "ACTFW/Options/CommonOptions.hpp" +#include "ACTFW/Plugins/Json/JsonGeometryConverter.hpp" +#include "ACTFW/Plugins/Json/JsonMaterialWriter.hpp" +#include "ACTFW/Plugins/Root/RootMaterialTrackReader.hpp" +#include "ACTFW/Plugins/Root/RootMaterialWriter.hpp" +#include "ACTFW/Propagation/PropagationOptions.hpp" +#include "ACTFW/Utilities/Paths.hpp" +#include "Acts/Detector/TrackingGeometry.hpp" +#include "Acts/Extrapolator/Navigator.hpp" +#include "Acts/Plugins/MaterialMapping/SurfaceMaterialMapper.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Propagator/StraightLineStepper.hpp" +#include "Acts/Utilities/GeometryContext.hpp" +#include "Acts/Utilities/MagneticFieldContext.hpp" + +namespace po = boost::program_options; + +/// @brief The material validation example, it runs a propagation +/// and then writes out the material information +/// +/// @tparam option_setup_t Type of the option setter +/// @tparam geometry_setup_t Type of the geometry setter +/// +/// @param argc the number of argumetns of the call +/// @param atgv the argument list +/// @param optionsSetup is the access struct to the additional options +/// @param geometrySetup is the access struct for the trackingGeometry +/// +template <typename options_setup_t, typename geometry_setup_t> +int +materialMappingExample(int argc, + char* argv[], + options_setup_t optionsSetup, + geometry_setup_t geometrySetup) +{ + + // Setup and parse options + auto desc = FW::Options::makeDefaultOptions(); + FW::Options::addSequencerOptions(desc); + FW::Options::addGeometryOptions(desc); + FW::Options::addMaterialOptions(desc); + FW::Options::addMaterialMappingOptions(desc); + FW::Options::addPropagationOptions(desc); + FW::Options::addInputOptions(desc); + FW::Options::addOutputOptions(desc); + + // Add specific options for this geometry + optionsSetup(desc); + auto vm = FW::Options::parse(desc, argc, argv); + if (vm.empty()) { + return EXIT_FAILURE; + } + + FW::Sequencer sequencer(FW::Options::readSequencerConfig(vm)); + + // Get the log level + auto logLevel = FW::Options::readLogLevel(vm); + + // The geometry, material and decoration + auto geometry = FW::Geometry::build(vm, geometrySetup); + auto tGeometry = geometry.first; + + /// Default contexts + Acts::GeometryContext geoContext; + Acts::MagneticFieldContext mfContext; + + // Get a Navigator + Acts::Navigator navigator(tGeometry); + + // Straight line stepper + using SlStepper = Acts::StraightLineStepper; + using Propagator = Acts::Propagator<SlStepper, Acts::Navigator>; + // Make stepper and propagator + SlStepper stepper; + Propagator propagator(std::move(stepper), std::move(navigator)); + + auto matCollection = vm["mat-mapping-collection"].template as<std::string>(); + + // --------------------------------------------------------------------------------- + // Input directory & input file handling + std::string intputDir = vm["input-dir"].template as<std::string>(); + auto intputFiles = vm["input-files"].template as<read_strings>(); + + if (vm["input-root"].template as<bool>()) { + // Read the material step information from a ROOT TTree + FW::Root::RootMaterialTrackReader::Config matTrackReaderRootConfig; + if (not matCollection.empty()) { + matTrackReaderRootConfig.collection = matCollection; + } + matTrackReaderRootConfig.fileList = intputFiles; + auto matTrackReaderRoot + = std::make_shared<FW::Root::RootMaterialTrackReader>( + matTrackReaderRootConfig); + sequencer.addReader(matTrackReaderRoot); + } + + /// The material mapper + Acts::SurfaceMaterialMapper::Config smmConfig; + auto smm = std::make_shared<Acts::SurfaceMaterialMapper>( + smmConfig, + std::move(propagator), + Acts::getDefaultLogger("SurfaceMaterialMapper", logLevel)); + + /// The material mapping algorithm + FW::MaterialMapping::Config mmAlgConfig(geoContext, mfContext); + mmAlgConfig.materialMapper = smm; + mmAlgConfig.trackingGeometry = tGeometry; + + // Get the file name from the options + std::string materialFileName = vm["mat-output-file"].as<std::string>(); + + if (!materialFileName.empty() and vm["output-root"].template as<bool>()) { + + // The writer of the indexed material + FW::Root::RootMaterialWriter::Config rmwConfig("MaterialWriter"); + rmwConfig.fileName = materialFileName + ".root"; + FW::Root::RootMaterialWriter rmwImpl(rmwConfig); + // Fullfill the IMaterialWriter interface + using RootWriter = FW::MaterialWriterT<FW::Root::RootMaterialWriter>; + mmAlgConfig.materialWriters.push_back( + std::make_shared<RootWriter>(std::move(rmwImpl))); + } + + if (!materialFileName.empty() and vm["output-json"].template as<bool>()) { + /// The name of the output file + std::string fileName = vm["mat-output-file"].template as<std::string>(); + // the material writer + FW::Json::JsonGeometryConverter::Config jmConverterCfg( + "JsonGeometryConverter", Acts::Logging::INFO); + jmConverterCfg.processSensitives + = vm["mat-output-sensitives"].template as<bool>(); + jmConverterCfg.processApproaches + = vm["mat-output-approaches"].template as<bool>(); + jmConverterCfg.processRepresenting + = vm["mat-output-representing"].template as<bool>(); + jmConverterCfg.processBoundaries + = vm["mat-output-boundaries"].template as<bool>(); + jmConverterCfg.processVolumes + = vm["mat-output-volumes"].template as<bool>(); + jmConverterCfg.writeData = vm["mat-output-data"].template as<bool>(); + // The writer + FW::Json::JsonMaterialWriter jmwImpl(jmConverterCfg, + materialFileName + ".json"); + // Fullfill the IMaterialWriter interface + using JsonWriter = FW::MaterialWriterT<FW::Json::JsonMaterialWriter>; + mmAlgConfig.materialWriters.push_back( + std::make_shared<JsonWriter>(std::move(jmwImpl))); + } + + // Create the material mapping + auto mmAlg = std::make_shared<FW::MaterialMapping>(mmAlgConfig); + + // Append the Algorithm + sequencer.addAlgorithm(mmAlg); + + // Initiate the run + sequencer.run(); + // Return success code + return 0; +} diff --git a/Examples/MaterialMapping/src/detail/MaterialValidationBase.hpp b/Examples/MaterialMapping/src/detail/MaterialValidationBase.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ebc63e28ff3abfd265525c0ec2e1dc9adddc05a9 --- /dev/null +++ b/Examples/MaterialMapping/src/detail/MaterialValidationBase.hpp @@ -0,0 +1,223 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2018 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include <boost/program_options.hpp> +#include <memory> +#include "ACTFW/Framework/Sequencer.hpp" +#include "ACTFW/Geometry/CommonGeometry.hpp" +#include "ACTFW/Options/CommonOptions.hpp" +#include "ACTFW/Plugins/BField/BFieldOptions.hpp" +#include "ACTFW/Plugins/Root/RootMaterialTrackWriter.hpp" +#include "ACTFW/Propagation/PropagationAlgorithm.hpp" +#include "ACTFW/Propagation/PropagationOptions.hpp" +#include "ACTFW/Random/RandomNumbersOptions.hpp" +#include "ACTFW/Random/RandomNumbersSvc.hpp" +#include "ACTFW/Utilities/Paths.hpp" +#include "Acts/Detector/TrackingGeometry.hpp" +#include "Acts/Extrapolator/Navigator.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/MagneticField/InterpolatedBFieldMap.hpp" +#include "Acts/MagneticField/SharedBField.hpp" +#include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Propagator/StraightLineStepper.hpp" + +namespace po = boost::program_options; + +/// @brief Propagation setup +/// +/// @tparam sequencer_t Type of the sequencer of the framework +/// @tparam bfield_t Type of the magnetic field +/// +/// @param sequencer The framework sequencer, Propagation algorithm to be added +/// @param bfield The bfield object needed for the Stepper & propagagor +/// @param vm The program options for the log file +/// @param randomNumberSvc The framework random number engine +/// @param tGeometry The TrackingGeometry object +/// +/// @return a process code +template <typename sequencer_t, typename bfield_t> +FW::ProcessCode +setupPropagation(sequencer_t& sequencer, + bfield_t bfield, + po::variables_map& vm, + std::shared_ptr<FW::RandomNumbersSvc> randomNumberSvc, + std::shared_ptr<const Acts::TrackingGeometry> tGeometry) +{ + // Get the log level + auto logLevel = FW::Options::readLogLevel(vm); + + // Get a Navigator + Acts::Navigator navigator(tGeometry); + + // Resolve the bfield map template and create the propgator + using Stepper = Acts::EigenStepper<bfield_t>; + using Propagator = Acts::Propagator<Stepper, Acts::Navigator>; + Stepper stepper(std::move(bfield)); + Propagator propagator(std::move(stepper), std::move(navigator)); + + // Read the propagation config and create the algorithms + auto pAlgConfig = FW::Options::readPropagationConfig(vm, propagator); + pAlgConfig.randomNumberSvc = randomNumberSvc; + auto propagationAlg = std::make_shared<FW::PropagationAlgorithm<Propagator>>( + pAlgConfig, logLevel); + + // Add the propagation algorithm + sequencer.addAlgorithm({propagationAlg}); + + return FW::ProcessCode::SUCCESS; +} + +/// @brief Straight Line Propagation setup +/// +/// @tparam sequencer_t Type of the sequencer of the framework +/// +/// @param sequencer The framework sequencer, Propagation algorithm to be added +/// @param vm The program options for the log file +/// @param randomNumberSvc The framework random number engine +/// @param tGeometry The TrackingGeometry object +/// +/// @return a process code +template <typename sequencer_t> +FW::ProcessCode +setupStraightLinePropagation( + sequencer_t& sequencer, + po::variables_map& vm, + std::shared_ptr<FW::RandomNumbersSvc> randomNumberSvc, + std::shared_ptr<const Acts::TrackingGeometry> tGeometry) +{ + // Get the log level + auto logLevel = FW::Options::readLogLevel(vm); + + // Get a Navigator + Acts::Navigator navigator(tGeometry); + + // Straight line stepper + using SlStepper = Acts::StraightLineStepper; + using Propagator = Acts::Propagator<SlStepper, Acts::Navigator>; + // Make stepper and propagator + SlStepper stepper; + Propagator propagator(std::move(stepper), std::move(navigator)); + + // Read the propagation config and create the algorithms + auto pAlgConfig = FW::Options::readPropagationConfig(vm, propagator); + pAlgConfig.randomNumberSvc = randomNumberSvc; + auto propagationAlg = std::make_shared<FW::PropagationAlgorithm<Propagator>>( + pAlgConfig, logLevel); + + // Add the propagation algorithm + sequencer.addAlgorithm({propagationAlg}); + + return FW::ProcessCode::SUCCESS; +} + +/// @brief The material validation example, it runs a propagation +/// and then writes out the material information +/// +/// @tparam options_setup_t Type of the options generator +/// @tparam geometry_setup_t Type of the geometry generator +/// +/// @param argc the number of argumetns of the call +/// @param atgv the argument list +/// +/// +/// @param optionsSetup is a struct to generate example specific options +/// @param geometrySteup is a struct to generate the geometry +template <typename options_setup_t, typename geometry_setup_t> +int +materialValidationExample(int argc, + char* argv[], + options_setup_t optionsSetup, + geometry_setup_t geometrySetup) +{ + + // Setup and parse options + auto desc = FW::Options::makeDefaultOptions(); + FW::Options::addSequencerOptions(desc); + FW::Options::addGeometryOptions(desc); + FW::Options::addMaterialOptions(desc); + FW::Options::addBFieldOptions(desc); + FW::Options::addRandomNumbersOptions(desc); + FW::Options::addPropagationOptions(desc); + FW::Options::addOutputOptions(desc); + + // Add specific options for this geometry + optionsSetup(desc); + auto vm = FW::Options::parse(desc, argc, argv); + if (vm.empty()) { + return EXIT_FAILURE; + } + + FW::Sequencer sequencer(FW::Options::readSequencerConfig(vm)); + + // Now read the standard options + auto logLevel = FW::Options::readLogLevel(vm); + + // The geometry, material and decoration + auto geometry = FW::Geometry::build(vm, geometrySetup); + auto tGeometry = geometry.first; + auto contextDecorators = geometry.second; + + // Create the random number engine + auto randomNumberSvcCfg = FW::Options::readRandomNumbersConfig(vm); + auto randomNumberSvc + = std::make_shared<FW::RandomNumbersSvc>(randomNumberSvcCfg); + // Add it to the sequencer + sequencer.addService(randomNumberSvc); + + // Create BField service + auto bField = FW::Options::readBField<po::variables_map>(vm); + auto field2D = std::get<std::shared_ptr<InterpolatedBFieldMap2D>>(bField); + auto field3D = std::get<std::shared_ptr<InterpolatedBFieldMap3D>>(bField); + auto fieldC = std::get<std::shared_ptr<Acts::ConstantBField>>(bField); + + if (vm["prop-stepper"].template as<int>() == 0) { + // Straight line stepper was chosen + setupStraightLinePropagation(sequencer, vm, randomNumberSvc, tGeometry); + } else if (field2D) { + // Define the interpolated b-field: 2D + using BField = Acts::SharedBField<InterpolatedBFieldMap2D>; + BField fieldMap(field2D); + setupPropagation(sequencer, fieldMap, vm, randomNumberSvc, tGeometry); + } else if (field3D) { + // Define the interpolated b-field: 3D + using BField = Acts::SharedBField<InterpolatedBFieldMap3D>; + BField fieldMap(field3D); + setupPropagation(sequencer, fieldMap, vm, randomNumberSvc, tGeometry); + } else { + // Create the constant field + using CField = Acts::ConstantBField; + CField fieldMap(*std::get<std::shared_ptr<CField>>(bField)); + // Create the constant field + setupPropagation(sequencer, fieldMap, vm, randomNumberSvc, tGeometry); + } + + // --------------------------------------------------------------------------------- + // Output directory + std::string outputDir = vm["output-dir"].template as<std::string>(); + auto matCollection = vm["prop-material-collection"].as<std::string>(); + + if (vm["output-root"].template as<bool>()) { + // Write the propagation steps as ROOT TTree + FW::Root::RootMaterialTrackWriter::Config matTrackWriterRootConfig; + matTrackWriterRootConfig.collection = matCollection; + matTrackWriterRootConfig.filePath + = FW::joinPaths(outputDir, matCollection + ".root"); + auto matTrackWriterRoot + = std::make_shared<FW::Root::RootMaterialTrackWriter>( + matTrackWriterRootConfig, logLevel); + sequencer.addWriter(matTrackWriterRoot); + } + + // Initiate the run + sequencer.run(); + // Return success code + return 0; +} diff --git a/Examples/Propagation/CMakeLists.txt b/Examples/Propagation/CMakeLists.txt index 717abb06860d3f2b27ecbef4b40ee375ec53477e..049d55e60dcc5064b7b06cff870bd8a6e15d5184 100755 --- a/Examples/Propagation/CMakeLists.txt +++ b/Examples/Propagation/CMakeLists.txt @@ -1,57 +1,71 @@ +set(_common_libraries + ActsCore + ACTFramework + ACTFWPropagation + ACTFWExamplesCommon + ACTFWBFieldPlugin + ACTFWObjPlugin + ACTFWJsonPlugin + ACTFWRootPlugin + ${Boost_LIBRARIES}) + # Generic detector add_executable(ACTFWGenericPropagationExample src/GenericPropagationExample.cpp) -target_include_directories(ACTFWGenericPropagationExample PRIVATE ${Boost_INCLUDE_DIRS}) -target_link_libraries(ACTFWGenericPropagationExample PRIVATE ActsCore) -target_link_libraries(ACTFWGenericPropagationExample PRIVATE ACTFramework ACTFWExamplesCommon ACTFWPropagation ACTFWGenericDetector) -target_link_libraries(ACTFWGenericPropagationExample PRIVATE ACTFWRootPlugin ACTFWObjPlugin ACTFWBFieldPlugin) -target_link_libraries(ACTFWGenericPropagationExample PRIVATE ${Boost_LIBRARIES}) - -install(TARGETS ACTFWGenericPropagationExample RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +target_include_directories(ACTFWGenericPropagationExample PRIVATE + ${Boost_INCLUDE_DIRS}) +target_link_libraries(ACTFWGenericPropagationExample PRIVATE + ${_common_libraries} + ACTFWGenericDetector) +install( + TARGETS ACTFWGenericPropagationExample + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) # Generic detector with IOV based alignment add_executable(ACTFWAlignedPropagationExample src/AlignedPropagationExample.cpp) -target_include_directories(ACTFWAlignedPropagationExample PRIVATE ${Boost_INCLUDE_DIRS}) -target_link_libraries(ACTFWAlignedPropagationExample PRIVATE ActsCore) -target_link_libraries(ACTFWAlignedPropagationExample PRIVATE ACTFramework ACTFWExamplesCommon ACTFWPropagation) -target_link_libraries(ACTFWAlignedPropagationExample PRIVATE ACTFWGenericDetector ACTFWContextualDetector) -target_link_libraries(ACTFWAlignedPropagationExample PRIVATE ACTFWRootPlugin ACTFWObjPlugin ACTFWBFieldPlugin) -target_link_libraries(ACTFWAlignedPropagationExample PRIVATE ${Boost_LIBRARIES}) - -install(TARGETS ACTFWAlignedPropagationExample RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +target_include_directories(ACTFWAlignedPropagationExample PRIVATE + ${Boost_INCLUDE_DIRS}) +target_link_libraries(ACTFWAlignedPropagationExample PRIVATE + ${_common_libraries} + ACTFWContextualDetector) +install( + TARGETS ACTFWAlignedPropagationExample + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -# Generic detector with payload based alignment +# Generic detector with Payload based alignment add_executable(ACTFWPayloadPropagationExample src/PayloadPropagationExample.cpp) -target_include_directories(ACTFWPayloadPropagationExample PRIVATE ${Boost_INCLUDE_DIRS}) -target_link_libraries(ACTFWPayloadPropagationExample PRIVATE ActsCore) -target_link_libraries(ACTFWPayloadPropagationExample PRIVATE ACTFramework ACTFWExamplesCommon ACTFWPropagation) -target_link_libraries(ACTFWPayloadPropagationExample PRIVATE ACTFWGenericDetector ACTFWContextualDetector) -target_link_libraries(ACTFWPayloadPropagationExample PRIVATE ACTFWRootPlugin ACTFWObjPlugin ACTFWBFieldPlugin) -target_link_libraries(ACTFWPayloadPropagationExample PRIVATE ${Boost_LIBRARIES}) - -install(TARGETS ACTFWPayloadPropagationExample RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +target_include_directories(ACTFWPayloadPropagationExample PRIVATE + ${Boost_INCLUDE_DIRS}) +target_link_libraries(ACTFWPayloadPropagationExample PRIVATE + ${_common_libraries} + ACTFWContextualDetector) +install( + TARGETS ACTFWPayloadPropagationExample + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) # TGEO based detector if (USE_TGEO) add_executable(ACTFWTGeoPropagationExample src/TGeoPropagationExample.cpp) - target_include_directories(ACTFWTGeoPropagationExample PRIVATE ${Boost_INCLUDE_DIRS}) - target_link_libraries(ACTFWTGeoPropagationExample PRIVATE ActsCore) - target_link_libraries(ACTFWTGeoPropagationExample PRIVATE ACTFramework ACTFWExamplesCommon ACTFWPropagation ACTFWTGeoDetector) - target_link_libraries(ACTFWTGeoPropagationExample PRIVATE ACTFWRootPlugin ACTFWObjPlugin ACTFWBFieldPlugin) - target_link_libraries(ACTFWTGeoPropagationExample PRIVATE ${Boost_LIBRARIES}) - - install(TARGETS ACTFWTGeoPropagationExample RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + target_include_directories(ACTFWTGeoPropagationExample PRIVATE + ${Boost_INCLUDE_DIRS}) + target_link_libraries(ACTFWTGeoPropagationExample PRIVATE + ${_common_libraries} + ACTFWTGeoDetector ACTFWGeometryInterfaces) + install( + TARGETS ACTFWTGeoPropagationExample + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() # DD4hep detector if (USE_DD4HEP) add_executable(ACTFWDD4hepPropagationExample src/DD4hepPropagationExample.cpp) - target_include_directories(ACTFWDD4hepPropagationExample PRIVATE ${DD4hep_INCLUDE_DIRS}) - target_include_directories(ACTFWDD4hepPropagationExample PRIVATE ${Boost_INCLUDE_DIRS}) - target_link_libraries(ACTFWDD4hepPropagationExample PRIVATE ActsCore) - target_link_libraries(ACTFWDD4hepPropagationExample PRIVATE ACTFramework ACTFWExamplesCommon ACTFWPropagation ACTFWDD4hepDetector) - target_link_libraries(ACTFWDD4hepPropagationExample PRIVATE ACTFWRootPlugin ACTFWObjPlugin ACTFWBFieldPlugin) - target_link_libraries(ACTFWDD4hepPropagationExample PRIVATE ${DD4hep_LIBRARIES}) - target_link_libraries(ACTFWDD4hepPropagationExample PRIVATE ${Boost_LIBRARIES}) - - install(TARGETS ACTFWDD4hepPropagationExample RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + target_include_directories(ACTFWDD4hepPropagationExample PRIVATE + ${Boost_INCLUDE_DIRS} + ${DD4hep_INCLUDE_DIRS}) + target_link_libraries(ACTFWDD4hepPropagationExample PRIVATE + ${_common_libraries} + ACTFWDD4hepDetector ACTFWGeometryInterfaces + ${DD4hep_LIBRARIES}) + install( + TARGETS ACTFWDD4hepPropagationExample + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() diff --git a/Examples/Propagation/src/detail/PropagationExampleBase.hpp b/Examples/Propagation/src/detail/PropagationExampleBase.hpp index 42542d1549df155a798c2010733f8b33a617e7bd..743ccde0b6c1391fc697d6ddae7dcfc600dd362b 100644 --- a/Examples/Propagation/src/detail/PropagationExampleBase.hpp +++ b/Examples/Propagation/src/detail/PropagationExampleBase.hpp @@ -13,6 +13,7 @@ #include <boost/program_options.hpp> #include "ACTFW/Framework/Sequencer.hpp" +#include "ACTFW/Geometry/CommonGeometry.hpp" #include "ACTFW/Options/CommonOptions.hpp" #include "ACTFW/Plugins/BField/BFieldOptions.hpp" #include "ACTFW/Plugins/BField/ScalableBField.hpp" @@ -130,30 +131,32 @@ propagationExample(int argc, options_setup_t& optionsSetup, geometry_setup_t& geometrySetup) { - // setup and parse options + // Setup and parse options auto desc = FW::Options::makeDefaultOptions(); FW::Options::addSequencerOptions(desc); FW::Options::addGeometryOptions(desc); + FW::Options::addMaterialOptions(desc); FW::Options::addBFieldOptions(desc); FW::Options::addRandomNumbersOptions(desc); FW::Options::addPropagationOptions(desc); FW::Options::addOutputOptions(desc); + // Add specific options for this geometry optionsSetup(desc); auto vm = FW::Options::parse(desc, argc, argv); if (vm.empty()) { return EXIT_FAILURE; } - FW::Sequencer sequencer(FW::Options::readSequencerConfig(vm)); // Now read the standard options - auto logLevel = FW::Options::readLogLevel(vm); - auto geometry = geometrySetup(vm); + auto logLevel = FW::Options::readLogLevel(vm); + + // The geometry, material and decoration + auto geometry = FW::Geometry::build(vm, geometrySetup); auto tGeometry = geometry.first; auto contextDecorators = geometry.second; - - // Add it to the sequencer + // Add the decorator to the sequencer for (auto cdr : contextDecorators) { sequencer.addContextDecorator(cdr); } diff --git a/Plugins/CMakeLists.txt b/Plugins/CMakeLists.txt index 40755da18e79f5b741275fe40fb17f2d12a21f32..6b1965c6ec1197388e39e630dbe6e18fb88be49b 100644 --- a/Plugins/CMakeLists.txt +++ b/Plugins/CMakeLists.txt @@ -1,9 +1,9 @@ add_subdirectory(BField) add_subdirectory(Csv) -#add_subdirectory_if(DD4hepG4 USE_DD4HEP AND USE_GEANT4) +add_subdirectory_if(DD4hepG4 USE_DD4HEP AND USE_GEANT4) add_subdirectory_if(Geant4 USE_GEANT4) -#add_subdirectory(Json) +add_subdirectory(Json) add_subdirectory(Obj) add_subdirectory_if(Pythia8 USE_PYTHIA8) add_subdirectory(Root) -add_subdirectory_if(HepMC USE_HEPMC3) \ No newline at end of file +add_subdirectory_if(HepMC USE_HEPMC3) diff --git a/Plugins/DD4hepG4/CMakeLists.txt b/Plugins/DD4hepG4/CMakeLists.txt index 8a6eec5c805da2e73105b8f5b8694b27b4d7542b..c732647d968b354829c10f7b8318b20e91a95738 100644 --- a/Plugins/DD4hepG4/CMakeLists.txt +++ b/Plugins/DD4hepG4/CMakeLists.txt @@ -6,7 +6,7 @@ add_library(ACTFWDD4hepG4Plugin SHARED ${src_files}) target_include_directories(ACTFWDD4hepG4Plugin PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/> $<INSTALL_INTERFACE:include>) target_include_directories(ACTFWDD4hepG4Plugin PUBLIC ${DD4hep_INCLUDE_DIRS}) target_include_directories(ACTFWDD4hepG4Plugin PUBLIC ${ROOT_INCLUDE_DIRS}) -target_link_libraries(ACTFWDD4hepG4Plugin PUBLIC ACTFramework) +target_link_libraries(ACTFWDD4hepG4Plugin PUBLIC ACTFramework ACTFWGeometryInterfaces) target_link_libraries(ACTFWDD4hepG4Plugin PUBLIC ${DD4hep_LIBRARIES} ${DD4hep_DDG4_LIBRARY}) target_link_libraries(ACTFWDD4hepG4Plugin PUBLIC ${Geant4_LIBRARIES}) target_link_libraries(ACTFWDD4hepG4Plugin PUBLIC ${ROOT_LIBRARIES}) diff --git a/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMDetectorConstruction.hpp b/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMDetectorConstruction.hpp index ae118893f43b3083fb867a7542c2c6e8b35abb19..099c170e61d43f686c3ceac2645f55b957f58537 100644 --- a/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMDetectorConstruction.hpp +++ b/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMDetectorConstruction.hpp @@ -6,8 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef ACTFW_PLUGINS_GEANT4_MMDETECTORCONSTRUCTION_H -#define ACTFW_PLUGINS_GEANT4_MMDETECTORCONSTRUCTION_H +#pragma once #include "G4VUserDetectorConstruction.hh" #include "globals.hh" @@ -19,7 +18,7 @@ class G4VPhysicalVolume; class TGeoNode; namespace FW { -namespace G4 { +namespace Geant4 { /// @class MMDetectorConstruction /// @@ -56,5 +55,3 @@ namespace G4 { }; } // namespace G4 } // namespace FW - -#endif // ACTFW_PLUGINS_GEANT4_MMDETECTORCONSTRUCTION_H diff --git a/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMEventAction.hpp b/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMEventAction.hpp index 3b2dab0b111c0670ba57f7dda124b3e2e0b1abb4..0bd5252241d1bc2867c35a7412f592cb47a98160 100644 --- a/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMEventAction.hpp +++ b/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMEventAction.hpp @@ -1,26 +1,26 @@ // This file is part of the Acts project. // -// Copyright (C) 2017 Acts project team +// Copyright (C) 2017-2018 Acts project team // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. /////////////////////////////////////////////////////////////////// -// MMEventAction.h +// MMEventAction.hpp /////////////////////////////////////////////////////////////////// -#ifndef ACTFW_PLUGINS_GEANT4_MMEVENTACTION_H -#define ACTFW_PLUGINS_GEANT4_MMEVENTACTION_H +#pragma once #include <memory> -#include "Acts/Plugins/MaterialMapping/RecordedMaterialTrack.hpp" +#include "Acts/Extrapolator/MaterialInteractor.hpp" #include "G4UserEventAction.hh" #include "globals.hh" -/// @namespace FW::G4:: Namespace for geant4 material mapping +/// @namespace FW::Geant4:: Namespace for geant4 material mapping namespace FW { -namespace G4 { + +namespace Geant4 { class MMSteppingAction; @@ -81,7 +81,5 @@ namespace G4 { m_records.clear(); return rrecords; } -} // namespace G4 +} // namespace Geant4 } // namespace FW - -#endif // ACTFW_PLUGINS_GEANT4_MMEVENTACTION_H diff --git a/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMPrimaryGeneratorAction.hpp b/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMPrimaryGeneratorAction.hpp index bc9a038b5187195e5058e8609e4e182d365765f4..12402a8875d9cd30981e57fd0eb3c65d5f64865e 100644 --- a/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMPrimaryGeneratorAction.hpp +++ b/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMPrimaryGeneratorAction.hpp @@ -7,11 +7,10 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. /////////////////////////////////////////////////////////////////// -// MMPrimaryGeneratorAction.h +// MMPrimaryGeneratorAction.hpp /////////////////////////////////////////////////////////////////// -#ifndef ACTFW_PLUGINS_GEANT4_MMPRIMARYGENERATORACTION_H -#define ACTFW_PLUGINS_GEANT4_MMPRIMARYGENERATORACTION_H +#pragma once #include <memory> #include "G4SystemOfUnits.hh" @@ -23,7 +22,7 @@ class G4ParticleGun; class G4Event; namespace FW { -namespace G4 { +namespace Geant4 { /// @class MMPrimaryGeneratorAction /// @@ -82,5 +81,3 @@ namespace G4 { } // namespace G4 } // namespace FW - -#endif // GEANT4MATERIALMAPPING_MMPRIMARYGENERATORACTION_H diff --git a/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMRunAction.hpp b/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMRunAction.hpp index 536961f160d38796d52be3a5cfe10bc088dfbefb..cea996a87972fb90943843330368f069b09378fa 100644 --- a/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMRunAction.hpp +++ b/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMRunAction.hpp @@ -7,11 +7,10 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. /////////////////////////////////////////////////////////////////// -// MMRunAction.h +// MMRunAction.hpp /////////////////////////////////////////////////////////////////// -#ifndef ACTFW_PLUGINS_GEANT4_MMRUNACTION_H -#define ACTFW_PLUGINS_GEANT4_MMRUNACTION_H +#pragma once #include <memory> #include "G4UserRunAction.hh" @@ -20,7 +19,7 @@ class G4Run; namespace FW { -namespace G4 { +namespace Geant4 { /// @class MMRunAction /// @@ -58,5 +57,3 @@ namespace G4 { }; } // namespace G4 } // namespace FW - -#endif // ACTFW_PLUGINS_GEANT4_MMRUNACTION_H diff --git a/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMSteppingAction.hpp b/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMSteppingAction.hpp index f1be5ba8ff63f29cd2d16004972a85286fe8de2e..9d3ab9648b36b19ba7b9c25f6d5449720ffbcc61 100644 --- a/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMSteppingAction.hpp +++ b/Plugins/Geant4/include/ACTFW/Plugins/Geant4/MMSteppingAction.hpp @@ -1,34 +1,32 @@ // This file is part of the Acts project. // -// Copyright (C) 2017 Acts project team +// Copyright (C) 2017-2018 Acts project team // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. /////////////////////////////////////////////////////////////////// -// MMMaterialStepAction.h +// MMMaterialStepAction.hpp /////////////////////////////////////////////////////////////////// -#ifndef ACTFW_PLUGINS_GEANT4_MMSTEPPINGACTION_H -#define ACTFW_PLUGINS_GEANT4_MMSTEPPINGACTION_H +#pragma once #include <vector> -#include "Acts/Plugins/MaterialMapping/RecordedMaterialTrack.hpp" +#include "Acts/Extrapolator/MaterialInteractor.hpp" #include "G4UserSteppingAction.hh" #include "globals.hh" namespace FW { -namespace G4 { +namespace Geant4 { /// @class MMSteppingAction /// /// @brief Collects the RecordedMaterialProperties entities /// /// The MMSteppingAction class is the implementation of the - /// Geant4 class SteppingAction. It creates extracts the weighted material + /// Geant4 class SteppingAction. It extracts the weighted material /// of every step and collects all material steps. - class MMSteppingAction : public G4UserSteppingAction { public: @@ -38,12 +36,12 @@ namespace G4 { /// Destructor ~MMSteppingAction() override; - /// Static access method + /// Static access method to the instance static MMSteppingAction* Instance(); - /// Interface Method doing the step - /// @note it creates and collects the RecordedMaterialProperties entities + /// @brief Interface Method doing the step + /// @note it creates and collects the MaterialInteraction entities /// @param step is the Geant4 step of the particle void UserSteppingAction(const G4Step* step) final override; @@ -53,8 +51,8 @@ namespace G4 { void Reset(); - /// Access to the collected RecordedMaterialProperties entities - std::vector<Acts::RecordedMaterialProperties> + /// Access to the collected Acts::MaterialInteraction entities + std::vector<Acts::MaterialInteraction> materialSteps() { return m_steps; @@ -64,11 +62,9 @@ namespace G4 { /// Instance of the SteppingAction static MMSteppingAction* fgInstance; - /// The collected RecordedMaterialProperties entities - std::vector<Acts::RecordedMaterialProperties> m_steps; + /// The collected Acts::MaterialInteraction entities + std::vector<Acts::MaterialInteraction> m_steps = {}; }; -} // namespace G4 +} // namespace Geant4 } // namespace FW - -#endif // ACTFW_PLUGINS_GEANT4_MMSTEPPINGACTION_H diff --git a/Plugins/Geant4/src/MMDetectorConstruction.cpp b/Plugins/Geant4/src/MMDetectorConstruction.cpp index 40fa3d29f5cd49736a28897727f732b3484da9c1..15e6efc4c1e422cb5e3e135c5ed9209d61296024 100644 --- a/Plugins/Geant4/src/MMDetectorConstruction.cpp +++ b/Plugins/Geant4/src/MMDetectorConstruction.cpp @@ -10,13 +10,13 @@ #include "G4GDMLParser.hh" #include "TGeoManager.h" -FW::G4::MMDetectorConstruction::MMDetectorConstruction() +FW::Geant4::MMDetectorConstruction::MMDetectorConstruction() : G4VUserDetectorConstruction(), m_tgeoNode(nullptr), m_gdmlFile(nullptr) { } G4VPhysicalVolume* -FW::G4::MMDetectorConstruction::Construct() +FW::Geant4::MMDetectorConstruction::Construct() { if (m_tgeoNode) { // Import geometry from Root to VGM @@ -40,13 +40,13 @@ FW::G4::MMDetectorConstruction::Construct() } void -FW::G4::MMDetectorConstruction::setTGeoGeometry(TGeoNode* tgeoNode) +FW::Geant4::MMDetectorConstruction::setTGeoGeometry(TGeoNode* tgeoNode) { m_tgeoNode = tgeoNode; } void -FW::G4::MMDetectorConstruction::setGdmlInput(std::string gdmlFile) +FW::Geant4::MMDetectorConstruction::setGdmlInput(std::string gdmlFile) { m_gdmlFile = new std::string(gdmlFile); } diff --git a/Plugins/Geant4/src/MMEventAction.cpp b/Plugins/Geant4/src/MMEventAction.cpp index f4b8e66f1208231aac4724e871f9f1b06246057f..cd528f2c0b1242c52f0ca41db2e68844ef2ec292 100644 --- a/Plugins/Geant4/src/MMEventAction.cpp +++ b/Plugins/Geant4/src/MMEventAction.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017 Acts project team +// Copyright (C) 2017-2018 Acts project team // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -13,16 +13,16 @@ #include "G4Event.hh" #include "G4RunManager.hh" -FW::G4::MMEventAction* FW::G4::MMEventAction::fgInstance = nullptr; +FW::Geant4::MMEventAction* FW::Geant4::MMEventAction::fgInstance = nullptr; -FW::G4::MMEventAction* -FW::G4::MMEventAction::Instance() +FW::Geant4::MMEventAction* +FW::Geant4::MMEventAction::Instance() { // Static acces function via G4RunManager return fgInstance; } -FW::G4::MMEventAction::MMEventAction() : G4UserEventAction() +FW::Geant4::MMEventAction::MMEventAction() : G4UserEventAction() { if (fgInstance) { throw std::logic_error("Attempted to duplicate a singleton"); @@ -31,34 +31,38 @@ FW::G4::MMEventAction::MMEventAction() : G4UserEventAction() } } -FW::G4::MMEventAction::~MMEventAction() +FW::Geant4::MMEventAction::~MMEventAction() { fgInstance = nullptr; } void -FW::G4::MMEventAction::BeginOfEventAction(const G4Event*) +FW::Geant4::MMEventAction::BeginOfEventAction(const G4Event*) { // reset the collection of material steps MMSteppingAction::Instance()->Reset(); } void -FW::G4::MMEventAction::EndOfEventAction(const G4Event* event) +FW::Geant4::MMEventAction::EndOfEventAction(const G4Event* event) { - const auto* rawPos = event->GetPrimaryVertex(); - const Acts::Vector3D pos(rawPos->GetX0(), rawPos->GetY0(), rawPos->GetZ0()); + + const auto* rawPos = event->GetPrimaryVertex(); // access the initial direction of the track G4ThreeVector rawDir = MMPrimaryGeneratorAction::Instance()->direction(); - const Acts::Vector3D dir(rawDir.x(), rawDir.y(), rawDir.z()); // create the RecordedMaterialTrack - Acts::RecordedMaterialTrack mtrecord( - pos, dir, MMSteppingAction::Instance()->materialSteps()); + Acts::RecordedMaterialTrack mtrecord; + mtrecord.first.first + = Acts::Vector3D(rawPos->GetX0(), rawPos->GetY0(), rawPos->GetZ0()); + mtrecord.first.second = Acts::Vector3D(rawDir.x(), rawDir.y(), rawDir.z()); + mtrecord.second.materialInteractions + = MMSteppingAction::Instance()->materialSteps(); + // write out the RecordedMaterialTrack of one event m_records.push_back(mtrecord); } void -FW::G4::MMEventAction::Reset() +FW::Geant4::MMEventAction::Reset() { } diff --git a/Plugins/Geant4/src/MMPrimaryGeneratorAction.cpp b/Plugins/Geant4/src/MMPrimaryGeneratorAction.cpp index 58afaa9daa998c2964b2c66ccc67387bf988b9bf..034c44ff2b3e9c5fdd513d16ee6f3d4f4f93e55d 100644 --- a/Plugins/Geant4/src/MMPrimaryGeneratorAction.cpp +++ b/Plugins/Geant4/src/MMPrimaryGeneratorAction.cpp @@ -16,10 +16,11 @@ #include "G4UnitsTable.hh" #include "Randomize.hh" -FW::G4::MMPrimaryGeneratorAction* FW::G4::MMPrimaryGeneratorAction::fgInstance +FW::Geant4::MMPrimaryGeneratorAction* + FW::Geant4::MMPrimaryGeneratorAction::fgInstance = nullptr; -FW::G4::MMPrimaryGeneratorAction::MMPrimaryGeneratorAction( +FW::Geant4::MMPrimaryGeneratorAction::MMPrimaryGeneratorAction( const G4String& particleName, G4double energy, G4int randomSeed1, @@ -46,20 +47,20 @@ FW::G4::MMPrimaryGeneratorAction::MMPrimaryGeneratorAction( CLHEP::HepRandom::getTheEngine()->setSeed(randomSeed1, randomSeed2); } -FW::G4::MMPrimaryGeneratorAction::~MMPrimaryGeneratorAction() +FW::Geant4::MMPrimaryGeneratorAction::~MMPrimaryGeneratorAction() { fgInstance = nullptr; } -FW::G4::MMPrimaryGeneratorAction* -FW::G4::MMPrimaryGeneratorAction::Instance() +FW::Geant4::MMPrimaryGeneratorAction* +FW::Geant4::MMPrimaryGeneratorAction::Instance() { // Static acces function via G4RunManager return fgInstance; } void -FW::G4::MMPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent) +FW::Geant4::MMPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent) { // this function is called at the begining of event G4double phi = -M_PI + G4UniformRand() * 2. * M_PI; diff --git a/Plugins/Geant4/src/MMRunAction.cpp b/Plugins/Geant4/src/MMRunAction.cpp index 7d4c5ee81c68ca7ad61f17dcc76b6faf661a96e3..2a1534b0eb8cd547a9c1d873fcc57fb0836d39ae 100644 --- a/Plugins/Geant4/src/MMRunAction.cpp +++ b/Plugins/Geant4/src/MMRunAction.cpp @@ -11,9 +11,9 @@ #include "ACTFW/Plugins/Geant4/MMEventAction.hpp" #include "G4Run.hh" -FW::G4::MMRunAction* FW::G4::MMRunAction::fgInstance = nullptr; +FW::Geant4::MMRunAction* FW::Geant4::MMRunAction::fgInstance = nullptr; -FW::G4::MMRunAction::MMRunAction() : G4UserRunAction() +FW::Geant4::MMRunAction::MMRunAction() : G4UserRunAction() { if (fgInstance) { throw std::logic_error("Attempted to duplicate a singleton"); @@ -22,19 +22,19 @@ FW::G4::MMRunAction::MMRunAction() : G4UserRunAction() } } -FW::G4::MMRunAction::~MMRunAction() +FW::Geant4::MMRunAction::~MMRunAction() { fgInstance = nullptr; } -FW::G4::MMRunAction* -FW::G4::MMRunAction::Instance() +FW::Geant4::MMRunAction* +FW::Geant4::MMRunAction::Instance() { return fgInstance; } void -FW::G4::MMRunAction::BeginOfRunAction(const G4Run* aRun) +FW::Geant4::MMRunAction::BeginOfRunAction(const G4Run* aRun) { G4cout << "### Run " << aRun->GetRunID() << " start." << G4endl; // initialize event cumulative quantities @@ -42,7 +42,7 @@ FW::G4::MMRunAction::BeginOfRunAction(const G4Run* aRun) } void -FW::G4::MMRunAction::EndOfRunAction(const G4Run* aRun) +FW::Geant4::MMRunAction::EndOfRunAction(const G4Run* aRun) { G4int nofEvents = aRun->GetNumberOfEvent(); if (nofEvents == 0) return; diff --git a/Plugins/Geant4/src/MMSteppingAction.cpp b/Plugins/Geant4/src/MMSteppingAction.cpp index 16d6fbcab56ceaaf3ecd50223db35d802f501870..f5f3884eb11284690306bf51c539a0d0846a3044 100644 --- a/Plugins/Geant4/src/MMSteppingAction.cpp +++ b/Plugins/Geant4/src/MMSteppingAction.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017 Acts project team +// Copyright (C) 2017-2018 Acts project team // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -12,16 +12,18 @@ #include "G4Material.hh" #include "G4Step.hh" -FW::G4::MMSteppingAction* FW::G4::MMSteppingAction::fgInstance = nullptr; +FW::Geant4::MMSteppingAction* FW::Geant4::MMSteppingAction::fgInstance + = nullptr; -FW::G4::MMSteppingAction* -FW::G4::MMSteppingAction::Instance() +FW::Geant4::MMSteppingAction* +FW::Geant4::MMSteppingAction::Instance() { // Static acces function via G4RunManager return fgInstance; } -FW::G4::MMSteppingAction::MMSteppingAction() : G4UserSteppingAction(), m_steps() +FW::Geant4::MMSteppingAction::MMSteppingAction() + : G4UserSteppingAction(), m_steps() // m_volMgr(MaterialRunAction::Instance()->getGeant4VolumeManager()) { if (fgInstance) { @@ -31,13 +33,13 @@ FW::G4::MMSteppingAction::MMSteppingAction() : G4UserSteppingAction(), m_steps() } } -FW::G4::MMSteppingAction::~MMSteppingAction() +FW::Geant4::MMSteppingAction::~MMSteppingAction() { fgInstance = nullptr; } void -FW::G4::MMSteppingAction::UserSteppingAction(const G4Step* step) +FW::Geant4::MMSteppingAction::UserSteppingAction(const G4Step* step) { // get the material G4Material* material = step->GetPreStepPoint()->GetMaterial(); @@ -78,16 +80,17 @@ FW::G4::MMSteppingAction::UserSteppingAction(const G4Step* step) G4cout << "steplength: " << steplength << G4endl;*/ // create the RecordedMaterialProperties - const auto& rawPos = step->GetPreStepPoint()->GetPosition(); - const Acts::Vector3D pos(rawPos.x(), rawPos.y(), rawPos.z()); - const Acts::MaterialProperties matprop(X0, L0, A, Z, rho, steplength); - const Acts::RecordedMaterialProperties recMatProp(matprop, pos); - m_steps.push_back(recMatProp); + const auto& rawPos = step->GetPreStepPoint()->GetPosition(); + Acts::MaterialInteraction mInteraction; + mInteraction.position = Acts::Vector3D(rawPos.x(), rawPos.y(), rawPos.z()); + mInteraction.materialProperties + = Acts::MaterialProperties(X0, L0, A, Z, rho, steplength); + m_steps.push_back(mInteraction); } } void -FW::G4::MMSteppingAction::Reset() +FW::Geant4::MMSteppingAction::Reset() { m_steps.clear(); } diff --git a/Plugins/Json/CMakeLists.txt b/Plugins/Json/CMakeLists.txt index 77020c27aa28e96644f116e803ffca0aba7b5c8d..a231045b4c78c982ca1642b441888daa41493989 100644 --- a/Plugins/Json/CMakeLists.txt +++ b/Plugins/Json/CMakeLists.txt @@ -1,3 +1,10 @@ -add_library(ACTFWJsonPlugin INTERFACE) -target_include_directories(ACTFWJsonPlugin INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/> $<INSTALL_INTERFACE:include>) +set(srcs src/JsonMaterialWriter.cpp + src/JsonGeometryConverter.cpp) + +add_library(ACTFWJsonPlugin SHARED ${srcs}) +target_include_directories(ACTFWJsonPlugin PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) +target_link_libraries(ACTFWJsonPlugin PUBLIC ActsCore ActsJsonPlugin) +target_link_libraries(ACTFWJsonPlugin PUBLIC ACTFramework) + +install(TARGETS ACTFWJsonPlugin LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(DIRECTORY include/ACTFW DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/Plugins/Json/include/ACTFW/Plugins/Json/JsonGeometryConverter.hpp b/Plugins/Json/include/ACTFW/Plugins/Json/JsonGeometryConverter.hpp new file mode 100644 index 0000000000000000000000000000000000000000..998a302c665ce865915e7b1a0df1d06ae5d01dcb --- /dev/null +++ b/Plugins/Json/include/ACTFW/Plugins/Json/JsonGeometryConverter.hpp @@ -0,0 +1,236 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include <map> +#include "Acts/Detector/TrackingGeometry.hpp" +#include "Acts/Material/ISurfaceMaterial.hpp" +#include "Acts/Material/IVolumeMaterial.hpp" +#include "Acts/Material/MaterialProperties.hpp" +#include "Acts/Plugins/Json/lib/json.hpp" +#include "Acts/Utilities/BinUtility.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/Logger.hpp" + +// Convenience shorthand +using json = nlohmann::json; + +namespace Acts { + +using SurfaceMaterialMap + = std::map<GeometryID, std::shared_ptr<const ISurfaceMaterial>>; + +using VolumeMaterialMap + = std::map<GeometryID, std::shared_ptr<const IVolumeMaterial>>; + +using DetectorMaterialMaps = std::pair<SurfaceMaterialMap, VolumeMaterialMap>; +} + +namespace FW { + +namespace Json { + + using SurfaceMaterialRep + = std::map<geo_id_value, const Acts::ISurfaceMaterial*>; + using VolumeMaterialRep + = std::map<geo_id_value, const Acts::IVolumeMaterial*>; + + /// @brief Layer representation for Json writing + struct LayerRep + { + // the layer id + Acts::GeometryID layerID; + + SurfaceMaterialRep sensitives; + SurfaceMaterialRep approaches; + const Acts::ISurfaceMaterial* representing = nullptr; + + /// The LayerRep is actually worth it to write out + operator bool() const + { + return (sensitives.size() != 0 or approaches.size() != 0 + or representing != nullptr); + } + }; + + /// @brief Volume representation for Json writing + struct VolumeRep + { + // the geometry id + Acts::GeometryID volumeID; + + /// the namne + std::string volumeName; + + std::map<geo_id_value, LayerRep> layers; + SurfaceMaterialRep boundaries; + const Acts::IVolumeMaterial* material = nullptr; + + /// The VolumeRep is actually worth it to write out + operator bool() const + { + return (layers.size() != 0 or boundaries.size() != 0 + or material != nullptr); + } + }; + + /// @brief Detector representation for Json writing + struct DetectorRep + { + + std::map<geo_id_value, VolumeRep> volumes; + }; + + /// @class JsonGeometryConverter + /// + /// @brief read the material from Json + class JsonGeometryConverter + { + + public: + /// @class Config + /// Configuration of the Reader + class Config + { + public: + /// The geometry version + std::string geoversion = "undefined"; + /// The detector tag + std::string detkey = "detector"; + /// The volume identification string + std::string volkey = "volumes"; + /// The name identification + std::string namekey = "name"; + /// The boundary surface string + std::string boukey = "boundaries"; + /// The layer identification string + std::string laykey = "layers"; + /// The volume material string + std::string matkey = "material"; + /// The approach identification string + std::string appkey = "approach"; + /// The sensitive identification string + std::string senkey = "sensitive"; + /// The representing idntification string + std::string repkey = "representing"; + /// The bin keys + std::string bin0key = "bin0"; + /// The bin1 key + std::string bin1key = "bin1"; + /// The type key -> proto, else + std::string typekey = "type"; + /// The data key + std::string datakey = "data"; + /// The default logger + std::shared_ptr<const Acts::Logger> logger; + /// The name of the writer + std::string name = ""; + + /// Steering to handle sensitive data + bool processSensitives = true; + /// Steering to handle approach data + bool processApproaches = true; + /// Steering to handle representing data + bool processRepresenting = true; + /// Steering to handle boundary data + bool processBoundaries = true; + /// Steering to handle volume data + bool processVolumes = true; + /// Write out data + bool writeData = true; + + /// Constructor + /// + /// @param lname Name of the writer tool + /// @param lvl The output logging level + Config(const std::string& lname = "JsonGeometryConverter", + Acts::Logging::Level lvl = Acts::Logging::INFO) + : logger(Acts::getDefaultLogger(lname, lvl)), name(lname) + { + } + }; + + /// Constructor + /// + /// @param cfg configuration struct for the reader + JsonGeometryConverter(const Config& cfg); + + /// Destructor + ~JsonGeometryConverter() = default; + + /// Convert method + /// + /// @param surfaceMaterialMap The indexed material map collection + std::pair<Acts::SurfaceMaterialMap, Acts::VolumeMaterialMap> + jsonToMaterialMaps(const json& materialmaps); + + /// Convert method + /// + /// @param surfaceMaterialMap The indexed material map collection + json + materialMapsToJson(const Acts::DetectorMaterialMaps& maps); + + /// Write method + /// + /// @param tGeometry is the tracking geometry which contains the material + json + trackingGeometryToJson(const Acts::TrackingGeometry& tGeometry); + + private: + /// Convert to internal representation method, recursive call + /// + /// @param tGeometry is the tracking geometry which contains the material + void + convertToRep(DetectorRep& detRep, const Acts::TrackingVolume& tVolume); + + /// Convert to internal representation method + /// + /// @param tGeometry is the tracking geometry which contains the material + LayerRep + convertToRep(const Acts::Layer& tLayer); + + /// Create the Surface Material from Json + /// - factory method, ownership given + /// @param material is the json part representing a material object + const Acts::ISurfaceMaterial* + jsonToSurfaceMaterial(const json& material); + + /// Create the Material Matrix from Json + /// + /// @param data is the json part representing a material data array + Acts::MaterialPropertiesMatrix + jsonToMaterialMatrix(const json& data); + + /// Create the BinUtility for from Json + Acts::BinUtility + jsonToBinUtility(const json& bin); + + /// Create Json from a detector represenation + json + detectorRepToJson(const DetectorRep& detRep); + + /// SurfaceMaterial to Json + /// + /// @param the SurfaceMaterial + json + surfaceMaterialToJson(const Acts::ISurfaceMaterial& sMaterial); + + /// The config class + Config m_cfg; + + /// Private access to the logging instance + const Acts::Logger& + logger() const + { + return *m_cfg.logger; + } + }; + +} // namespace Json +} // namespace FW \ No newline at end of file diff --git a/Plugins/Json/include/ACTFW/Plugins/Json/JsonMaterialDecorator.hpp b/Plugins/Json/include/ACTFW/Plugins/Json/JsonMaterialDecorator.hpp new file mode 100644 index 0000000000000000000000000000000000000000..5cfaa066ed9e126e1187f1c10a3cb2dc9c2c93a7 --- /dev/null +++ b/Plugins/Json/include/ACTFW/Plugins/Json/JsonMaterialDecorator.hpp @@ -0,0 +1,106 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include <fstream> +#include <map> +#include <mutex> +#include "ACTFW/Plugins/Json/JsonGeometryConverter.hpp" +#include "Acts/Detector/TrackingVolume.hpp" +#include "Acts/Material/IMaterialDecorator.hpp" +#include "Acts/Material/ISurfaceMaterial.hpp" +#include "Acts/Material/IVolumeMaterial.hpp" +#include "Acts/Surfaces/Surface.hpp" + +// Convenience shorthand +using json = nlohmann::json; + +namespace Acts { + +using SurfaceMaterialMap + = std::map<GeometryID, std::shared_ptr<const ISurfaceMaterial>>; + +using VolumeMaterialMap + = std::map<GeometryID, std::shared_ptr<const IVolumeMaterial>>; +} + +namespace FW { + +namespace Json { + + /// @brief Material decorator from Json format + /// + /// This reads in material maps for surfaces and volumes + /// from a json file + class JsonMaterialDecorator : public Acts::IMaterialDecorator + { + public: + JsonMaterialDecorator(const JsonGeometryConverter::Config& rConfig, + const std::string& jFileName, + bool clearSurfaceMaterial = true, + bool clearVolumeMaterial = true) + : m_readerConfig(rConfig) + , m_clearSurfaceMaterial(clearSurfaceMaterial) + , m_clearVolumeMaterial(clearVolumeMaterial) + { + // the material reader + FW::Json::JsonGeometryConverter::Config jmConverterCfg( + "JsonGeometryConverter", Acts::Logging::VERBOSE); + FW::Json::JsonGeometryConverter jmConverter(jmConverterCfg); + + std::ifstream ifj(jFileName.c_str()); + json jin; + ifj >> jin; + + auto maps = jmConverter.jsonToMaterialMaps(jin); + m_surfaceMaterialMap = maps.first; + m_volumeMaterialMap = maps.second; + } + + /// Decorate a surface + /// + /// @param surface the non-cost surface that is decorated + void + decorate(Acts::Surface& surface) const final + { + // Clear the material if registered to do so + if (m_clearSurfaceMaterial) { + surface.assignSurfaceMaterial(nullptr); + } + + // Try to find the surface in the map + auto sMaterial = m_surfaceMaterialMap.find(surface.geoID()); + if (sMaterial != m_surfaceMaterialMap.end()) { + surface.assignSurfaceMaterial(sMaterial->second); + } + } + + /// Decorate a TrackingVolume + /// + /// @param volume the non-cost volume that is decorated + void + decorate(Acts::TrackingVolume& volume) const final + { + // Clear the material if registered to do so + if (m_clearVolumeMaterial) { + volume.assignVolumeMaterial(nullptr); + } + } + + private: + JsonGeometryConverter::Config m_readerConfig; + Acts::SurfaceMaterialMap m_surfaceMaterialMap; + Acts::VolumeMaterialMap m_volumeMaterialMap; + + bool m_clearSurfaceMaterial{true}; + bool m_clearVolumeMaterial{true}; + }; + +} // namespace Json +} // namespace FW diff --git a/Plugins/Json/include/ACTFW/Plugins/Json/JsonMaterialWriter.hpp b/Plugins/Json/include/ACTFW/Plugins/Json/JsonMaterialWriter.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0fcbbced9f31d8d92dc6059d7b4d95b59be7347f --- /dev/null +++ b/Plugins/Json/include/ACTFW/Plugins/Json/JsonMaterialWriter.hpp @@ -0,0 +1,86 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/////////////////////////////////////////////////////////////////// +// JsonMaterialWriter.h +/////////////////////////////////////////////////////////////////// + +#pragma once + +#include <mutex> +#include "ACTFW/Framework/ProcessCode.hpp" +#include "ACTFW/Plugins/Json/JsonGeometryConverter.hpp" +#include "Acts/Material/ISurfaceMaterial.hpp" +#include "Acts/Material/IVolumeMaterial.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/GeometryID.hpp" +#include "Acts/Utilities/Logger.hpp" + +namespace Acts { + +class TrackingGeometry; + +using SurfaceMaterialMap + = std::map<GeometryID, std::shared_ptr<const ISurfaceMaterial>>; + +using VolumeMaterialMap + = std::map<GeometryID, std::shared_ptr<const IVolumeMaterial>>; + +using DetectorMaterialMaps = std::pair<SurfaceMaterialMap, VolumeMaterialMap>; +} + +namespace FW { + +namespace Json { + + /// @class Json Material writer + /// + /// @brief Writes out Detector material maps + /// using the Json Geometry converter + class JsonMaterialWriter + { + + public: + /// Constructor + /// + /// @param cfg The configuration struct of the converter + JsonMaterialWriter(const JsonGeometryConverter::Config& cfg, + const std::string& fileName); + + /// Virtual destructor + ~JsonMaterialWriter(); + + /// Write out the material map + /// + /// @param detMaterial is the SurfaceMaterial and VolumeMaterial maps + void + write(const Acts::DetectorMaterialMaps& detMaterial); + + /// Write out the material map from Geometry + /// + /// @param tGeometry is the TrackingGeometry + void + write(const Acts::TrackingGeometry& tGeometry); + + private: + /// The config class of the converter + JsonGeometryConverter::Config m_cfg; + + /// The file name + std::string m_fileName; + + /// Private access to the logging instance + const Acts::Logger& + logger() const + { + return *m_cfg.logger; + } + }; + +} // namespace Json +} // namespace FW diff --git a/Plugins/Json/src/JsonGeometryConverter.cpp b/Plugins/Json/src/JsonGeometryConverter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4ae1f83ab2097597b3331b5fbc68e8796c14a214 --- /dev/null +++ b/Plugins/Json/src/JsonGeometryConverter.cpp @@ -0,0 +1,531 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "ACTFW/Plugins/Json/JsonGeometryConverter.hpp" +#include <boost/algorithm/string.hpp> +#include <boost/algorithm/string/finder.hpp> +#include <boost/algorithm/string/iter_find.hpp> +#include <cstdio> +#include <fstream> +#include <iostream> +#include <map> +#include <sstream> +#include <stdexcept> +#include <string> +#include "Acts/Detector/TrackingVolume.hpp" +#include "Acts/Layers/ApproachDescriptor.hpp" +#include "Acts/Material/BinnedSurfaceMaterial.hpp" +#include "Acts/Material/HomogeneousSurfaceMaterial.hpp" +#include "Acts/Material/ProtoSurfaceMaterial.hpp" +#include "Acts/Surfaces/SurfaceArray.hpp" +#include "Acts/Utilities/BinUtility.hpp" +#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/GeometryID.hpp" + +FW::Json::JsonGeometryConverter::JsonGeometryConverter( + const FW::Json::JsonGeometryConverter::Config& cfg) + : m_cfg(std::move(cfg)) +{ + // Validate the configuration + if (!m_cfg.logger) { + throw std::invalid_argument("Missing logger"); + } +} + +std::pair<Acts::SurfaceMaterialMap, Acts::VolumeMaterialMap> +FW::Json::JsonGeometryConverter::jsonToMaterialMaps(const json& materialmaps) +{ + + auto& j = materialmaps; + // The return maps + std::pair<Acts::SurfaceMaterialMap, Acts::VolumeMaterialMap> maps; + ACTS_VERBOSE("j2a: Reading material maps from json file."); + ACTS_VERBOSE("j2a: Found entries for " << j.count(m_cfg.volkey) + << " volume(s)."); + // structured binding + for (auto & [ key, value ] : j.items()) { + // check if this the volume key + if (key == m_cfg.volkey) { + // get the volume json + auto volj = value; + for (auto & [ vkey, vvalue ] : volj.items()) { + // create the volume id + int vid = std::stoi(vkey); + Acts::GeometryID volumeID(vid, Acts::GeometryID::volume_mask); + ACTS_VERBOSE("j2a: -> Found Volume " << vid); + // loop through the information in the volume + for (auto & [ vckey, vcvalue ] : vvalue.items()) { + if (vckey == m_cfg.boukey and m_cfg.processBoundaries + and not vcvalue.empty()) { + ACTS_VERBOSE("j2a: --> BoundarySurface(s) to be parsed"); + for (auto & [ bkey, bvalue ] : vcvalue.items()) { + // create the boundary id + int bid = std::stoi(bkey); + Acts::GeometryID boundaryID(volumeID); + boundaryID.add(bid, Acts::GeometryID::boundary_mask); + ACTS_VERBOSE("j2a: ---> Found boundary surface " << bid); + auto boumat = jsonToSurfaceMaterial(bvalue); + maps.first[boundaryID] + = std::shared_ptr<const Acts::ISurfaceMaterial>(boumat); + } + } else if (vckey == m_cfg.laykey) { + ACTS_VERBOSE("j2a: --> Layer(s) to be parsed"); + // now loop over layers + auto layj = vcvalue; + for (auto & [ lkey, lvalue ] : layj.items()) { + // create the layer id + int lid = std::stoi(lkey); + Acts::GeometryID layerID(volumeID); + layerID.add(lid, Acts::GeometryID::layer_mask); + ACTS_VERBOSE("j2a: ---> Found Layer " << lid); + // finally loop over layer components + for (auto & [ lckey, lcvalue ] : lvalue.items()) { + if (lckey == m_cfg.repkey and m_cfg.processRepresenting + and not lcvalue.empty()) { + ACTS_VERBOSE("j2a: ----> Found representing surface"); + auto repmat = jsonToSurfaceMaterial(lcvalue); + maps.first[layerID] + = std::shared_ptr<const Acts::ISurfaceMaterial>(repmat); + } else if (lckey == m_cfg.appkey and m_cfg.processApproaches + and not lcvalue.empty()) { + ACTS_VERBOSE("j2a: ----> Found approach surface(s)"); + // loop over approach surfaces + for (auto & [ askey, asvalue ] : lcvalue.items()) { + // create the layer id, todo set to max value + int aid = (askey == "*") ? 0 : std::stoi(askey); + Acts::GeometryID approachID(layerID); + approachID.add(aid, Acts::GeometryID::approach_mask); + ACTS_VERBOSE("j2a: -----> Approach surface " << askey); + auto appmat = jsonToSurfaceMaterial(asvalue); + maps.first[approachID] + = std::shared_ptr<const Acts::ISurfaceMaterial>(appmat); + } + } else if (lckey == m_cfg.senkey and m_cfg.processSensitives + and not lcvalue.empty()) { + ACTS_VERBOSE("j2a: ----> Found sensitive surface(s)"); + // loop over sensitive surfaces + for (auto & [ sskey, ssvalue ] : lcvalue.items()) { + // create the layer id, todo set to max value + int sid = (sskey == "*") ? 0 : std::stoi(sskey); + Acts::GeometryID senisitiveID(layerID); + senisitiveID.add(sid, Acts::GeometryID::sensitive_mask); + ACTS_VERBOSE("j2a: -----> Sensitive surface " << sskey); + auto senmat = jsonToSurfaceMaterial(ssvalue); + maps.first[senisitiveID] + = std::shared_ptr<const Acts::ISurfaceMaterial>(senmat); + } + } + } + } + + } else if (vckey == m_cfg.matkey and not vcvalue.empty()) { + ACTS_VERBOSE("--> VolumeMaterial to be parsed"); + } + } + } + } else if (key == m_cfg.geoversion) { + ACTS_VERBOSE("Detector version: " << m_cfg.geoversion); + } + } + + // Return the filled maps + return maps; +} + +/// Convert method +/// +json +FW::Json::JsonGeometryConverter::materialMapsToJson( + const Acts::DetectorMaterialMaps& maps) +{ + DetectorRep detRep; + // Collect all GeometryIDs per VolumeID for the formatted output + for (auto & [ key, value ] : maps.first) { + geo_id_value vid = key.value(Acts::GeometryID::volume_mask); + auto volRep = detRep.volumes.find(vid); + if (volRep == detRep.volumes.end()) { + detRep.volumes.insert({vid, VolumeRep()}); + volRep = detRep.volumes.find(vid); + volRep->second.volumeID = key; + } + geo_id_value lid = key.value(Acts::GeometryID::layer_mask); + if (lid != 0) { + // we are on a layer, get the layer rep + auto layRep = volRep->second.layers.find(lid); + if (layRep == volRep->second.layers.end()) { + volRep->second.layers.insert({lid, LayerRep()}); + layRep = volRep->second.layers.find(lid); + layRep->second.layerID = key; + } + // now insert appropriately + geo_id_value sid = key.value(Acts::GeometryID::sensitive_mask); + geo_id_value aid = key.value(Acts::GeometryID::approach_mask); + if (sid != 0) { + layRep->second.sensitives.insert({sid, value.get()}); + } else if (aid != 0) { + layRep->second.approaches.insert({aid, value.get()}); + } else { + layRep->second.representing = value.get(); + } + + } else { + // not on a layer can only be a boundary surface + geo_id_value bid = key.value(Acts::GeometryID::boundary_mask); + volRep->second.boundaries.insert({bid, value.get()}); + } + } + for (auto & [ key, value ] : maps.second) { + // find the volume representation + geo_id_value vid = key.value(Acts::GeometryID::volume_mask); + auto volRep = detRep.volumes.find(vid); + if (volRep == detRep.volumes.end()) { + detRep.volumes.insert({vid, VolumeRep()}); + volRep = detRep.volumes.find(vid); + volRep->second.volumeID = key; + } + volRep->second.material = value.get(); + } + // convert the detector representation to json format + return detectorRepToJson(detRep); +} + +/// Create Json from a detector represenation +json +FW::Json::JsonGeometryConverter::detectorRepToJson(const DetectorRep& detRep) +{ + json detectorj; + ACTS_VERBOSE("a2j: Writing json from detector representation"); + ACTS_VERBOSE("a2j: Found entries for " << detRep.volumes.size() + << " volume(s)."); + + json volumesj; + for (auto & [ key, value ] : detRep.volumes) { + json volj; + ACTS_VERBOSE("a2j: -> Writing Volume: " << key); + volj[m_cfg.namekey] = value.volumeName; + // write the layers + if (not value.layers.empty()) { + ACTS_VERBOSE("a2j: ---> Found " << value.layers.size() << " layer(s) "); + json layersj; + for (auto & [ lkey, lvalue ] : value.layers) { + ACTS_VERBOSE("a2j: ----> Convert layer " << lkey); + json layj; + // first check for approaches + if (not lvalue.approaches.empty() and m_cfg.processApproaches) { + ACTS_VERBOSE("a2j: -----> Found " << lvalue.approaches.size() + << " approach surface(s)"); + json approachesj; + for (auto & [ akey, avalue ] : lvalue.approaches) { + ACTS_VERBOSE("a2j: ------> Convert approach surface " << akey); + approachesj[std::to_string(akey)] = surfaceMaterialToJson(*avalue); + } + // add to the layer json + layj[m_cfg.appkey] = approachesj; + } + // then check for sensitive + if (not lvalue.sensitives.empty() and m_cfg.processSensitives) { + ACTS_VERBOSE("a2j: -----> Found " << lvalue.sensitives.size() + << " sensitive surface(s)"); + json sensitivesj; + for (auto & [ skey, svalue ] : lvalue.sensitives) { + ACTS_VERBOSE("a2j: ------> Convert sensitive surface " << skey); + sensitivesj[std::to_string(skey)] = surfaceMaterialToJson(*svalue); + } + // add to the layer json + layj[m_cfg.senkey] = sensitivesj; + } + // finally check for representing + if (lvalue.representing != nullptr and m_cfg.processRepresenting) { + ACTS_VERBOSE("a2j: ------> Convert representing surface "); + layj[m_cfg.repkey] = surfaceMaterialToJson(*lvalue.representing); + } + layersj[std::to_string(lkey)] = layj; + } + volj[m_cfg.laykey] = layersj; + } + + volumesj[std::to_string(key)] = volj; + } + + detectorj[m_cfg.volkey] = volumesj; + + return detectorj; +} + +/// Create the Surface Material +const Acts::ISurfaceMaterial* +FW::Json::JsonGeometryConverter::jsonToSurfaceMaterial(const json& material) +{ + + Acts::ISurfaceMaterial* sMaterial = nullptr; + // The bin utility for deescribing the data + Acts::BinUtility bUtility; + // Convert the material + Acts::MaterialPropertiesMatrix mpMatrix; + // Structured binding + for (auto & [ key, value ] : material.items()) { + // Check json keys + if (key == m_cfg.bin0key and not value.empty()) { + bUtility += jsonToBinUtility(value); + } else if (key == m_cfg.bin1key and not value.empty()) { + bUtility += jsonToBinUtility(value); + } + if (key == m_cfg.datakey and not value.empty()) { + mpMatrix = jsonToMaterialMatrix(value); + } + } + + // We have protoMaterial + if (mpMatrix.size() == 0) { + sMaterial = new Acts::ProtoSurfaceMaterial(bUtility); + } else if (bUtility.bins() == 1) { + sMaterial = new Acts::HomogeneousSurfaceMaterial(mpMatrix[0][0]); + } else { + sMaterial = new Acts::BinnedSurfaceMaterial(bUtility, mpMatrix); + } + // return what you have + return sMaterial; +} + +json +FW::Json::JsonGeometryConverter::trackingGeometryToJson( + const Acts::TrackingGeometry& tGeometry) +{ + DetectorRep detRep; + convertToRep(detRep, *tGeometry.highestTrackingVolume()); + return detectorRepToJson(detRep); +} + +void +FW::Json::JsonGeometryConverter::convertToRep( + DetectorRep& detRep, + const Acts::TrackingVolume& tVolume) +{ + // The writer reader volume representation + VolumeRep volRep; + // there are confined volumes + if (tVolume.confinedVolumes()) { + // get through the volumes + auto& volumes = tVolume.confinedVolumes()->arrayObjects(); + // loop over the volumes + for (auto& vol : volumes) { + // recursive call + convertToRep(detRep, *vol); + } + } + // write the material if there's one + if (tVolume.volumeMaterial() != nullptr) { + volRep.material = tVolume.volumeMaterial(); + } + // there are confied layers + if (tVolume.confinedLayers()) { + // get the layers + auto& layers = tVolume.confinedLayers()->arrayObjects(); + // loop of the volumes + for (auto& lay : layers) { + auto layRep = convertToRep(*lay); + if (layRep) { + // it's a valid representation so let's go with it + Acts::GeometryID layerID = lay->geoID(); + geo_id_value lid = layerID.value(Acts::GeometryID::layer_mask); + volRep.layers.insert({lid, std::move(layRep)}); + } + } + } + // Let's finally check the boundaries + for (auto& bsurf : tVolume.boundarySurfaces()) { + // the surface representation + auto& bssfRep = bsurf->surfaceRepresentation(); + if (bssfRep.surfaceMaterial()) { + Acts::GeometryID boundaryID = bssfRep.geoID(); + geo_id_value bid = boundaryID.value(Acts::GeometryID::boundary_mask); + volRep.boundaries[bid] = bssfRep.surfaceMaterial(); + } + } + // Write if it's good + if (volRep) { + Acts::GeometryID volumeID = tVolume.geoID(); + volRep.volumeName = tVolume.volumeName(); + volRep.volumeID = volumeID; + geo_id_value vid = volumeID.value(Acts::GeometryID::volume_mask); + detRep.volumes.insert({vid, std::move(volRep)}); + } + return; +} + +FW::Json::LayerRep +FW::Json::JsonGeometryConverter::convertToRep(const Acts::Layer& layer) +{ + LayerRep layRep; + // fill layer ID information + layRep.layerID = layer.geoID(); + if (m_cfg.processSensitives and layer.surfaceArray() != nullptr) { + for (auto& ssf : layer.surfaceArray()->surfaces()) { + if (ssf != nullptr && ssf->surfaceMaterial()) { + Acts::GeometryID sensitiveID = ssf->geoID(); + geo_id_value sid = sensitiveID.value(Acts::GeometryID::sensitive_mask); + layRep.sensitives.insert({sid, ssf->surfaceMaterial()}); + } + } + } + // the representing + if (layer.surfaceRepresentation().surfaceMaterial() != nullptr) { + layRep.representing = layer.surfaceRepresentation().surfaceMaterial(); + } + // the approach + if (layer.approachDescriptor() != nullptr) { + for (auto& asf : layer.approachDescriptor()->containedSurfaces()) { + // get the surface and check for material + if (asf->surfaceMaterial() != nullptr) { + Acts::GeometryID approachID = asf->geoID(); + geo_id_value aid = approachID.value(Acts::GeometryID::approach_mask); + layRep.approaches.insert({aid, asf->surfaceMaterial()}); + } + } + } + // return the layer representation + return layRep; +} + +json +FW::Json::JsonGeometryConverter::surfaceMaterialToJson( + const Acts::ISurfaceMaterial& sMaterial) +{ + + json smj; + + // lemma 0 : accept the surface + auto convertMaterialProperties + = [](const Acts::MaterialProperties& mp) -> std::vector<float> { + // convert when ready + if (mp) { + /// Return the thickness in mm + return { + mp.averageX0(), + mp.averageL0(), + mp.averageZ(), + mp.averageA(), + mp.averageRho(), + mp.thickness(), + }; + } + return {}; + }; + + // if a bin utility is to be written + const Acts::BinUtility* bUtility = nullptr; + // check if we have a proto material + auto psMaterial = dynamic_cast<const Acts::ProtoSurfaceMaterial*>(&sMaterial); + if (psMaterial != nullptr) { + // type is proto + smj[m_cfg.typekey] = "proto"; + bUtility = &(psMaterial->binUtility()); + } else { + // now check if we have a homogeneous material + auto hsMaterial + = dynamic_cast<const Acts::HomogeneousSurfaceMaterial*>(&sMaterial); + if (hsMaterial != nullptr) { + // type is homogeneous + smj[m_cfg.typekey] = "homogeneous"; + if (m_cfg.writeData) { + // write out the data, it's a [[[X0,L0,Z,A,rho,thickness]]] + auto& mp = hsMaterial->materialProperties(0, 0); + std::vector<std::vector<std::vector<float>>> mmat + = {{convertMaterialProperties(mp)}}; + smj[m_cfg.datakey] = mmat; + } + } else { + // only option remaining: BinnedSurface material + // now check if we have a homogeneous material + auto bsMaterial + = dynamic_cast<const Acts::BinnedSurfaceMaterial*>(&sMaterial); + if (bsMaterial != nullptr) { + // type is binned + smj[m_cfg.typekey] = "binned"; + bUtility = &(bsMaterial->binUtility()); + // convert the data + // get the material matrix + if (m_cfg.writeData) { + auto& mpMatrix = bsMaterial->fullMaterial(); + std::vector<std::vector<std::vector<float>>> mmat; + mmat.reserve(mpMatrix.size()); + for (auto& mpVector : mpMatrix) { + std::vector<std::vector<float>> mvec; + mvec.reserve(mpVector.size()); + for (auto& mp : mpVector) { + mvec.push_back(convertMaterialProperties(mp)); + } + mmat.push_back(std::move(mvec)); + } + smj[m_cfg.datakey] = mmat; + } + } + } + } + // add the bin utility + if (bUtility != nullptr) { + std::vector<std::string> binkeys = {m_cfg.bin0key, m_cfg.bin1key}; + // loop over dimensions and write + auto& binningData = bUtility->binningData(); + // loop over the dimensions + for (size_t ibin = 0; ibin < binningData.size(); ++ibin) { + json binj; + auto cbData = binningData[ibin]; + binj.push_back(Acts::binningValueNames[cbData.binvalue]); + if (cbData.option == Acts::closed) { + binj.push_back("closed"); + } else { + binj.push_back("open"); + } + binj.push_back(cbData.bins()); + smj[binkeys[ibin]] = binj; + } + } + + return smj; +} + +/// Create the Material Matrix +Acts::MaterialPropertiesMatrix +FW::Json::JsonGeometryConverter::jsonToMaterialMatrix(const json& data) +{ + Acts::MaterialPropertiesMatrix mpMatrix; + /// This is assumed to be an array or array of array[6] + for (auto& outer : data) { + Acts::MaterialPropertiesVector mpVector; + for (auto& inner : outer) { + if (inner.size() > 5) { + mpVector.push_back(Acts::MaterialProperties( + inner[0], inner[1], inner[2], inner[3], inner[4], inner[5])); + } else { + mpVector.push_back(Acts::MaterialProperties()); + } + } + mpMatrix.push_back(std::move(mpVector)); + } + return mpMatrix; +} + +/// Create the BinUtility for this +Acts::BinUtility +FW::Json::JsonGeometryConverter::jsonToBinUtility(const json& bin) +{ + // finding the iterator position to determine the binning value + auto bit = std::find( + Acts::binningValueNames.begin(), Acts::binningValueNames.end(), bin[0]); + size_t indx = std::distance(Acts::binningValueNames.begin(), bit); + Acts::BinningValue bval = Acts::BinningValue(indx); + Acts::BinningOption bopt = bin[1] == "open" ? Acts::open : Acts::closed; + unsigned int bins = bin[2]; + double min, max = 0; + if (bin[3].size() == 2) { + min = bin[3][0]; + max = bin[3][1]; + } + return Acts::BinUtility(bins, min, max, bopt, bval); +} diff --git a/Plugins/Json/src/JsonMaterialWriter.cpp b/Plugins/Json/src/JsonMaterialWriter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f760060d6d2b0bef4f8b45b920eb64209578b80f --- /dev/null +++ b/Plugins/Json/src/JsonMaterialWriter.cpp @@ -0,0 +1,53 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "ACTFW/Plugins/Json/JsonMaterialWriter.hpp" +#include <fstream> +#include <ios> +#include <iostream> +#include <stdexcept> +#include "Acts/Material/BinnedSurfaceMaterial.hpp" +#include "Acts/Utilities/GeometryID.hpp" + +FW::Json::JsonMaterialWriter::JsonMaterialWriter( + const FW::Json::JsonGeometryConverter::Config& cfg, + const std::string& fileName) + : m_cfg(cfg), m_fileName(fileName) +{ + // Validate the configuration + if (m_cfg.name.empty()) { + throw std::invalid_argument("Missing service name"); + } +} + +FW::Json::JsonMaterialWriter::~JsonMaterialWriter() +{ +} + +void +FW::Json::JsonMaterialWriter::write( + const Acts::DetectorMaterialMaps& detMaterial) +{ + // Evoke the converter + FW::Json::JsonGeometryConverter jmConverter(m_cfg); + auto jout = jmConverter.materialMapsToJson(detMaterial); + // And write the file + std::ofstream ofj(m_fileName); + ofj << std::setw(4) << jout << std::endl; +} + +void +FW::Json::JsonMaterialWriter::write(const Acts::TrackingGeometry& tGeometry) +{ + // Evoke the converter + FW::Json::JsonGeometryConverter jmConverter(m_cfg); + auto jout = jmConverter.trackingGeometryToJson(tGeometry); + // And write the file + std::ofstream ofj(m_fileName); + ofj << std::setw(4) << jout << std::endl; +} diff --git a/Plugins/Obj/src/ObjTrackingGeometryWriter.cpp b/Plugins/Obj/src/ObjTrackingGeometryWriter.cpp index 5df6a763b6e1ada45d8f36fcfbbb6d82520a5917..4e17c80670f5c731f911b588e91895ca2d230806 100644 --- a/Plugins/Obj/src/ObjTrackingGeometryWriter.cpp +++ b/Plugins/Obj/src/ObjTrackingGeometryWriter.cpp @@ -75,14 +75,14 @@ FW::Obj::ObjTrackingGeometryWriter::write(const AlgorithmContext& context, // layer prefix surfaceWriter->write(m_cfg.layerPrefix); // try to write the material surface as well - if (layer->surfaceRepresentation().associatedMaterial()) { + if (layer->surfaceRepresentation().surfaceMaterial()) { surfaceWriter->write(context, layer->surfaceRepresentation()); } // the the approaching surfaces and check if they have material if (layer->approachDescriptor()) { // loop over the contained Surfaces for (auto& cSurface : layer->approachDescriptor()->containedSurfaces()) - if (cSurface->associatedMaterial()) { + if (cSurface->surfaceMaterial()) { surfaceWriter->write(context, *cSurface); } } diff --git a/Plugins/Root/CMakeLists.txt b/Plugins/Root/CMakeLists.txt index 13b387f52e264fdc60a98cce90208bf8ee45b15f..a5dee1ce40d0d6b121b16591911ee326be6635a3 100644 --- a/Plugins/Root/CMakeLists.txt +++ b/Plugins/Root/CMakeLists.txt @@ -1,8 +1,12 @@ -set(sources - src/RootParticleWriter.cpp - src/RootPlanarClusterWriter.cpp - src/RootPropagationStepsWriter.cpp - src/RootSimHitWriter.cpp) +set(sources src/RootMaterialDecorator.cpp + src/RootMaterialWriter.cpp + src/RootMaterialTrackReader.cpp + src/RootMaterialTrackWriter.cpp + src/RootPlanarClusterWriter.cpp + src/RootParticleWriter.cpp + src/RootPropagationStepsWriter.cpp + src/RootSimHitWriter.cpp + ) add_library(ACTFWRootPlugin SHARED ${sources}) target_include_directories( diff --git a/Plugins/Root/include/ACTFW/Plugins/Root/RootExCellWriter.hpp b/Plugins/Root/include/ACTFW/Plugins/Root/RootExCellWriter.hpp deleted file mode 100644 index 535b9c4c50c7b984b868de3717887cbc4b6f26a0..0000000000000000000000000000000000000000 --- a/Plugins/Root/include/ACTFW/Plugins/Root/RootExCellWriter.hpp +++ /dev/null @@ -1,130 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2017-2018 Acts project team -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#pragma once - -#include <TFile.h> -#include <TTree.h> -#include <mutex> -#include "ACTFW/Framework/IService.hpp" -#include "ACTFW/Framework/ProcessCode.hpp" -#include "ACTFW/Framework/WriterT.hpp" -#include "Acts/Extrapolation/ExtrapolationCell.hpp" -#include "Acts/Utilities/Logger.hpp" - -namespace FW { - -namespace Root { - - /// @class ExtrapolationCellWriter - /// - /// A root based implementation to write out extrapolation steps. - /// This is the Legacy equivalent of the PropgationSteps writer. - /// - /// The event number is part of the written data. - /// - /// A common file can be provided for to the writer to attach his TTree, - /// this is done by setting the Config::rootFile pointer to an existing file - /// - /// @tparam parameters_t Type of the track parameters - /// - /// Safe to use from multiple writer threads - uses a std::mutex lock. - template <typename parameters_t> - class RootExCellWriter - : public FW::WriterT<std::vector<Acts::ExtrapolationCell<parameters_t>>> - { - public: - using Base - = FW::WriterT<std::vector<Acts::ExtrapolationCell<parameters_t>>>; - - using FW::WriterT<std::vector<Acts::ExtrapolationCell<parameters_t>>>:: - logger; - - /// @struct ExtrapolationStep - /// this holds the information to be written out - struct ExtrapolationStep - { - float x, y, z; ///< position (global) - float px, py, pz; ///< momentum - float type; ///< type of the step - }; - - /// @brief The nested config class - struct Config - { - public: - std::string collection; ///< particle collection to write - std::string filePath; ///< path of the output file - std::string fileMode = "RECREATE"; ///< file access mode - std::string treeName - = "extrapolation_cells"; ///< name of the output tree - TFile* rootFile = nullptr; ///< common root file - bool writeSensitive = true; ///< indiciation to write out sensitive - bool writeMaterial = true; ///< indiciation to write out material - bool writePassive = true; ///< indiciation to write out passive - bool writeBoundary = true; ///< indiciation to write out boundary - unsigned int reservedSteps = 100; ///< number of steps to be expected - }; - - /// Constructor - /// @param cfg is the configuration class - /// @param level The log level of the writer - RootExCellWriter(const Config& cfg, - Acts::Logging::Level level = Acts::Logging::INFO); - - /// Virtual destructor - ~RootExCellWriter() override; - - /// End-of-run hook - ProcessCode - endRun() final override; - - protected: - /// The protected writeT method, called by the WriterT base - /// - /// @tparam parameters_t Type of the parameters object - /// - /// @param [in] context is the algorithm context for event consistency - /// @param [in] ecells are the celss to be written out - ProcessCode - writeT(const FW::AlgorithmContext& context, - const std::vector<Acts::ExtrapolationCell<parameters_t>>& ecells) - final override; - - Config m_cfg; ///< the config class - std::mutex m_writeMutex; ///< protect multi-threaded writes - TFile* m_outputFile{nullptr}; ///< the output file - TTree* m_outputTree{nullptr}; ///< the output tree - int m_eventNr; ///< the event number of - float m_eta; ///< global eta start - float m_phi; ///< global phi start - float m_materialX0; ///< material in X0 - float m_materialL0; ///< material in L0 - std::vector<float> m_s_positionX; ///< global position x of the step - std::vector<float> m_s_positionY; ///< global position y of the step - std::vector<float> m_s_positionZ; ///< global position z of the step - std::vector<float> m_s_positionR; ///< global position z of the step - std::vector<float> m_s_materialX0; ///< step material X0 - std::vector<float> m_s_materialL0; ///< step material L0 - std::vector<int> m_s_material; ///< type of the step: material - std::vector<int> m_s_boundary; ///< type of the step: boundary - std::vector<int> m_s_sensitive; ///< type of the step: sensitive - std::vector<int> m_s_volumeID; ///< volume identification - std::vector<int> m_s_layerID; ///< layer identification - std::vector<int> m_s_surfaceID; ///< surface identification - std::vector<float> - m_s_localposition0; ///< local position - first coordinate - std::vector<float> - m_s_localposition1; ///< local position - second coordinate - int m_hits; ///< number of hits in sensitive material - }; - -} // namespace Root -} // namespace FW - -#include "RootExCellWriter.ipp" diff --git a/Plugins/Root/include/ACTFW/Plugins/Root/RootExCellWriter.ipp b/Plugins/Root/include/ACTFW/Plugins/Root/RootExCellWriter.ipp deleted file mode 100644 index f48611ac47705837d01213475e9efe0975d29f68..0000000000000000000000000000000000000000 --- a/Plugins/Root/include/ACTFW/Plugins/Root/RootExCellWriter.ipp +++ /dev/null @@ -1,241 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2017 Acts project team -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include <ios> -#include <stdexcept> -#include "Acts/Utilities/Helpers.hpp" - -#include "Acts/Utilities/Helpers.hpp" - -template <typename parameters_t> -FW::ProcessCode -FW::Root::RootExCellWriter<parameters_t>::writeT( - const FW::AlgorithmContext& context, - const std::vector<Acts::ExtrapolationCell<parameters_t>>& ecells) -{ - - // Exclusive access to the tree while writing - std::lock_guard<std::mutex> lock(m_writeMutex); - // Get the event number - m_eventNr = context.eventNumber; - - const unsigned int reservedSteps = m_cfg.reservedSteps; - - // loop over all the extrapolation cells - for (auto& eCell : ecells) { - // the event paramters - auto sMomentum = eCell.startParameters->momentum(); - m_eta = Acts::VectorHelpers::eta(sMomentum); - m_phi = Acts::VectorHelpers::phi(sMomentum); - m_materialX0 = eCell.materialX0; - m_materialL0 = eCell.materialL0; - - // clear the vectors & reserve - // - for main step information - m_s_positionX.clear(); - m_s_positionY.clear(); - m_s_positionZ.clear(); - m_s_positionR.clear(); - m_s_volumeID.clear(); - m_s_layerID.clear(); - m_s_surfaceID.clear(); - m_s_positionX.reserve(reservedSteps); - m_s_positionY.reserve(reservedSteps); - m_s_positionZ.reserve(reservedSteps); - m_s_positionR.reserve(reservedSteps); - m_s_volumeID.reserve(reservedSteps); - m_s_layerID.reserve(reservedSteps); - m_s_surfaceID.reserve(reservedSteps); - - // - for the sensitive - if (m_cfg.writeSensitive) { - m_s_sensitive.clear(); - m_s_localposition0.clear(); - m_s_localposition1.clear(); - m_s_sensitive.reserve(reservedSteps); - m_s_localposition0.reserve(reservedSteps); - m_s_localposition1.reserve(reservedSteps); - } - // - for the material - if (m_cfg.writeMaterial) { - m_s_material.clear(); - m_s_materialX0.clear(); - m_s_materialL0.clear(); - m_s_material.reserve(reservedSteps); - m_s_materialX0.reserve(reservedSteps); - m_s_materialL0.reserve(reservedSteps); - } - // - for the boundary - if (m_cfg.writeBoundary) { - m_s_boundary.clear(); - m_s_boundary.reserve(reservedSteps); - } - // the number of sensitive hits per event - m_hits = 0; - // loop over extrapolation steps - for (auto& es : eCell.extrapolationSteps) { - if (es.parameters) { - /// step parameters - const parameters_t& pars = (*es.parameters); - /// type information - int material = es.configuration.checkMode( - Acts::ExtrapolationMode::CollectMaterial); - int boundary = es.configuration.checkMode( - Acts::ExtrapolationMode::CollectBoundary); - int sensitive = es.configuration.checkMode( - Acts::ExtrapolationMode::CollectSensitive); - int passive = es.configuration.checkMode( - Acts::ExtrapolationMode::CollectPassive); - - /// check the layer, surface, volume ID - geo_id_value volumeID = pars.referenceSurface().geoID().value( - Acts::GeometryID::volume_mask); - geo_id_value layerID = pars.referenceSurface().geoID().value( - Acts::GeometryID::layer_mask); - geo_id_value surfaceID = pars.referenceSurface().geoID().value( - Acts::GeometryID::sensitive_mask); - /// - if ((m_cfg.writeSensitive && sensitive) - || (m_cfg.writeBoundary && boundary) - || (m_cfg.writeMaterial && material) - || (m_cfg.writePassive && passive)) { - - // the material steps - if (m_cfg.writeMaterial) { - // the material is being written out - double materialStepX0 = 0.; - double materialStepL0 = 0.; - if (es.material) { - // assign the material - materialStepX0 = es.materialScaling * es.material.thicknessInX0(); - materialStepX0 = es.materialScaling * es.material.thicknessInL0(); - } - m_s_materialX0.push_back(materialStepX0); - m_s_materialX0.push_back(materialStepL0); - } - - /// goblal position information - m_s_positionX.push_back(pars.position().x()); - m_s_positionY.push_back(pars.position().y()); - m_s_positionZ.push_back(pars.position().z()); - m_s_positionR.push_back(Acts::VectorHelpers::perp(pars.position())); - - /// local position information - only makes sense for sensitive really - if (m_cfg.writeSensitive) { - m_s_localposition0.push_back(pars.parameters()[Acts::eLOC_X]); - m_s_localposition1.push_back(pars.parameters()[Acts::eLOC_Y]); - } - /// volume, layer and surface ID - m_s_volumeID.push_back(volumeID); - m_s_layerID.push_back(layerID); - m_s_surfaceID.push_back(surfaceID); - /// indicate what hit you have - m_s_material.push_back(material); - m_s_boundary.push_back(boundary); - m_s_sensitive.push_back(sensitive); - } - if (sensitive) m_hits++; - } - } - m_outputTree->Fill(); - } - // return scuess - return FW::ProcessCode::SUCCESS; -} - -template <typename parameters_t> -FW::Root::RootExCellWriter<parameters_t>::RootExCellWriter( - const FW::Root::RootExCellWriter<parameters_t>::Config& cfg, - Acts::Logging::Level level) - : FW::WriterT<std::vector<Acts::ExtrapolationCell<parameters_t>>>( - cfg.collection, - "RootExCellWriter", - level) - , m_cfg(cfg) - , m_outputFile(cfg.rootFile) -{ - // Validate the configuration - if (m_cfg.collection.empty()) { - throw std::invalid_argument("Missing input collection"); - } else if (m_cfg.treeName.empty()) { - throw std::invalid_argument("Missing tree name"); - } - - // Setup ROOT I/O - if (m_outputFile == nullptr) { - m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str()); - if (m_outputFile == nullptr) { - throw std::ios_base::failure("Could not open '" + m_cfg.filePath); - } - m_outputFile->cd(); - } - m_outputTree - = new TTree(m_cfg.treeName.c_str(), "TTree from RootPlanarClusterWriter"); - if (!m_outputTree) throw std::bad_alloc(); - - // Event parameters - m_outputTree->Branch("event_nr", &m_eventNr); - - // Initial parameters - m_outputTree->Branch("eta", &m_eta); - m_outputTree->Branch("phi", &m_phi); - - // Output the step information - m_outputTree->Branch("step_x", &m_s_positionX); - m_outputTree->Branch("step_y", &m_s_positionY); - m_outputTree->Branch("step_z", &m_s_positionZ); - m_outputTree->Branch("step_r", &m_s_positionR); - - // Identification - m_outputTree->Branch("volumeID", &m_s_volumeID); - m_outputTree->Branch("layerID", &m_s_layerID); - m_outputTree->Branch("surfaceID", &m_s_surfaceID); - - // Material section - if (m_cfg.writeMaterial) { - m_outputTree->Branch("material_X0", &m_materialX0); - m_outputTree->Branch("material_L0", &m_materialL0); - m_outputTree->Branch("step_material_X0", &m_s_materialX0); - m_outputTree->Branch("step_material_L0", &m_s_materialL0); - m_outputTree->Branch("material", &m_s_material); - } - - // Sensitive section - if (m_cfg.writeSensitive) { - m_outputTree->Branch("sensitive", &m_s_sensitive); - m_outputTree->Branch("step_l0", &m_s_localposition0); - m_outputTree->Branch("step_l1", &m_s_localposition1); - } - - // Boundary section - if (m_cfg.writeBoundary) m_outputTree->Branch("boundary", &m_s_boundary); - - // Number of sensitive hits - m_outputTree->Branch("hits", &m_hits); -} - -template <typename parameters_t> -FW::Root::RootExCellWriter<parameters_t>::~RootExCellWriter() -{ - // Only close the root file that you created yourself - if (m_cfg.rootFile == nullptr) { - m_outputFile->Close(); - } -} - -template <typename parameters_t> -FW::ProcessCode -FW::Root::RootExCellWriter<parameters_t>::endRun() -{ - m_outputFile->cd(); - m_outputTree->Write(); - ACTS_VERBOSE("Wrote particles to tree '" << m_cfg.treeName << "' in '" - << m_cfg.filePath - << "'"); - return ProcessCode::SUCCESS; -} diff --git a/Plugins/Root/include/ACTFW/Plugins/Root/RootMaterialDecorator.hpp b/Plugins/Root/include/ACTFW/Plugins/Root/RootMaterialDecorator.hpp new file mode 100644 index 0000000000000000000000000000000000000000..695927cc29a4b55c41131250cc75b6bdfb95aa36 --- /dev/null +++ b/Plugins/Root/include/ACTFW/Plugins/Root/RootMaterialDecorator.hpp @@ -0,0 +1,165 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include <map> +#include <mutex> +#include "ACTFW/Framework/ProcessCode.hpp" +#include "Acts/Detector/TrackingVolume.hpp" +#include "Acts/Material/IMaterialDecorator.hpp" +#include "Acts/Material/ISurfaceMaterial.hpp" +#include "Acts/Material/IVolumeMaterial.hpp" +#include "Acts/Surfaces/Surface.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/GeometryID.hpp" +#include "Acts/Utilities/Logger.hpp" + +class TFile; + +namespace Acts { + +using SurfaceMaterialMap + = std::map<GeometryID, std::shared_ptr<const ISurfaceMaterial>>; + +using VolumeMaterialMap + = std::map<GeometryID, std::shared_ptr<const IVolumeMaterial>>; +} + +namespace FW { + +namespace Root { + + /// @class RootMaterialDecorator + /// + /// @brief Read the collection of SurfaceMaterial & VolumeMaterial + class RootMaterialDecorator : public Acts::IMaterialDecorator + { + public: + /// @class Config + /// Configuration of the Reader + class Config + { + public: + /// The name of the output tree + std::string folderNameBase = "Material"; + /// The volume identification string + std::string voltag = "_vol"; + /// The layer identification string + std::string laytag = "_lay"; + /// The approach identification string + std::string apptag = "_app"; + /// The sensitive identification string + std::string sentag = "_sen"; + /// The bin number tag + std::string ntag = "n"; + /// The value tag -> binning values: binZ, binR, binPhi, etc. + std::string vtag = "v"; + /// The option tag -> binning options: open, closed + std::string otag = "o"; + /// The range min tag: min value + std::string mintag = "min"; + /// The range max tag: max value + std::string maxtag = "max"; + /// The thickness tag + std::string ttag = "t"; + /// The x0 tag + std::string x0tag = "x0"; + /// The l0 tag + std::string l0tag = "l0"; + /// The A tag + std::string atag = "A"; + /// The Z tag + std::string ztag = "Z"; + /// The rho tag + std::string rhotag = "rho"; + /// The name of the output file + std::string fileName = "material-maps.root"; + /// The default logger + std::shared_ptr<const Acts::Logger> logger; + // The name of the writer + std::string name = ""; + + /// Constructor + /// + /// @param lname Name of the writer tool + /// @param lvl The output logging level + Config(const std::string& lname = "MaterialReader", + Acts::Logging::Level lvl = Acts::Logging::INFO) + : logger(Acts::getDefaultLogger(lname, lvl)), name(lname) + { + } + }; + + /// Constructor + /// + /// @param cfg configuration struct for the reader + RootMaterialDecorator(const Config& cfg); + + /// Destructor + ~RootMaterialDecorator(); + + /// Decorate a surface + /// + /// @param surface the non-cost surface that is decorated + void + decorate(Acts::Surface& surface) const final + { + // Null out the material for this surface + if (m_clearSurfaceMaterial) { + surface.assignSurfaceMaterial(nullptr); + } + // Try to find the surface in the map + auto sMaterial = m_surfaceMaterialMap.find(surface.geoID()); + if (sMaterial != m_surfaceMaterialMap.end()) { + surface.assignSurfaceMaterial(sMaterial->second); + } + } + + /// Decorate a TrackingVolume + /// + /// @param volume the non-cost volume that is decorated + void + decorate(Acts::TrackingVolume& volume) const final + { + // Null out the material for this volume + if (m_clearSurfaceMaterial) { + volume.assignVolumeMaterial(nullptr); + } + // Try to find the surface in the map + auto vMaterial = m_volumeMaterialMap.find(volume.geoID()); + if (vMaterial != m_volumeMaterialMap.end()) { + volume.assignVolumeMaterial(vMaterial->second); + } + } + + private: + /// The config class + Config m_cfg; + + /// The input file + TFile* m_inputFile{nullptr}; + + /// Surface based material + Acts::SurfaceMaterialMap m_surfaceMaterialMap; + + /// Volume based material + Acts::VolumeMaterialMap m_volumeMaterialMap; + + bool m_clearSurfaceMaterial{true}; + bool m_clearVolumeMaterial{true}; + + /// Private access to the logging instance + const Acts::Logger& + logger() const + { + return *m_cfg.logger; + } + }; +} // namespace Root +} // namespace FW diff --git a/Plugins/Root/include/ACTFW/Plugins/Root/RootMaterialTrackReader.hpp b/Plugins/Root/include/ACTFW/Plugins/Root/RootMaterialTrackReader.hpp new file mode 100644 index 0000000000000000000000000000000000000000..079934852e553ad8a4436e93b1f3123fd62e7708 --- /dev/null +++ b/Plugins/Root/include/ACTFW/Plugins/Root/RootMaterialTrackReader.hpp @@ -0,0 +1,151 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include <mutex> +#include <vector> +#include "ACTFW/Framework/IReader.hpp" +#include "ACTFW/Framework/IService.hpp" +#include "ACTFW/Framework/ProcessCode.hpp" +#include "Acts/Extrapolator/MaterialInteractor.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/Logger.hpp" + +class TChain; + +namespace FW { + +namespace Root { + + /// @class RootMaterialTrackReader + /// + /// @brief Reads in MaterialTrack information from a root file + /// and fills it into a format to be understood by the MaterialMapping + /// algorithm + class RootMaterialTrackReader : public IReader + { + public: + /// @brief The nested configuration struct + struct Config + { + std::string collection + = "material-tracks"; ///< material collection to read + std::string filePath = ""; ///< path of the output file + std::string treeName = "material-tracks"; ///< name of the output tree + std::vector<std::string> fileList; ///< The name of the input file + + unsigned int batchSize = 1; ///!< The number of tracks per event + + /// The default logger + std::shared_ptr<const Acts::Logger> logger; + + /// The name of the service + std::string name; + + /// Constructor + /// @param lname The name of the Material reader + /// @parqam lvl The log level for the logger + Config(const std::string& lname = "MaterialReader", + Acts::Logging::Level lvl = Acts::Logging::INFO) + : logger(Acts::getDefaultLogger(lname, lvl)), name(lname) + { + } + }; + + /// Constructor + /// @param cfg The Configuration struct + RootMaterialTrackReader(const Config& cfg); + + /// Destructor + ~RootMaterialTrackReader(); + + /// Framework name() method + std::string + name() const final override; + + /// Skip a few events in the IO stream + /// @param [in] nEvents is the number of skipped events + ProcessCode + skip(size_t nEvents) final override; + + /// Read out data from the input stream + /// + /// @param context The algorithm context + ProcessCode + read(const FW::AlgorithmContext& context) final override; + + /// Return the number of events + virtual size_t + numEvents() const final override; + + private: + /// Private access to the logging instance + const Acts::Logger& + logger() const + { + return *m_cfg.logger; + } + + /// The config class + Config m_cfg; + + /// mutex used to protect multi-threaded reads + std::mutex m_read_mutex; + + /// The number of events + size_t m_events = 0; + + /// The input tree name + TChain* m_inputChain = nullptr; + + float m_v_x; ///< start global x + float m_v_y; ///< start global y + float m_v_z; ///< start global z + float m_v_px; ///< start global momentum x + float m_v_py; ///< start global momentum y + float m_v_pz; ///< start global momentum z + float m_v_phi; ///< start phi direction + float m_v_eta; ///< start eta direction + float m_tX0; ///< thickness in X0/L0 + float m_tL0; ///< thickness in X0/L0 + + std::vector<float>* m_step_x = new std::vector<float>; ///< step x position + std::vector<float>* m_step_y = new std::vector<float>; ///< step y position + std::vector<float>* m_step_z = new std::vector<float>; ///< step z position + std::vector<float>* m_step_length + = new std::vector<float>; ///< step length + std::vector<float>* m_step_X0 + = new std::vector<float>; ///< step material x0 + std::vector<float>* m_step_L0 + = new std::vector<float>; ///< step material l0 + std::vector<float>* m_step_A = new std::vector<float>; ///< step material A + std::vector<float>* m_step_Z = new std::vector<float>; ///< step material Z + std::vector<float>* m_step_rho + = new std::vector<float>; ///< step material rho + }; + + inline std::string + RootMaterialTrackReader::name() const + { + return m_cfg.name; + } + + inline size_t + RootMaterialTrackReader::numEvents() const + { + return m_events; + } + + inline ProcessCode RootMaterialTrackReader::skip(size_t /*nEvents*/) + { + return ProcessCode::SUCCESS; + } + +} // namespace Root +} // namespace FW diff --git a/Plugins/Root/include/ACTFW/Plugins/Root/RootMaterialTrackWriter.hpp b/Plugins/Root/include/ACTFW/Plugins/Root/RootMaterialTrackWriter.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a529739c1439f7cb43a906c1bc5f41367f29207a --- /dev/null +++ b/Plugins/Root/include/ACTFW/Plugins/Root/RootMaterialTrackWriter.hpp @@ -0,0 +1,118 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include <mutex> +#include "ACTFW/Framework/IService.hpp" +#include "ACTFW/Framework/ProcessCode.hpp" +#include "ACTFW/Framework/WriterT.hpp" +#include "Acts/Extrapolator/MaterialInteractor.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "TTree.h" + +namespace Acts { +// Using some short hands for Recorded Material +using RecordedMaterial = MaterialInteractor::result_type; + +// And recorded material track +// - this is start: position, start momentum +// and the Recorded material +using RecordedMaterialTrack + = std::pair<std::pair<Acts::Vector3D, Acts::Vector3D>, RecordedMaterial>; +} + +namespace FW { + +namespace Root { + + /// @class RootMaterialTrackWriter + /// + /// @brief Writes out MaterialTrack collections from a root file + /// + /// This service is the root implementation of the IWriterT. + /// It writes out a MaterialTrack which is usually generated from + /// Geant4 material mapping + class RootMaterialTrackWriter + : public WriterT<std::vector<Acts::RecordedMaterialTrack>> + { + public: + using Base = WriterT<std::vector<Acts::RecordedMaterialTrack>>; + + /// @brief The nested configuration struct + struct Config + { + std::string collection + = "material-tracks"; ///< material collection to write + std::string filePath = ""; ///< path of the output file + std::string fileMode = "RECREATE"; ///< file access mode + std::string treeName = "material-tracks"; ///< name of the output tree + TFile* rootFile = nullptr; ///< common root file + + /// Re-calculate total values from individual steps (for cross-checks) + bool recalculateTotals = false; + }; + + /// Constructor with + /// @param cfg configuration struct + /// @param output logging level + RootMaterialTrackWriter(const Config& cfg, + Acts::Logging::Level level = Acts::Logging::INFO); + + /// Virtual destructor + ~RootMaterialTrackWriter() override; + + /// Framework intialize method + FW::ProcessCode + endRun() final override; + + protected: + // This implementation holds the actual writing method + /// and is called by the WriterT<>::write interface + /// + /// @param ctx The Algorithm context with per event information + /// @param clusters is the data to be written out + ProcessCode + writeT(const AlgorithmContext& ctx, + const std::vector<Acts::RecordedMaterialTrack>& materialtracks) + final override; + + private: + /// The config class + Config m_cfg; + /// mutex used to protect multi-threaded writes + std::mutex m_writeMutex; + /// The output file name + TFile* m_outputFile; + /// The output tree name + TTree* m_outputTree; + + float m_v_x; ///< start global x + float m_v_y; ///< start global y + float m_v_z; ///< start global z + float m_v_px; ///< start global momentum x + float m_v_py; ///< start global momentum y + float m_v_pz; ///< start global momentum z + float m_v_phi; ///< start phi direction + float m_v_eta; ///< start eta direction + float m_tX0; ///< thickness in X0/L0 + float m_tL0; ///< thickness in X0/L0 + + std::vector<float> m_step_x; ///< step x position + std::vector<float> m_step_y; ///< step y position + std::vector<float> m_step_z; ///< step z position + std::vector<float> m_step_length; ///< step length + std::vector<float> m_step_X0; ///< step material x0 + std::vector<float> m_step_L0; ///< step material l0 + std::vector<float> m_step_A; ///< step material A + std::vector<float> m_step_Z; ///< step material Z + std::vector<float> m_step_rho; ///< step material rho + }; + +} // namespace Root +} // namespace FW diff --git a/Plugins/Root/include/ACTFW/Plugins/Root/RootMaterialWriter.hpp b/Plugins/Root/include/ACTFW/Plugins/Root/RootMaterialWriter.hpp new file mode 100644 index 0000000000000000000000000000000000000000..88bd721b3eb5ba85c68b1458ce6dc6c5598be81d --- /dev/null +++ b/Plugins/Root/include/ACTFW/Plugins/Root/RootMaterialWriter.hpp @@ -0,0 +1,175 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2019 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/////////////////////////////////////////////////////////////////// +// RootMaterialWriter.h +/////////////////////////////////////////////////////////////////// + +#pragma once + +#include <map> +#include <mutex> +#include "ACTFW/Framework/ProcessCode.hpp" +#include "Acts/Detector/TrackingGeometry.hpp" +#include "Acts/Detector/TrackingVolume.hpp" +#include "Acts/Material/IMaterialDecorator.hpp" +#include "Acts/Material/ISurfaceMaterial.hpp" +#include "Acts/Material/IVolumeMaterial.hpp" +#include "Acts/Surfaces/Surface.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/GeometryID.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "TFile.h" + +namespace Acts { + +using SurfaceMaterialMap + = std::map<GeometryID, std::shared_ptr<const ISurfaceMaterial>>; + +using VolumeMaterialMap + = std::map<GeometryID, std::shared_ptr<const IVolumeMaterial>>; + +using DetectorMaterialMaps = std::pair<SurfaceMaterialMap, VolumeMaterialMap>; +} + +namespace FW { + +namespace Root { + + /// @brief Material decorator from Root format + /// + /// This reads in material maps for surfaces and volumes + /// from a root file + class RootMaterialWriter + { + + public: + /// @class Config + /// + /// Configuration of the Writer + struct Config + { + + /// Steering to handle sensitive data + bool processSensitives = true; + + /// Steering to handle approach data + bool processApproaches = true; + + /// Steering to handle representing data + bool processRepresenting = true; + + /// Steering to handle boundary data + bool processBoundaries = true; + + /// Steering to handle volume data + bool processVolumes = true; + + /// The name of the output tree + std::string folderNameBase = "Material"; + /// The volume identification string + std::string voltag = "_vol"; + /// The layer identification string + std::string laytag = "_lay"; + /// The approach identification string + std::string apptag = "_app"; + /// The sensitive identification string + std::string sentag = "_sen"; + /// The bin number tag + std::string ntag = "n"; + /// The value tag -> binning values: binZ, binR, binPhi, etc. + std::string vtag = "v"; + /// The option tag -> binning options: open, closed + std::string otag = "o"; + /// The range min tag: min value + std::string mintag = "min"; + /// The range max tag: max value + std::string maxtag = "max"; + /// The thickness tag + std::string ttag = "t"; + /// The x0 tag + std::string x0tag = "x0"; + /// The l0 tag + std::string l0tag = "l0"; + /// The A tag + std::string atag = "A"; + /// The Z tag + std::string ztag = "Z"; + /// The rho tag + std::string rhotag = "rho"; + /// The name of the output file + std::string fileName = "material-maps.root"; + /// The default logger + std::shared_ptr<const Acts::Logger> logger; + // The name of the writer + std::string name = ""; + + /// Constructor + /// + /// @param lname Name of the writer tool + /// @param lvl The output logging level + Config(const std::string& lname = "RootMaterialWriter", + Acts::Logging::Level lvl = Acts::Logging::INFO) + : logger(Acts::getDefaultLogger(lname, lvl)), name(lname) + { + } + }; + + /// Constructor + /// + /// @param cfg The configuration struct + RootMaterialWriter(const Config& cfg); + + /// Virtual destructor + ~RootMaterialWriter(); + + /// Write out the material map + /// + /// @param detMaterial is the SurfaceMaterial and VolumeMaterial maps + void + write(const Acts::DetectorMaterialMaps& detMaterial); + + /// Write out the material map from Geometry + /// + /// @param tGeometry is the TrackingGeometry + void + write(const Acts::TrackingGeometry& tGeometry); + + private: + /// Collect the material from the tracking geometry + /// + /// @param tVolume The TrackingVolume for the material to be collected + /// @param [in,out] detMatMap the map to be filled + void + collectMaterial(const Acts::TrackingVolume& tVolume, + Acts::DetectorMaterialMaps& detMatMap); + + /// Collect the material from the tracking geometry + /// + /// @param tLayer The TrackingVolume for the material to be collected + /// @param [in,out] detMatMap the map to be filled + void + collectMaterial(const Acts::Layer& tLayer, + Acts::DetectorMaterialMaps& detMatMap); + + /// The config class + Config m_cfg; + + /// The output file name + TFile* m_outputFile; + + /// Private access to the logging instance + const Acts::Logger& + logger() const + { + return *m_cfg.logger; + } + }; + +} // namespace Root +} // namespace FW diff --git a/Plugins/Root/src/RootMaterialDecorator.cpp b/Plugins/Root/src/RootMaterialDecorator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..45cfac91208387ddd1670fd9102ea7d3b96ebcb0 --- /dev/null +++ b/Plugins/Root/src/RootMaterialDecorator.cpp @@ -0,0 +1,190 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2018 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "ACTFW/Plugins/Root/RootMaterialDecorator.hpp" +#include <boost/algorithm/string.hpp> +#include <boost/algorithm/string/finder.hpp> +#include <boost/algorithm/string/iter_find.hpp> +#include <cstdio> +#include <iostream> +#include <sstream> +#include <stdexcept> +#include <string> +#include "Acts/Material/BinnedSurfaceMaterial.hpp" +#include "Acts/Material/HomogeneousSurfaceMaterial.hpp" +#include "Acts/Utilities/BinUtility.hpp" +#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/GeometryID.hpp" +#include "TFile.h" +#include "TH2F.h" +#include "TIterator.h" +#include "TKey.h" +#include "TList.h" + +FW::Root::RootMaterialDecorator::RootMaterialDecorator( + const FW::Root::RootMaterialDecorator::Config& cfg) + : m_cfg(cfg), m_inputFile(nullptr) +{ + // Validate the configuration + if (m_cfg.folderNameBase.empty()) { + throw std::invalid_argument("Missing ROOT folder name"); + } else if (m_cfg.fileName.empty()) { + throw std::invalid_argument("Missing file name"); + } else if (!m_cfg.logger) { + throw std::invalid_argument("Missing logger"); + } else if (m_cfg.name.empty()) { + throw std::invalid_argument("Missing service name"); + } + + // Setup ROOT I/O + m_inputFile = TFile::Open(m_cfg.fileName.c_str()); + if (!m_inputFile) { + throw std::ios_base::failure("Could not open '" + m_cfg.fileName); + } + + // Get the list of keys from the file + TList* tlist = m_inputFile->GetListOfKeys(); + auto tIter = tlist->MakeIterator(); + tIter->Reset(); + + // Iterate over the keys in the file + while (TKey* key = (TKey*)(tIter->Next())) { + + // The surface material to be read in for this + std::shared_ptr<const Acts::ISurfaceMaterial> sMaterial = nullptr; + + // Remember the directory + std::string tdName(key->GetName()); + + ACTS_VERBOSE("Processing directory: " << tdName); + + // volume + std::vector<std::string> splitNames; + iter_split( + splitNames, tdName, boost::algorithm::first_finder(m_cfg.voltag)); + boost::split(splitNames, splitNames[1], boost::is_any_of("_")); + geo_id_value volID = std::stoi(splitNames[0]); + // layer + iter_split( + splitNames, tdName, boost::algorithm::first_finder(m_cfg.laytag)); + boost::split(splitNames, splitNames[1], boost::is_any_of("_")); + geo_id_value layID = std::stoi(splitNames[0]); + // approach + iter_split( + splitNames, tdName, boost::algorithm::first_finder(m_cfg.apptag)); + boost::split(splitNames, splitNames[1], boost::is_any_of("_")); + geo_id_value appID = std::stoi(splitNames[0]); + // sensitive + iter_split( + splitNames, tdName, boost::algorithm::first_finder(m_cfg.sentag)); + geo_id_value senID = std::stoi(splitNames[1]); + + // Reconstruct the geometry ID + Acts::GeometryID geoID(volID, Acts::GeometryID::volume_mask); + geoID.add(layID, Acts::GeometryID::layer_mask); + geoID.add(appID, Acts::GeometryID::approach_mask); + geoID.add(senID, Acts::GeometryID::sensitive_mask); + ACTS_VERBOSE("GeometryID re-constructed as " << geoID.toString()); + + // Construct the names + std::string nName = tdName + "/" + m_cfg.ntag; + std::string vName = tdName + "/" + m_cfg.vtag; + std::string oName = tdName + "/" + m_cfg.otag; + std::string minName = tdName + "/" + m_cfg.mintag; + std::string maxName = tdName + "/" + m_cfg.maxtag; + std::string tName = tdName + "/" + m_cfg.ttag; + std::string x0Name = tdName + "/" + m_cfg.x0tag; + std::string l0Name = tdName + "/" + m_cfg.l0tag; + std::string aName = tdName + "/" + m_cfg.atag; + std::string zName = tdName + "/" + m_cfg.ztag; + std::string rhoName = tdName + "/" + m_cfg.rhotag; + + // Get the histograms + TH1F* n = dynamic_cast<TH1F*>(m_inputFile->Get(nName.c_str())); + TH1F* v = dynamic_cast<TH1F*>(m_inputFile->Get(vName.c_str())); + TH1F* o = dynamic_cast<TH1F*>(m_inputFile->Get(oName.c_str())); + TH1F* min = dynamic_cast<TH1F*>(m_inputFile->Get(minName.c_str())); + TH1F* max = dynamic_cast<TH1F*>(m_inputFile->Get(maxName.c_str())); + TH2F* t = dynamic_cast<TH2F*>(m_inputFile->Get(tName.c_str())); + TH2F* x0 = dynamic_cast<TH2F*>(m_inputFile->Get(x0Name.c_str())); + TH2F* l0 = dynamic_cast<TH2F*>(m_inputFile->Get(l0Name.c_str())); + TH2F* A = dynamic_cast<TH2F*>(m_inputFile->Get(aName.c_str())); + TH2F* Z = dynamic_cast<TH2F*>(m_inputFile->Get(zName.c_str())); + TH2F* rho = dynamic_cast<TH2F*>(m_inputFile->Get(rhoName.c_str())); + + // Only go on when you have all histograms + if (n and v and o and min and max and t and x0 and l0 and A and Z and rho) { + + // Get the number of bins + int nbins0 = t->GetNbinsX(); + int nbins1 = t->GetNbinsY(); + + // The material matrix + Acts::MaterialPropertiesMatrix materialMatrix( + nbins1, + Acts::MaterialPropertiesVector(nbins0, Acts::MaterialProperties())); + + // We need binned material properties + if (nbins0 * nbins1 > 1) { + // Fill the matrix first + for (int ib0 = 1; ib0 <= nbins0; ++ib0) { + for (int ib1 = 1; ib1 <= nbins1; ++ib1) { + double dt = t->GetBinContent(ib0, ib1); + if (dt > 0.) { + double dx0 = x0->GetBinContent(ib0, ib1); + double dl0 = l0->GetBinContent(ib0, ib1); + double da = A->GetBinContent(ib0, ib1); + double dz = Z->GetBinContent(ib0, ib1); + double drho = rho->GetBinContent(ib0, ib1); + // Create material properties + materialMatrix[ib1 - 1][ib0 - 1] + = Acts::MaterialProperties(dx0, dl0, da, dz, drho, dt); + } + } + } + + // Now reconstruct the bin untilities + Acts::BinUtility bUtility; + for (size_t ib = 1; ib < n->GetNbinsX() + 1; ++ib) { + size_t nbins = size_t(n->GetBinContent(ib)); + Acts::BinningValue val = Acts::BinningValue(v->GetBinContent(ib)); + Acts::BinningOption opt = Acts::BinningOption(o->GetBinContent(ib)); + float rmin = min->GetBinContent(ib); + float rmax = max->GetBinContent(ib); + bUtility += Acts::BinUtility(nbins, rmin, rmax, opt, val); + } + ACTS_VERBOSE("Created " << bUtility); + + // Construct the binned material with the right bin utility + sMaterial = std::make_shared<const Acts::BinnedSurfaceMaterial>( + bUtility, std::move(materialMatrix)); + + } else { + // Only homogeneous material present + double dt = t->GetBinContent(1, 1); + double dx0 = x0->GetBinContent(1, 1); + double dl0 = l0->GetBinContent(1, 1); + double da = A->GetBinContent(1, 1); + double dz = Z->GetBinContent(1, 1); + double drho = rho->GetBinContent(1, 1); + // Create and set the homogenous surface material + sMaterial = std::make_shared<const Acts::HomogeneousSurfaceMaterial>( + Acts::MaterialProperties(dx0, dl0, da, dz, drho, dt)); + } + } + ACTS_VERBOSE("Successfully read Material for : " << geoID.toString()); + + // Insert into the new collection + m_surfaceMaterialMap.insert({geoID, std::move(sMaterial)}); + } +} + +FW::Root::RootMaterialDecorator::~RootMaterialDecorator() +{ + m_inputFile->Close(); +} diff --git a/Plugins/Root/src/RootMaterialTrackReader.cpp b/Plugins/Root/src/RootMaterialTrackReader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..42d4b157ca8e4281949ba4d005e53bdc77f0f92d --- /dev/null +++ b/Plugins/Root/src/RootMaterialTrackReader.cpp @@ -0,0 +1,126 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2018 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "ACTFW/Plugins/Root/RootMaterialTrackReader.hpp" +#include <iostream> +#include "ACTFW/Framework/WhiteBoard.hpp" +#include "TChain.h" +#include "TFile.h" + +FW::Root::RootMaterialTrackReader::RootMaterialTrackReader( + const FW::Root::RootMaterialTrackReader::Config& cfg) + : FW::IReader(), m_cfg(cfg), m_events(0), m_inputChain(nullptr) +{ + m_inputChain = new TChain(m_cfg.treeName.c_str()); + + // Set the branches + m_inputChain->SetBranchAddress("v_x", &m_v_x); + m_inputChain->SetBranchAddress("v_y", &m_v_y); + m_inputChain->SetBranchAddress("v_z", &m_v_z); + m_inputChain->SetBranchAddress("v_px", &m_v_px); + m_inputChain->SetBranchAddress("v_py", &m_v_py); + m_inputChain->SetBranchAddress("v_pz", &m_v_pz); + m_inputChain->SetBranchAddress("v_phi", &m_v_phi); + m_inputChain->SetBranchAddress("v_eta", &m_v_eta); + m_inputChain->SetBranchAddress("t_X0", &m_tX0); + m_inputChain->SetBranchAddress("t_L0", &m_tL0); + m_inputChain->SetBranchAddress("mat_x", &m_step_x); + m_inputChain->SetBranchAddress("mat_y", &m_step_y); + m_inputChain->SetBranchAddress("mat_z", &m_step_z); + m_inputChain->SetBranchAddress("mat_step_length", &m_step_length); + m_inputChain->SetBranchAddress("mat_X0", &m_step_X0); + m_inputChain->SetBranchAddress("mat_L0", &m_step_L0); + m_inputChain->SetBranchAddress("mat_A", &m_step_A); + m_inputChain->SetBranchAddress("mat_Z", &m_step_Z); + m_inputChain->SetBranchAddress("mat_rho", &m_step_rho); + + // loop over the input files + for (auto inputFile : m_cfg.fileList) { + // add file to the input chain + m_inputChain->Add(inputFile.c_str()); + ACTS_DEBUG("Adding File " << inputFile << " to tree '" << m_cfg.treeName + << "'."); + } + + m_events = m_inputChain->GetEntries(); + ACTS_DEBUG("The full chain has " << m_events << " entries."); +} + +FW::Root::RootMaterialTrackReader::~RootMaterialTrackReader() +{ + + delete m_step_x; + delete m_step_y; + delete m_step_z; + delete m_step_length; + delete m_step_X0; + delete m_step_L0; + delete m_step_A; + delete m_step_Z; + delete m_step_rho; +} + +FW::ProcessCode +FW::Root::RootMaterialTrackReader::read(const FW::AlgorithmContext& context) +{ + + ACTS_DEBUG("Trying to read recorded material from tracks."); + // read in the material track + if (m_inputChain && context.eventNumber < m_events) { + // lock the mutex + std::lock_guard<std::mutex> lock(m_read_mutex); + // now read + + // The collection to be written + std::vector<Acts::RecordedMaterialTrack> mtrackCollection; + + for (size_t ib = 0; ib < m_cfg.batchSize; ++ib) { + + // Read the correct entry: batch size * event_number + ib + m_inputChain->GetEntry(m_cfg.batchSize * context.eventNumber + ib); + ACTS_VERBOSE("Reading entry: " << m_cfg.batchSize * context.eventNumber + + ib); + + Acts::RecordedMaterialTrack rmTrack; + // Fill the position and momentum + rmTrack.first.first = Acts::Vector3D(m_v_x, m_v_y, m_v_z); + rmTrack.first.second = Acts::Vector3D(m_v_px, m_v_py, m_v_pz); + + // Fill the individual steps + size_t msteps = m_step_length->size(); + ACTS_VERBOSE("Reading " << msteps << " material steps."); + rmTrack.second.materialInteractions.reserve(msteps); + rmTrack.second.materialInX0 = 0.; + rmTrack.second.materialInL0 = 0.; + + for (size_t is = 0; is < msteps; ++is) { + + double mX0 = (*m_step_X0)[is]; + double mL0 = (*m_step_L0)[is]; + double s = (*m_step_length)[is]; + + rmTrack.second.materialInX0 += s / mX0; + rmTrack.second.materialInL0 += s / mL0; + + /// Fill the position & the material + Acts::MaterialInteraction mInteraction; + mInteraction.position + = Acts::Vector3D((*m_step_x)[is], (*m_step_y)[is], (*m_step_z)[is]); + mInteraction.materialProperties = Acts::MaterialProperties( + mX0, mL0, (*m_step_A)[is], (*m_step_Z)[is], (*m_step_rho)[is], s); + rmTrack.second.materialInteractions.push_back(std::move(mInteraction)); + } + mtrackCollection.push_back(std::move(rmTrack)); + } + + // Write to the collection to the EventStore + context.eventStore.add(m_cfg.collection, std::move(mtrackCollection)); + } + // Return success flag + return FW::ProcessCode::SUCCESS; +} diff --git a/Plugins/Root/src/RootMaterialTrackWriter.cpp b/Plugins/Root/src/RootMaterialTrackWriter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9de5388dca45cc61190e3eeac1c7d140699e21ea --- /dev/null +++ b/Plugins/Root/src/RootMaterialTrackWriter.cpp @@ -0,0 +1,165 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2018 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "ACTFW/Plugins/Root/RootMaterialTrackWriter.hpp" + +#include <ios> +#include <iostream> +#include <stdexcept> + +#include "TFile.h" + +#include "Acts/Utilities/Helpers.hpp" + +using Acts::VectorHelpers::eta; +using Acts::VectorHelpers::phi; +using Acts::VectorHelpers::perp; + +FW::Root::RootMaterialTrackWriter::RootMaterialTrackWriter( + const FW::Root::RootMaterialTrackWriter::Config& cfg, + Acts::Logging::Level level) + : Base(cfg.collection, "RootMaterialTrackWriter", level) + , m_cfg(cfg) + , m_outputFile(cfg.rootFile) +{ + // An input collection name and tree name must be specified + if (m_cfg.collection.empty()) { + throw std::invalid_argument("Missing input collection"); + } else if (m_cfg.treeName.empty()) { + throw std::invalid_argument("Missing tree name"); + } + + // Setup ROOT I/O + if (m_outputFile == nullptr) { + m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str()); + if (m_outputFile == nullptr) { + throw std::ios_base::failure("Could not open '" + m_cfg.filePath); + } + } + m_outputFile->cd(); + m_outputTree + = new TTree(m_cfg.treeName.c_str(), "TTree from RootMaterialTrackWriter"); + if (m_outputTree == nullptr) throw std::bad_alloc(); + + // Set the branches + m_outputTree->Branch("v_x", &m_v_x); + m_outputTree->Branch("v_y", &m_v_y); + m_outputTree->Branch("v_z", &m_v_z); + m_outputTree->Branch("v_px", &m_v_px); + m_outputTree->Branch("v_py", &m_v_py); + m_outputTree->Branch("v_pz", &m_v_pz); + m_outputTree->Branch("v_phi", &m_v_phi); + m_outputTree->Branch("v_eta", &m_v_eta); + m_outputTree->Branch("t_X0", &m_tX0); + m_outputTree->Branch("t_L0", &m_tL0); + m_outputTree->Branch("mat_x", &m_step_x); + m_outputTree->Branch("mat_y", &m_step_y); + m_outputTree->Branch("mat_z", &m_step_z); + m_outputTree->Branch("mat_step_length", &m_step_length); + m_outputTree->Branch("mat_X0", &m_step_X0); + m_outputTree->Branch("mat_L0", &m_step_L0); + m_outputTree->Branch("mat_A", &m_step_A); + m_outputTree->Branch("mat_Z", &m_step_Z); + m_outputTree->Branch("mat_rho", &m_step_rho); +} + +FW::Root::RootMaterialTrackWriter::~RootMaterialTrackWriter() +{ + m_outputFile->Close(); +} + +FW::ProcessCode +FW::Root::RootMaterialTrackWriter::endRun() +{ + // write the tree and close the file + ACTS_INFO("Writing ROOT output File : " << m_cfg.filePath); + m_outputFile->cd(); + m_outputTree->Write(); + return FW::ProcessCode::SUCCESS; +} + +FW::ProcessCode +FW::Root::RootMaterialTrackWriter::writeT( + const AlgorithmContext& ctx, + const std::vector<Acts::RecordedMaterialTrack>& materialTracks) +{ + // Exclusive access to the tree while writing + std::lock_guard<std::mutex> lock(m_writeMutex); + + // loop over the material tracks and write them out + for (auto& mtrack : materialTracks) { + + // clearing the vector first + m_step_x.clear(); + m_step_y.clear(); + m_step_z.clear(); + m_step_length.clear(); + m_step_X0.clear(); + m_step_L0.clear(); + m_step_A.clear(); + m_step_Z.clear(); + m_step_rho.clear(); + + // reserve the vector then + size_t mints = mtrack.second.materialInteractions.size(); + m_step_x.reserve(mints); + m_step_y.reserve(mints); + m_step_z.reserve(mints); + m_step_length.reserve(mints); + m_step_X0.reserve(mints); + m_step_L0.reserve(mints); + m_step_A.reserve(mints); + m_step_Z.reserve(mints); + m_step_rho.reserve(mints); + + // reset the global counter + if (m_cfg.recalculateTotals) { + m_tX0 = 0.; + m_tL0 = 0.; + } else { + m_tX0 = mtrack.second.materialInX0; + m_tL0 = mtrack.second.materialInL0; + } + + // set the track information at vertex + m_v_x = mtrack.first.first.x(); + m_v_y = mtrack.first.first.y(); + m_v_z = mtrack.first.first.z(); + m_v_px = mtrack.first.second.x(); + m_v_py = mtrack.first.second.y(); + m_v_pz = mtrack.first.second.z(); + m_v_phi = phi(mtrack.first.second); + m_v_eta = eta(mtrack.first.second); + + // an now loop over the material + for (auto& mint : mtrack.second.materialInteractions) { + // the material step position information + m_step_x.push_back(mint.position.x()); + m_step_y.push_back(mint.position.y()); + m_step_z.push_back(mint.position.z()); + // the material information + const auto& mprops = mint.materialProperties; + m_step_length.push_back(mprops.thickness()); + m_step_X0.push_back(mprops.averageX0()); + m_step_L0.push_back(mprops.averageL0()); + m_step_A.push_back(mprops.averageA()); + m_step_Z.push_back(mprops.averageZ()); + m_step_rho.push_back(mprops.averageRho()); + // re-calculate if defined to do so + if (m_cfg.recalculateTotals) { + m_tX0 += mprops.thicknessInX0(); + m_tL0 += mprops.thicknessInL0(); + } + } + // write to + m_outputTree->Fill(); + } + + // return success + return FW::ProcessCode::SUCCESS; +} diff --git a/Plugins/Root/src/RootMaterialWriter.cpp b/Plugins/Root/src/RootMaterialWriter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a00523d42d6b373e07ddc42efa2aaebd7ea5bf51 --- /dev/null +++ b/Plugins/Root/src/RootMaterialWriter.cpp @@ -0,0 +1,296 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2018 Acts project team +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "ACTFW/Plugins/Root/RootMaterialWriter.hpp" +#include <ios> +#include <iostream> +#include <stdexcept> +#include "Acts/Material/BinnedSurfaceMaterial.hpp" +#include "Acts/Utilities/GeometryID.hpp" +#include "TFile.h" +#include "TH2F.h" + +FW::Root::RootMaterialWriter::RootMaterialWriter( + const FW::Root::RootMaterialWriter::Config& cfg) + : m_cfg(cfg), m_outputFile(nullptr) +{ + // Validate the configuration + if (m_cfg.folderNameBase.empty()) { + throw std::invalid_argument("Missing folder name base"); + } else if (m_cfg.fileName.empty()) { + throw std::invalid_argument("Missing file name"); + } else if (!m_cfg.logger) { + throw std::invalid_argument("Missing logger"); + } else if (m_cfg.name.empty()) { + throw std::invalid_argument("Missing service name"); + } + + // Setup ROOT I/O + m_outputFile = TFile::Open(m_cfg.fileName.c_str(), "recreate"); + if (!m_outputFile) { + throw std::ios_base::failure("Could not open '" + m_cfg.fileName); + } +} + +FW::Root::RootMaterialWriter::~RootMaterialWriter() +{ + m_outputFile->Close(); +} + +void +FW::Root::RootMaterialWriter::write( + const Acts::DetectorMaterialMaps& detMaterial) +{ + + // Change to the output file + m_outputFile->cd(); + + auto& surfaceMaps = detMaterial.first; + for (auto & [ key, value ] : surfaceMaps) { + + // Get the Surface material + const Acts::ISurfaceMaterial* sMaterial = value.get(); + + // get the geometry ID + Acts::GeometryID geoID = key; + // decode the geometryID + geo_id_value gvolID = geoID.value(Acts::GeometryID::volume_mask); + geo_id_value glayID = geoID.value(Acts::GeometryID::layer_mask); + geo_id_value gappID = geoID.value(Acts::GeometryID::approach_mask); + geo_id_value gsenID = geoID.value(Acts::GeometryID::sensitive_mask); + // create the directory + std::string tdName = m_cfg.folderNameBase.c_str(); + tdName += m_cfg.voltag + std::to_string(gvolID); + tdName += m_cfg.laytag + std::to_string(glayID); + tdName += m_cfg.apptag + std::to_string(gappID); + tdName += m_cfg.sentag + std::to_string(gsenID); + // create a new directory + m_outputFile->mkdir(tdName.c_str()); + m_outputFile->cd(tdName.c_str()); + + ACTS_VERBOSE("Writing out map at " << tdName); + + size_t bins0 = 1, bins1 = 1; + // understand what sort of material you have in mind + const Acts::BinnedSurfaceMaterial* bsm + = dynamic_cast<const Acts::BinnedSurfaceMaterial*>(sMaterial); + if (bsm) { + // overwrite the bin numbers + bins0 = bsm->binUtility().bins(0); + bins1 = bsm->binUtility().bins(1); + + // Get the binning data + auto& binningData = bsm->binUtility().binningData(); + // 1-D or 2-D maps + size_t binningBins = binningData.size(); + + // The bin number information + TH1F* n = new TH1F(m_cfg.ntag.c_str(), + "bins; bin", + binningBins, + -0.5, + binningBins - 0.5); + + // The binning value information + TH1F* v = new TH1F(m_cfg.vtag.c_str(), + "binning values; bin", + binningBins, + -0.5, + binningBins - 0.5); + + // The binning option information + TH1F* o = new TH1F(m_cfg.otag.c_str(), + "binning options; bin", + binningBins, + -0.5, + binningBins - 0.5); + + // The binning option information + TH1F* min = new TH1F(m_cfg.mintag.c_str(), + "min; bin", + binningBins, + -0.5, + binningBins - 0.5); + + // The binning option information + TH1F* max = new TH1F(m_cfg.maxtag.c_str(), + "max; bin", + binningBins, + -0.5, + binningBins - 0.5); + + // Now fill the histogram content + size_t b = 1; + for (auto bData : binningData) { + // Fill: nbins, value, option, min, max + n->SetBinContent(b, int(binningData[b - 1].bins())); + v->SetBinContent(b, int(binningData[b - 1].binvalue)); + o->SetBinContent(b, int(binningData[b - 1].option)); + min->SetBinContent(b, binningData[b - 1].min); + max->SetBinContent(b, binningData[b - 1].max); + ++b; + } + n->Write(); + v->Write(); + o->Write(); + min->Write(); + max->Write(); + } + + TH2F* t = new TH2F(m_cfg.ttag.c_str(), + "thickness [mm] ;b0 ;b1", + bins0, + -0.5, + bins0 - 0.5, + bins1, + -0.5, + bins1 - 0.5); + TH2F* x0 = new TH2F(m_cfg.x0tag.c_str(), + "X_{0} [mm] ;b0 ;b1", + bins0, + -0.5, + bins0 - 0.5, + bins1, + -0.5, + bins1 - 0.5); + TH2F* l0 = new TH2F(m_cfg.l0tag.c_str(), + "#Lambda_{0} [mm] ;b0 ;b1", + bins0, + -0.5, + bins0 - 0.5, + bins1, + -0.5, + bins1 - 0.5); + TH2F* A = new TH2F(m_cfg.atag.c_str(), + "X_{0} [mm] ;b0 ;b1", + bins0, + -0.5, + bins0 - 0.5, + bins1, + -0.5, + bins1 - 0.5); + TH2F* Z = new TH2F(m_cfg.ztag.c_str(), + "#Lambda_{0} [mm] ;b0 ;b1", + bins0, + -0.5, + bins0 - 0.5, + bins1, + -0.5, + bins1 - 0.5); + TH2F* rho = new TH2F(m_cfg.rhotag.c_str(), + "#rho [g/mm^3] ;b0 ;b1", + bins0, + -0.5, + bins0 - 0.5, + bins1, + -0.5, + bins1 - 0.5); + + // loop over the material and fill + for (size_t b0 = 0; b0 < bins0; ++b0) { + for (size_t b1 = 0; b1 < bins1; ++b1) { + // get the material for the bin + auto& mat = sMaterial->materialProperties(b0, b1); + if (mat) { + t->SetBinContent(b0 + 1, b1 + 1, mat.thickness()); + x0->SetBinContent(b0 + 1, b1 + 1, mat.material().X0()); + l0->SetBinContent(b0 + 1, b1 + 1, mat.material().L0()); + A->SetBinContent(b0 + 1, b1 + 1, mat.material().A()); + Z->SetBinContent(b0 + 1, b1 + 1, mat.material().Z()); + rho->SetBinContent(b0 + 1, b1 + 1, mat.material().rho()); + } + } + } + t->Write(); + x0->Write(); + l0->Write(); + A->Write(); + Z->Write(); + rho->Write(); + } +} + +void +FW::Root::RootMaterialWriter::write(const Acts::TrackingGeometry& tGeometry) +{ + // Create a detector material map and loop recursively through it + Acts::DetectorMaterialMaps detMatMap; + auto hVolume = tGeometry.highestTrackingVolume(); + if (hVolume != nullptr) { + collectMaterial(*hVolume, detMatMap); + } + // Write the resulting map to the file + write(detMatMap); +} + +void +FW::Root::RootMaterialWriter::collectMaterial( + const Acts::TrackingVolume& tVolume, + Acts::DetectorMaterialMaps& detMatMap) +{ + + // If the volume has volume material, write that + if (tVolume.volumeMaterialPtr() != nullptr and m_cfg.processVolumes) { + detMatMap.second[tVolume.geoID()] = tVolume.volumeMaterialPtr(); + } + + // If confined layers exist, loop over them and collect the layer material + if (tVolume.confinedLayers() != nullptr) { + for (auto& lay : tVolume.confinedLayers()->arrayObjects()) { + collectMaterial(*lay, detMatMap); + } + } + + // If any of the boundary surfaces has material collect that + if (m_cfg.processBoundaries) { + for (auto& bou : tVolume.boundarySurfaces()) { + const auto& bSurface = bou->surfaceRepresentation(); + if (bSurface.surfaceMaterialPtr() != nullptr) { + detMatMap.first[bSurface.geoID()] = bSurface.surfaceMaterialPtr(); + } + } + } + + // If the volume has sub volumes, step down + if (tVolume.confinedVolumes() != nullptr) { + for (auto& tvol : tVolume.confinedVolumes()->arrayObjects()) { + collectMaterial(*tvol, detMatMap); + } + } +} + +void +FW::Root::RootMaterialWriter::collectMaterial( + const Acts::Layer& tLayer, + Acts::DetectorMaterialMaps& detMatMap) +{ + // If the representing surface has material, collect it + const auto& rSurface = tLayer.surfaceRepresentation(); + if (rSurface.surfaceMaterialPtr() != nullptr and m_cfg.processRepresenting) { + detMatMap.first[rSurface.geoID()] = rSurface.surfaceMaterialPtr(); + } + + // Check the approach surfaces + if (tLayer.approachDescriptor() != nullptr and m_cfg.processApproaches) { + for (auto& aSurface : tLayer.approachDescriptor()->containedSurfaces()) { + if (aSurface->surfaceMaterialPtr() != nullptr) { + detMatMap.first[aSurface->geoID()] = aSurface->surfaceMaterialPtr(); + } + } + } + + // Check the sensitive surfaces + if (tLayer.surfaceArray() != nullptr and m_cfg.processSensitives) { + // sensitive surface loop + for (auto& sSurface : tLayer.surfaceArray()->surfaces()) { + if (sSurface->surfaceMaterialPtr() != nullptr) { + detMatMap.first[sSurface->geoID()] = sSurface->surfaceMaterialPtr(); + } + } + } +} diff --git a/external/acts-core b/external/acts-core index e0ca76b4c611b77cf9f3c92a1825da25e516aca4..19d57d9646a3c5ad89a55ed7f6a8fe355e77d63a 160000 --- a/external/acts-core +++ b/external/acts-core @@ -1 +1 @@ -Subproject commit e0ca76b4c611b77cf9f3c92a1825da25e516aca4 +Subproject commit 19d57d9646a3c5ad89a55ed7f6a8fe355e77d63a diff --git a/external/acts-fatras b/external/acts-fatras index 167f6ba9be0f426e13530b086997f7f8fde0f8cf..826fd8dd88e50472947acf7184519582e13b9d7c 160000 --- a/external/acts-fatras +++ b/external/acts-fatras @@ -1 +1 @@ -Subproject commit 167f6ba9be0f426e13530b086997f7f8fde0f8cf +Subproject commit 826fd8dd88e50472947acf7184519582e13b9d7c