diff --git a/Algorithms/Vertexing/include/ACTFW/Vertexing/AdaptiveMultiVertexFinderAlgorithm.hpp b/Algorithms/Vertexing/include/ACTFW/Vertexing/AdaptiveMultiVertexFinderAlgorithm.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2b95c6b1aa05975365d916ec24e0167ffc738345 --- /dev/null +++ b/Algorithms/Vertexing/include/ACTFW/Vertexing/AdaptiveMultiVertexFinderAlgorithm.hpp @@ -0,0 +1,49 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2020 CERN for the benefit of the Acts project +// +// 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 <memory> + +#include "ACTFW/EventData/SimVertex.hpp" +#include "ACTFW/Framework/BareAlgorithm.hpp" +#include "ACTFW/Framework/ProcessCode.hpp" +#include "ACTFW/Framework/WhiteBoard.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Vertexing/FullBilloirVertexFitter.hpp" +#include "Acts/Vertexing/IterativeVertexFinder.hpp" + +namespace FWE { + +class AdaptiveMultiVertexFinderAlgorithm : public FW::BareAlgorithm { + public: + struct Config { + /// Input track collection + std::string trackCollection; + }; + + /// Constructor + AdaptiveMultiVertexFinderAlgorithm( + const Config& cfg, Acts::Logging::Level level = Acts::Logging::INFO); + + /// Framework execute method + /// @param [in] context is the Algorithm context for event consistency + FW::ProcessCode execute( + const FW::AlgorithmContext& context) const final override; + + private: + /// The config class + Config m_cfg; + + std::vector<Acts::BoundParameters> getInputTrackCollection( + const FW::AlgorithmContext& ctx) const; +}; + +} // namespace FWE \ No newline at end of file diff --git a/Algorithms/Vertexing/include/ACTFW/Vertexing/IterativeVertexFinderAlgorithm.hpp b/Algorithms/Vertexing/include/ACTFW/Vertexing/IterativeVertexFinderAlgorithm.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c86e6e47fab9094c3504a74b3a73b52245ab7368 --- /dev/null +++ b/Algorithms/Vertexing/include/ACTFW/Vertexing/IterativeVertexFinderAlgorithm.hpp @@ -0,0 +1,49 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2016-2019 CERN for the benefit of the Acts project +// +// 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 <memory> + +#include "ACTFW/EventData/SimVertex.hpp" +#include "ACTFW/Framework/BareAlgorithm.hpp" +#include "ACTFW/Framework/ProcessCode.hpp" +#include "ACTFW/Framework/WhiteBoard.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Vertexing/FullBilloirVertexFitter.hpp" +#include "Acts/Vertexing/IterativeVertexFinder.hpp" + +namespace FWE { + +class IterativeVertexFinderAlgorithm : public FW::BareAlgorithm { + public: + struct Config { + /// Input track collection + std::string trackCollection; + + /// The magnetic field + Acts::Vector3D bField; + }; + + /// Constructor + IterativeVertexFinderAlgorithm( + const Config& cfg, Acts::Logging::Level level = Acts::Logging::INFO); + + /// Framework execute method + /// @param [in] context is the Algorithm context for event consistency + FW::ProcessCode execute( + const FW::AlgorithmContext& context) const final override; + + private: + /// The config class + Config m_cfg; +}; + +} // namespace FWE \ No newline at end of file diff --git a/Algorithms/Vertexing/include/ACTFW/Vertexing/TutorialAMVFAlgorithm.hpp b/Algorithms/Vertexing/include/ACTFW/Vertexing/TutorialAMVFAlgorithm.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3e9614ff7946a2dcbc5fff83bda080abea1d28be --- /dev/null +++ b/Algorithms/Vertexing/include/ACTFW/Vertexing/TutorialAMVFAlgorithm.hpp @@ -0,0 +1,49 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2020 CERN for the benefit of the Acts project +// +// 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 <memory> + +#include "ACTFW/EventData/SimVertex.hpp" +#include "ACTFW/Framework/BareAlgorithm.hpp" +#include "ACTFW/Framework/ProcessCode.hpp" +#include "ACTFW/Framework/WhiteBoard.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Vertexing/FullBilloirVertexFitter.hpp" +#include "Acts/Vertexing/IterativeVertexFinder.hpp" + +namespace FWE { + +class TutorialAMVFAlgorithm : public FW::BareAlgorithm { + public: + struct Config { + /// Input track collection + std::string trackCollection; + }; + + /// Constructor + TutorialAMVFAlgorithm(const Config& cfg, + Acts::Logging::Level level = Acts::Logging::INFO); + + /// Framework execute method + /// @param [in] context is the Algorithm context for event consistency + FW::ProcessCode execute( + const FW::AlgorithmContext& context) const final override; + + private: + /// The config class + Config m_cfg; + + std::vector<Acts::BoundParameters> getInputTrackCollection( + const FW::AlgorithmContext& ctx) const; +}; + +} // namespace FWE \ No newline at end of file diff --git a/Algorithms/Vertexing/src/AdaptiveMultiVertexFinderAlgorithm.cpp b/Algorithms/Vertexing/src/AdaptiveMultiVertexFinderAlgorithm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a376260c9b7ceee8afece6a6a75445a7e12d0df6 --- /dev/null +++ b/Algorithms/Vertexing/src/AdaptiveMultiVertexFinderAlgorithm.cpp @@ -0,0 +1,145 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2020 CERN for the benefit of the Acts project +// +// 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/Vertexing/AdaptiveMultiVertexFinderAlgorithm.hpp" + +#include "ACTFW/Framework/RandomNumbers.hpp" +#include "ACTFW/TruthTracking/VertexAndTracks.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/MagneticField/MagneticFieldContext.hpp" +#include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Surfaces/PerigeeSurface.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/Helpers.hpp" +#include "Acts/Utilities/Units.hpp" +#include "Acts/Vertexing/AdaptiveMultiVertexFinder.hpp" +#include "Acts/Vertexing/AdaptiveMultiVertexFitter.hpp" +#include "Acts/Vertexing/HelicalTrackLinearizer.hpp" +#include "Acts/Vertexing/ImpactPointEstimator.hpp" +#include "Acts/Vertexing/LinearizedTrack.hpp" +#include "Acts/Vertexing/TrackDensityVertexFinder.hpp" +#include "Acts/Vertexing/Vertex.hpp" +#include "Acts/Vertexing/VertexFinderConcept.hpp" +#include "Acts/Vertexing/VertexingOptions.hpp" + +FWE::AdaptiveMultiVertexFinderAlgorithm::AdaptiveMultiVertexFinderAlgorithm( + const Config& cfg, Acts::Logging::Level level) + : FW::BareAlgorithm("AMVF Algorithm", level), m_cfg(cfg) {} + +/// @brief Algorithm that receives all selected tracks from an event +/// and finds and fits its vertices +FW::ProcessCode FWE::AdaptiveMultiVertexFinderAlgorithm::execute( + const FW::AlgorithmContext& ctx) const { + ////////////////////////////////////////////// + /* Full tutorial example code for reference */ + ////////////////////////////////////////////// + + using namespace Acts::UnitLiterals; + // Get the input track collection + auto allTracks = getInputTrackCollection(ctx); + // Create vector of track pointers for vertexing + std::vector<const Acts::BoundParameters*> inputTrackPtrCollection; + for (const auto& trk : allTracks) { + inputTrackPtrCollection.push_back(&trk); + } + + // Set up the magnetic field + Acts::ConstantBField bField(Acts::Vector3D(0., 0., 2_T)); + + // Set up EigenStepper + Acts::EigenStepper<Acts::ConstantBField> stepper(bField); + // Set up the propagator + using Propagator = Acts::Propagator<Acts::EigenStepper<Acts::ConstantBField>>; + auto propagator = std::make_shared<Propagator>(stepper); + + // Set up ImpactPointEstimator + using IPEstimator = + Acts::ImpactPointEstimator<Acts::BoundParameters, Propagator>; + IPEstimator::Config ipEstimatorCfg(bField, propagator); + IPEstimator ipEstimator(ipEstimatorCfg); + + // Set up the helical track linearizer + using Linearizer = Acts::HelicalTrackLinearizer<Propagator>; + Linearizer::Config ltConfig(bField, propagator); + Linearizer linearizer(ltConfig); + + // Set up deterministic annealing with user-defined temperatures + std::vector<double> temperatures{8.0, 4.0, 2.0, 1.4142136, 1.2247449, 1.0}; + Acts::AnnealingUtility::Config annealingConfig(temperatures); + Acts::AnnealingUtility annealingUtility(annealingConfig); + + // Set up the vertex fitter with user-defined annealing + using Fitter = + Acts::AdaptiveMultiVertexFitter<Acts::BoundParameters, Linearizer>; + Fitter::Config fitterCfg(ipEstimator); + fitterCfg.annealingTool = annealingUtility; + Fitter fitter(fitterCfg); + + // Set up the vertex seed finder + using SeedFinder = + Acts::TrackDensityVertexFinder<Fitter, Acts::GaussianTrackDensity>; + SeedFinder seedFinder; + + // The vertex finder type + using Finder = Acts::AdaptiveMultiVertexFinder<Fitter, SeedFinder>; + + Finder::Config finderConfig(std::move(fitter), seedFinder, ipEstimator, + linearizer); + // We do not want to use a beamspot constraint here + finderConfig.useBeamSpotConstraint = false; + + // Instantiate the finder + Finder finder(finderConfig); + // The vertex finder state + Finder::State state; + + // Default vertexing options, this is where e.g. a constraint could be set + using VertexingOptions = Acts::VertexingOptions<Acts::BoundParameters>; + VertexingOptions finderOpts(ctx.geoContext, ctx.magFieldContext); + + // Find vertices + auto res = finder.find(inputTrackPtrCollection, finderOpts, state); + + if (res.ok()) { + // Retrieve vertices found by vertex finder + auto vertexCollection = *res; + ACTS_INFO("Found " << vertexCollection.size() << " vertices in event."); + + unsigned int count = 0; + for (const auto& vtx : vertexCollection) { + ACTS_INFO("\t" << ++count << ". vertex at " + << "(" << vtx.position().x() << "," << vtx.position().y() + << "," << vtx.position().z() << ") with " + << vtx.tracks().size() << " tracks."); + } + } else { + ACTS_ERROR("Error in vertex finder: " << res.error().message()); + } + + return FW::ProcessCode::SUCCESS; +} + +std::vector<Acts::BoundParameters> +FWE::AdaptiveMultiVertexFinderAlgorithm::getInputTrackCollection( + const FW::AlgorithmContext& ctx) const { + // Setup containers + const auto& input = ctx.eventStore.get<std::vector<FW::VertexAndTracks>>( + m_cfg.trackCollection); + std::vector<Acts::BoundParameters> inputTrackCollection; + + for (auto& vertexAndTracks : input) { + inputTrackCollection.insert(inputTrackCollection.end(), + vertexAndTracks.tracks.begin(), + vertexAndTracks.tracks.end()); + } + + return inputTrackCollection; +} diff --git a/Algorithms/Vertexing/src/IterativeVertexFinderAlgorithm.cpp b/Algorithms/Vertexing/src/IterativeVertexFinderAlgorithm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..41bf0aad26b8b3cb5f65d72af65b853cfa956531 --- /dev/null +++ b/Algorithms/Vertexing/src/IterativeVertexFinderAlgorithm.cpp @@ -0,0 +1,136 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2019 CERN for the benefit of the Acts project +// +// 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/Vertexing/IterativeVertexFinderAlgorithm.hpp" + +#include <Acts/Geometry/GeometryContext.hpp> +#include <Acts/MagneticField/MagneticFieldContext.hpp> +#include <iostream> + +#include "ACTFW/Framework/RandomNumbers.hpp" +#include "ACTFW/TruthTracking/VertexAndTracks.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Surfaces/PerigeeSurface.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/Helpers.hpp" +#include "Acts/Utilities/Units.hpp" +#include "Acts/Vertexing/FullBilloirVertexFitter.hpp" +#include "Acts/Vertexing/HelicalTrackLinearizer.hpp" +#include "Acts/Vertexing/ImpactPointEstimator.hpp" +#include "Acts/Vertexing/IterativeVertexFinder.hpp" +#include "Acts/Vertexing/LinearizedTrack.hpp" +#include "Acts/Vertexing/Vertex.hpp" +#include "Acts/Vertexing/VertexFinderConcept.hpp" +#include "Acts/Vertexing/VertexingOptions.hpp" +#include "Acts/Vertexing/ZScanVertexFinder.hpp" + +FWE::IterativeVertexFinderAlgorithm::IterativeVertexFinderAlgorithm( + const Config& cfg, Acts::Logging::Level level) + : FW::BareAlgorithm("VertexFinding", level), m_cfg(cfg) {} + +/// @brief Algorithm that receives all selected tracks from an event +/// and finds and fits its vertices +FW::ProcessCode FWE::IterativeVertexFinderAlgorithm::execute( + const FW::AlgorithmContext& ctx) const { + using MagneticField = Acts::ConstantBField; + using Stepper = Acts::EigenStepper<MagneticField>; + using Propagator = Acts::Propagator<Stepper>; + using PropagatorOptions = Acts::PropagatorOptions<>; + using TrackParameters = Acts::BoundParameters; + using Linearizer = Acts::HelicalTrackLinearizer<Propagator>; + using VertexFitter = + Acts::FullBilloirVertexFitter<TrackParameters, Linearizer>; + using ImpactPointEstimator = + Acts::ImpactPointEstimator<TrackParameters, Propagator>; + using VertexSeeder = Acts::ZScanVertexFinder<VertexFitter>; + using VertexFinder = Acts::IterativeVertexFinder<VertexFitter, VertexSeeder>; + using VertexFinderOptions = Acts::VertexingOptions<TrackParameters>; + + static_assert(Acts::VertexFinderConcept<VertexSeeder>, + "VertexSeeder does not fulfill vertex finder concept."); + static_assert(Acts::VertexFinderConcept<VertexFinder>, + "VertexFinder does not fulfill vertex finder concept."); + + // Set up the magnetic field + MagneticField bField(m_cfg.bField); + // Set up propagator with void navigator + auto propagator = std::make_shared<Propagator>(Stepper(bField)); + PropagatorOptions propagatorOpts(ctx.geoContext, ctx.magFieldContext); + // Setup the vertex fitter + VertexFitter::Config vertexFitterCfg; + VertexFitter vertexFitter(std::move(vertexFitterCfg)); + // Setup the track linearizer + Linearizer::Config linearizerCfg(bField, propagator); + Linearizer linearizer(std::move(linearizerCfg)); + // Setup the seed finder + ImpactPointEstimator::Config ipEstCfg(bField, propagator); + ImpactPointEstimator ipEst(std::move(ipEstCfg)); + VertexSeeder::Config seederCfg(ipEst); + VertexSeeder seeder(std::move(seederCfg)); + // Set up the actual vertex finder + VertexFinder::Config finderCfg(std::move(vertexFitter), std::move(linearizer), + std::move(seeder), ipEst); + finderCfg.maxVertices = 200; + finderCfg.reassignTracksAfterFirstFit = true; + VertexFinder finder(finderCfg); + VertexFinder::State state; + VertexFinderOptions finderOpts(ctx.geoContext, ctx.magFieldContext); + + // Setup containers + const auto& input = ctx.eventStore.get<std::vector<FW::VertexAndTracks>>( + m_cfg.trackCollection); + std::vector<Acts::BoundParameters> inputTrackCollection; + + int counte = 0; + for (auto& bla : input) { + counte += bla.tracks.size(); + } + + ACTS_INFO("Truth vertices in event: " << input.size()); + + for (auto& vertexAndTracks : input) { + ACTS_INFO("\t True vertex at (" + << vertexAndTracks.vertex.position().x() << "," + << vertexAndTracks.vertex.position().y() << "," + << vertexAndTracks.vertex.position().z() << ") with " + << vertexAndTracks.tracks.size() << " tracks."); + inputTrackCollection.insert(inputTrackCollection.end(), + vertexAndTracks.tracks.begin(), + vertexAndTracks.tracks.end()); + } + + std::vector<const Acts::BoundParameters*> inputTrackPtrCollection; + for (const auto& trk : inputTrackCollection) { + inputTrackPtrCollection.push_back(&trk); + } + + // Find vertices + auto res = finder.find(inputTrackPtrCollection, finderOpts, state); + + if (res.ok()) { + // Retrieve vertices found by vertex finder + auto vertexCollection = *res; + + ACTS_INFO("Found " << vertexCollection.size() << " vertices in event."); + + unsigned int count = 0; + for (const auto& vtx : vertexCollection) { + ACTS_INFO("\t" << ++count << ". vertex at " + << "(" << vtx.position().x() << "," << vtx.position().y() + << "," << vtx.position().z() << ") with " + << vtx.tracks().size() << " tracks."); + } + } else { + ACTS_ERROR("Error in vertex finder."); + } + + return FW::ProcessCode::SUCCESS; +} diff --git a/Algorithms/Vertexing/src/TutorialAMVFAlgorithm.cpp b/Algorithms/Vertexing/src/TutorialAMVFAlgorithm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..248b1082de02fd09fe2f5cd8e7a57b622ce5f46b --- /dev/null +++ b/Algorithms/Vertexing/src/TutorialAMVFAlgorithm.cpp @@ -0,0 +1,86 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2020 CERN for the benefit of the Acts project +// +// 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/Vertexing/TutorialAMVFAlgorithm.hpp" + +#include "ACTFW/Framework/RandomNumbers.hpp" +#include "ACTFW/TruthTracking/VertexAndTracks.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/MagneticField/MagneticFieldContext.hpp" +#include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Surfaces/PerigeeSurface.hpp" +#include "Acts/Utilities/Definitions.hpp" +#include "Acts/Utilities/Helpers.hpp" +#include "Acts/Utilities/Units.hpp" +#include "Acts/Vertexing/AdaptiveMultiVertexFinder.hpp" +#include "Acts/Vertexing/AdaptiveMultiVertexFitter.hpp" +#include "Acts/Vertexing/HelicalTrackLinearizer.hpp" +#include "Acts/Vertexing/ImpactPointEstimator.hpp" +#include "Acts/Vertexing/LinearizedTrack.hpp" +#include "Acts/Vertexing/TrackDensityVertexFinder.hpp" +#include "Acts/Vertexing/Vertex.hpp" +#include "Acts/Vertexing/VertexFinderConcept.hpp" +#include "Acts/Vertexing/VertexingOptions.hpp" + +FWE::TutorialAMVFAlgorithm::TutorialAMVFAlgorithm(const Config& cfg, + Acts::Logging::Level level) + : FW::BareAlgorithm("Tutorial AMVF Algorithm", level), m_cfg(cfg) {} + +/// @brief Tutorial algorithm that receives all selected tracks from an event +/// and finds and fits its vertices using the AMVF +FW::ProcessCode FWE::TutorialAMVFAlgorithm::execute( + const FW::AlgorithmContext& ctx) const { + using namespace Acts::UnitLiterals; + + // Get the input track collection + auto allTracks = getInputTrackCollection(ctx); + // Create vector of track pointers for vertexing + std::vector<const Acts::BoundParameters*> inputTrackPtrCollection; + for (const auto& trk : allTracks) { + inputTrackPtrCollection.push_back(&trk); + } + //* Do not change the code above this line *// + + ////////////////////////////////////////////////////////////////////////////// + /***** Note: This is a skeleton file to be filled with tutorial code *****/ + /***** provided in the Acts Docs - Vertexing section under the link: *****/ + /* https://acts.readthedocs.io/en/latest/howto/setup_and_run_vertexing.html */ + /*** or in the Acts repository in docs/howto/setup_and_run_vertexing.md ***/ + ////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////// + /* Add the tutorial example code here */ + /////////////////////////////////////////////// + /////////////////////////////////////////////// + /* For the full tutorial code please refer */ + /* to AdaptiveMultiVertexFinderAlgorithm.cpp */ + /////////////////////////////////////////////// + + //* Do not change the code below this line *// + return FW::ProcessCode::SUCCESS; +} + +std::vector<Acts::BoundParameters> +FWE::TutorialAMVFAlgorithm::getInputTrackCollection( + const FW::AlgorithmContext& ctx) const { + // Setup containers + const auto& input = ctx.eventStore.get<std::vector<FW::VertexAndTracks>>( + m_cfg.trackCollection); + std::vector<Acts::BoundParameters> inputTrackCollection; + + for (auto& vertexAndTracks : input) { + inputTrackCollection.insert(inputTrackCollection.end(), + vertexAndTracks.tracks.begin(), + vertexAndTracks.tracks.end()); + } + + return inputTrackCollection; +} diff --git a/Run/Reconstruction/SolidRecTracks.cpp b/Run/Reconstruction/SolidRecTracks.cpp new file mode 100644 index 0000000000000000000000000000000000000000..caad9908475ec46f6de65778554de57676b593af --- /dev/null +++ b/Run/Reconstruction/SolidRecTracks.cpp @@ -0,0 +1,165 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2019 CERN for the benefit of the Acts project +// +// 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 <Acts/Utilities/Units.hpp> +#include <memory> + +#include "ACTFW/Digitization/HitSmearing.hpp" +#include "ACTFW/Framework/Sequencer.hpp" +#include "ACTFW/Framework/WhiteBoard.hpp" +#include "ACTFW/GenericDetector/GenericDetector.hpp" +#include "ACTFW/Geometry/CommonGeometry.hpp" +#include "ACTFW/Io/Csv/CsvOptionsReader.hpp" +#include "ACTFW/Io/Csv/CsvParticleReader.hpp" +#include "ACTFW/Io/Csv/CsvPlanarClusterReader.hpp" +#include "ACTFW/Io/Performance/CKFPerformanceWriter.hpp" +#include "ACTFW/Options/CommonOptions.hpp" +#include "ACTFW/Plugins/BField/BFieldOptions.hpp" +#include "ACTFW/TrackFinding/TrackFindingAlgorithm.hpp" +#include "ACTFW/TrackFinding/TrackFindingOptions.hpp" +#include "ACTFW/TruthTracking/ParticleSmearing.hpp" +#include "ACTFW/TruthTracking/TruthSeedSelector.hpp" +#include "ACTFW/Utilities/Options.hpp" +#include "ACTFW/Utilities/Paths.hpp" +#include "ACTFW/DD4hepDetector/DD4hepDetector.hpp" +#include "ACTFW/DD4hepDetector/DD4hepDetectorOptions.hpp" +#include "ACTFW/DD4hepDetector/DD4hepGeometryService.hpp" + +using namespace Acts::UnitLiterals; +using namespace FW; + +int main(int argc, char* argv[]) { + + //GenericDetector detector; + + // setup and parse options + auto desc = FW::Options::makeDefaultOptions("Solid Detector track reconstruction" ); + Options::addSequencerOptions(desc); + Options::addRandomNumbersOptions(desc); + //Options::addGeometryOptions(desc); + Options::addMaterialOptions(desc); + Options::addInputOptions(desc); + Options::addOutputOptions(desc); + detector.addOptions(desc); + Options::addBFieldOptions(desc); + Options::addTrackFindingOptions(desc); + Options::addDD4hepOptions(desc); + + auto vm = Options::parse(desc, argc, argv); + if (vm.empty()) { + return EXIT_FAILURE; + } + + Sequencer sequencer(Options::readSequencerConfig(vm)); + + // Read some standard options + auto logLevel = Options::readLogLevel(vm); + auto inputDir = vm["input-dir"].as<std::string>(); + auto outputDir = ensureWritableDirectory(vm["output-dir"].as<std::string>()); + auto rnd = + std::make_shared<FW::RandomNumbers>(Options::readRandomNumbersConfig(vm)); + + // setup the DD4hep detector + auto dd4hepCfg = Options::readDD4hepConfig<po::variables_map>(vm); + auto geometrySvc = std::make_shared<DD4hep::DD4hepGeometryService>(dd4hepCfg); + + // Setup detector geometry + auto geometry = Geometry::build(vm, detector); + auto trackingGeometry = geometry.first; + // Add context decorators + for (auto cdr : geometry.second) { + sequencer.addContextDecorator(cdr); + } + // Setup the magnetic field + auto magneticField = Options::readBField(vm); + + // Read particles (initial states) and clusters from CSV files + auto particleReader = Options::readCsvParticleReaderConfig(vm); + particleReader.inputStem = "particles_initial"; + particleReader.outputParticles = "particles_initial"; + sequencer.addReader( + std::make_shared<CsvParticleReader>(particleReader, logLevel)); + // Read clusters from CSV files + auto clusterReaderCfg = Options::readCsvPlanarClusterReaderConfig(vm); + clusterReaderCfg.trackingGeometry = trackingGeometry; + clusterReaderCfg.outputClusters = "clusters"; + clusterReaderCfg.outputHitIds = "hit_ids"; + clusterReaderCfg.outputHitParticlesMap = "hit_particles_map"; + clusterReaderCfg.outputSimulatedHits = "hits"; + sequencer.addReader( + std::make_shared<CsvPlanarClusterReader>(clusterReaderCfg, logLevel)); + + // Pre-select particles + // The pre-selection will select truth particles satisfying provided criteria + // from all particles read in by particle reader for further processing. It + // has no impact on the truth hits read-in by the cluster reader. + // @TODO: add options for truth particle selection criteria + TruthSeedSelector::Config particleSelectorCfg; + particleSelectorCfg.inputParticles = particleReader.outputParticles; + particleSelectorCfg.inputHitParticlesMap = + clusterReaderCfg.outputHitParticlesMap; + particleSelectorCfg.outputParticles = "particles_selected"; + particleSelectorCfg.ptMin = 1_GeV; + particleSelectorCfg.nHitsMin = 9; + sequencer.addAlgorithm( + std::make_shared<TruthSeedSelector>(particleSelectorCfg, logLevel)); + + // Create smeared measurements + HitSmearing::Config hitSmearingCfg; + hitSmearingCfg.inputSimulatedHits = clusterReaderCfg.outputSimulatedHits; + hitSmearingCfg.outputSourceLinks = "sourcelinks"; + hitSmearingCfg.sigmaLoc0 = 25_um; + hitSmearingCfg.sigmaLoc1 = 100_um; + hitSmearingCfg.randomNumbers = rnd; + hitSmearingCfg.trackingGeometry = trackingGeometry; + sequencer.addAlgorithm( + std::make_shared<HitSmearing>(hitSmearingCfg, logLevel)); + + const auto& inputParticles = particleSelectorCfg.outputParticles; + // Create smeared particles states + ParticleSmearing::Config particleSmearingCfg; + particleSmearingCfg.inputParticles = inputParticles; + particleSmearingCfg.outputTrackParameters = "smearedparameters"; + particleSmearingCfg.randomNumbers = rnd; + // Gaussian sigmas to smear particle parameters + particleSmearingCfg.sigmaD0 = 20_um; + particleSmearingCfg.sigmaD0PtA = 30_um; + particleSmearingCfg.sigmaD0PtB = 0.3 / 1_GeV; + particleSmearingCfg.sigmaZ0 = 20_um; + particleSmearingCfg.sigmaZ0PtA = 30_um; + particleSmearingCfg.sigmaZ0PtB = 0.3 / 1_GeV; + particleSmearingCfg.sigmaPhi = 1_degree; + particleSmearingCfg.sigmaTheta = 1_degree; + particleSmearingCfg.sigmaPRel = 0.01; + particleSmearingCfg.sigmaT0 = 1_ns; + sequencer.addAlgorithm( + std::make_shared<ParticleSmearing>(particleSmearingCfg, logLevel)); + + // Setup the track finding algorithm with CKF + // It takes all the source links created from truth hit smearing, seeds from + // truth particle smearing and source link selection config + auto trackFindingCfg = Options::readTrackFindingConfig(vm); + trackFindingCfg.inputSourceLinks = hitSmearingCfg.outputSourceLinks; + trackFindingCfg.inputInitialTrackParameters = + particleSmearingCfg.outputTrackParameters; + trackFindingCfg.outputTrajectories = "trajectories"; + trackFindingCfg.findTracks = TrackFindingAlgorithm::makeTrackFinderFunction( + trackingGeometry, magneticField, logLevel); + sequencer.addAlgorithm( + std::make_shared<TrackFindingAlgorithm>(trackFindingCfg, logLevel)); + + // Write CKF performance data + CKFPerformanceWriter::Config perfWriterCfg; + perfWriterCfg.inputParticles = inputParticles; + perfWriterCfg.inputTrajectories = trackFindingCfg.outputTrajectories; + perfWriterCfg.outputDir = outputDir; + sequencer.addWriter( + std::make_shared<CKFPerformanceWriter>(perfWriterCfg, logLevel)); + + return sequencer.run(); +}