Commit 77b2b860 authored by Whitney Armstrong's avatar Whitney Armstrong
Browse files

Upgrade to ACTS version 4.1.0

- A lot has changed since 1.0
- The source link is simplified and has a corresponding measurement
class now
- Copied Bfield and utilties from acts examples
- Currently it only compiles. Need to check reconstruction.

It Builds with acts 4.1.0

	modified:   GeoSvc.cpp
	modified:   GeoSvc.h
parent b17313f6
......@@ -39,3 +39,6 @@ __pycache__/
# ROOT file
*.root
*.sif
**old
install/*
variables:
EIC_TAG: "2.5-stable"
EIC_TAG: "2.7-stable"
default:
image: eicweb.phy.anl.gov:4567/containers/image_recipes/ubuntu_dind:latest
......@@ -29,6 +29,10 @@ env:
fi
- echo "CI JUGGLER_TAG for this pipeline set to ${JUGGLER_TAG}"
- echo "JUGGLER_TAG=$JUGGLER_TAG" >> juggler.env
- |
if [ "${DETECTOR_TAG}" ]; then
echo "DETECTOR_TAG=$DETECTOR_TAG" >> juggler.env
fi
artifacts:
reports:
dotenv: juggler.env
......
......@@ -21,6 +21,10 @@ gaudi_depends_on_subdirs(GaudiAlg GaudiKernel)
gaudi_add_library(JugBase
src/*.cpp
src/Utilities/*.cpp
src/Plugins/BFieldOptions.cpp
#src/Plugins/BFieldScalor.cpp
src/Plugins/BFieldUtils.cpp
INCLUDE_DIRS EICD PODIO ROOT $ENV{HOME}/stow/podio/include
LINK_LIBRARIES GaudiAlgLib GaudiKernel ROOT DD4hep::DDG4IO
PUBLIC_HEADERS JugBase)
......
// This file is part of the Acts project.
//
// Copyright (C) 2017 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 "Acts/Definitions/Algebra.hpp"
#include "Acts/Utilities/detail/AxisFwd.hpp"
#include "Acts/Utilities/detail/GridFwd.hpp"
#include "JugBase/Utilities/OptionsFwd.hpp"
#include <memory>
#include <tuple>
#include <variant>
// Forward declarations
namespace Acts {
template <typename G>
struct InterpolatedBFieldMapper;
template <typename M>
class InterpolatedBFieldMap;
class ConstantBField;
} // namespace Acts
namespace Jug {
namespace BField {
class ScalableBField;
}
} // namespace Jug
using InterpolatedMapper2D = Acts::InterpolatedBFieldMapper<
Acts::detail::Grid<Acts::Vector2, Acts::detail::EquidistantAxis,
Acts::detail::EquidistantAxis>>;
using InterpolatedMapper3D = Acts::InterpolatedBFieldMapper<Acts::detail::Grid<
Acts::Vector3, Acts::detail::EquidistantAxis, Acts::detail::EquidistantAxis,
Acts::detail::EquidistantAxis>>;
using InterpolatedBFieldMap2D =
Acts::InterpolatedBFieldMap<InterpolatedMapper2D>;
using InterpolatedBFieldMap3D =
Acts::InterpolatedBFieldMap<InterpolatedMapper3D>;
namespace Jug {
namespace Options {
using BFieldVariant =
std::variant<std::shared_ptr<InterpolatedBFieldMap2D>,
std::shared_ptr<InterpolatedBFieldMap3D>,
std::shared_ptr<Acts::ConstantBField>,
std::shared_ptr<Jug::BField::ScalableBField>>;
// common bfield options, with a bf prefix
void addBFieldOptions(boost::program_options::options_description& opt);
// create the bfield maps
BFieldVariant readBField(const boost::program_options::variables_map& vm);
} // namespace Options
} // namespace Jug
// 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/.
#pragma once
#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Utilities/Logger.hpp"
#include "Jug/Framework/AlgorithmContext.hpp"
#include "Jug/Framework/IContextDecorator.hpp"
#include <vector>
namespace Jug {
namespace BField {
/// A mockup service that rotates a
/// cylindrical geometry
class BFieldScalor : public IContextDecorator {
public:
/// @brief nested configuration struct
struct Config {
/// Incremental scaling
double scalor = 1.2;
};
/// Constructor
///
/// @param cfg Configuration struct
/// @param logger The logging framework
BFieldScalor(const Config& cfg,
std::unique_ptr<const Acts::Logger> logger =
Acts::getDefaultLogger("BFieldScalor", Acts::Logging::INFO));
/// Virtual destructor
virtual ~BFieldScalor() = default;
/// @brief decorates (adds, modifies) the AlgorithmContext
/// with a geometric rotation per event
///
/// @note If decorators depend on each other, they have to be
/// added in order.
///
/// @param context the bare (or at least non-const) Event context
ProcessCode decorate(AlgorithmContext& context) final override;
/// @brief decorator name() for screen output
const std::string& name() const final override { return m_name; }
private:
Config m_cfg; ///< the configuration class
std::unique_ptr<const Acts::Logger> m_logger; ///!< the logging instance
std::string m_name = "BFieldScalor";
/// Private access to the logging instance
const Acts::Logger& logger() const { return *m_logger; }
};
} // namespace BField
} // namespace Jug
// This file is part of the Acts project.
//
// Copyright (C) 2017 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 "Acts/Definitions/Units.hpp"
#include "Acts/MagneticField/InterpolatedBFieldMap.hpp"
#include "Acts/Utilities/Logger.hpp"
#include "Acts/Utilities/detail/Axis.hpp"
#include "Acts/Utilities/detail/Grid.hpp"
namespace Jug {
namespace BField {
namespace txt {
/// Method to setup the FieldMapper
/// @param localToGlobalBin Function mapping the local bins of r,z to the
/// global
/// bin of the map magnetic field value e.g.: we have small grid with the
/// values: r={2,3}, z ={4,5}, the corresponding indices are i(r) and j(z),
/// the
/// globalIndex is M and the field map is:
///|| r | i || z | j || |B(r,z)| || M ||
/// -----------------------------------
///|| 2 | 0 || 4 | 0 || 2.323 || 0 ||
///|| 2 | 0 || 5 | 1 || 2.334 || 1 ||
///|| 3 | 1 || 4 | 0 || 2.325 || 2 ||
///|| 3 | 1 || 5 | 1 || 2.331 || 3 ||
///
/// @code
/// In this case the function would look like:
/// [](std::array<size_t, 2> binsRZ, std::array<size_t, 2> nBinsRZ) {
/// return (binsRZ.at(0) * nBinsRZ.at(1) + binsRZ.at(1));
/// }
/// @endcode
/// @param[in] fieldMapFile Path to file containing field map in txt format
/// @param[in] lengthUnit The unit of the grid points
/// @param[in] BFieldUnit The unit of the magnetic field
/// @param[in] nPoints Extimate of number of grid points in field map needed
/// for allocation
/// @note This information is only used as a hint for the required size of
/// the internal vectors. A correct value is not needed, but will help
/// to speed up the field map initialization process.
/// @param[in] firstOctant Flag if set to true indicating that only the
/// first
/// quadrant of the grid points and the BField values has been given and
/// that
/// the BFieldMap should be created symmetrically for all quadrants.
/// e.g. we have the grid values r={0,1} with BFieldValues={2,3} on the r
/// axis.
/// If the flag is set to true the r-axis grid values will be set to
/// {-1,0,1}
/// and the BFieldValues will be set to {3,2,3}.
Acts::InterpolatedBFieldMapper<
Acts::detail::Grid<Acts::Vector2, Acts::detail::EquidistantAxis,
Acts::detail::EquidistantAxis>>
fieldMapperRZ(std::function<size_t(std::array<size_t, 2> binsRZ,
std::array<size_t, 2> nBinsRZ)>
localToGlobalBin,
std::string fieldMapFile = "",
double lengthUnit = Acts::UnitConstants::mm,
double BFieldUnit = Acts::UnitConstants::T, size_t nPoints = 1000,
bool firstOctant = false);
/// Method to setup the FieldMapper
/// @param localToGlobalBin Function mapping the local bins of x,y,z to the
/// global bin of the map magnetic field value e.g.: we have small grid with
/// the
/// values: x={2,3}, y={3,4}, z ={4,5}, the corresponding indices are i(x),
/// j(y)
/// and z(k), the globalIndex is M and the field map is:
///|| x | i || y | j || z | k || |B(x,y,z)| || M ||
/// --------------------------------------------
///|| 2 | 0 || 3 | 0 || 4 | 0 || 2.323 || 0 ||
///|| 2 | 0 || 3 | 0 || 5 | 1 || 2.334 || 1 ||
///|| 2 | 0 || 4 | 1 || 4 | 0 || 2.325 || 2 ||
///|| 2 | 0 || 4 | 1 || 5 | 1 || 2.331 || 3 ||
///|| 3 | 1 || 3 | 0 || 4 | 0 || 2.323 || 4 ||
///|| 3 | 1 || 3 | 0 || 5 | 1 || 2.334 || 5 ||
///|| 3 | 1 || 4 | 1 || 4 | 0 || 2.325 || 6 ||
///|| 3 | 1 || 4 | 1 || 5 | 1 || 2.331 || 7 ||
///
/// @code
/// In this case the function would look like:
/// [](std::array<size_t, 3> binsXYZ, std::array<size_t, 3> nBinsXYZ) {
/// return (binsXYZ.at(0) * (nBinsXYZ.at(1) * nBinsXYZ.at(2))
/// + binsXYZ.at(1) * nBinsXYZ.at(2)
/// + binsXYZ.at(2));
/// }
/// @endcode
/// @param[in] fieldMapFile Path to file containing field map in txt format
/// @param[in] lengthUnit The unit of the grid points
/// @param[in] BFieldUnit The unit of the magnetic field
/// @param[in] nPoints Extimate of number of grid points in field map needed
/// for allocation
/// @note This information is only used as a hint for the required size of
/// the internal vectors. A correct value is not needed, but will help
/// to speed up the field map initialization process.
/// @param[in] firstOctant Flag if set to true indicating that only the
/// first
/// octant of the grid points and the BField values has been given and that
/// the BFieldMap should be created symmetrically for all quadrants.
/// e.g. we have the grid values z={0,1} with BFieldValues={2,3} on the r
/// axis.
/// If the flag is set to true the z-axis grid values will be set to
/// {-1,0,1}
/// and the BFieldValues will be set to {3,2,3}.
Acts::InterpolatedBFieldMapper<Acts::detail::Grid<
Acts::Vector3, Acts::detail::EquidistantAxis, Acts::detail::EquidistantAxis,
Acts::detail::EquidistantAxis>>
fieldMapperXYZ(std::function<size_t(std::array<size_t, 3> binsXYZ,
std::array<size_t, 3> nBinsXYZ)>
localToGlobalBin,
std::string fieldMapFile = "",
double lengthUnit = Acts::UnitConstants::mm,
double BFieldUnit = Acts::UnitConstants::T,
size_t nPoints = 1000, bool firstOctant = false);
} // namespace txt
namespace root {
/// Method to setup the FieldMapper
/// @param localToGlobalBin Function mapping the local bins of r,z to the
/// global
/// bin of the map magnetic field value e.g.: we have small grid with the
/// values: r={2,3}, z ={4,5}, the corresponding indices are i(r) and j(z),
/// the
/// globalIndex is M and the field map is:
///|| r | i || z | j || |B(r,z)| || M ||
/// -----------------------------------
///|| 2 | 0 || 4 | 0 || 2.323 || 0 ||
///|| 2 | 0 || 5 | 1 || 2.334 || 1 ||
///|| 3 | 1 || 4 | 0 || 2.325 || 2 ||
///|| 3 | 1 || 5 | 1 || 2.331 || 3 ||
///
/// @code
/// In this case the function would look like:
/// [](std::array<size_t, 2> binsRZ, std::array<size_t, 2> nBinsRZ) {
/// return (binsRZ.at(0) * nBinsRZ.at(1) + binsRZ.at(1));
/// }
/// @endcode
/// @param[in] fieldMapFile Path to file containing field map in txt format
/// @param[in] treeName The name of the root tree
/// @param[in] lengthUnit The unit of the grid points
/// @param[in] BFieldUnit The unit of the magnetic field
/// @param[in] firstQuadrant Flag if set to true indicating that only the
/// first
/// quadrant of the grid points and the BField values has been given and
/// that
/// the BFieldMap should be created symmetrically for all quadrants.
/// e.g. we have the grid values r={0,1} with BFieldValues={2,3} on the r
/// axis.
/// If the flag is set to true the r-axis grid values will be set to
/// {-1,0,1}
/// and the BFieldValues will be set to {3,2,3}.
Acts::InterpolatedBFieldMapper<
Acts::detail::Grid<Acts::Vector2, Acts::detail::EquidistantAxis,
Acts::detail::EquidistantAxis>>
fieldMapperRZ(std::function<size_t(std::array<size_t, 2> binsRZ,
std::array<size_t, 2> nBinsRZ)>
localToGlobalBin,
std::string fieldMapFile = "", std::string treeName = "",
double lengthUnit = Acts::UnitConstants::mm,
double BFieldUnit = Acts::UnitConstants::T,
bool firstOctant = false);
/// Method to setup the FieldMapper
/// @param localToGlobalBin Function mapping the local bins of x,y,z to the
/// global bin of the map magnetic field value e.g.: we have small grid with
/// the
/// values: x={2,3}, y={3,4}, z ={4,5}, the corresponding indices are i(x),
/// j(y)
/// and z(k), the globalIndex is M and the field map is:
///|| x | i || y | j || z | k || |B(x,y,z)| || M ||
/// --------------------------------------------
///|| 2 | 0 || 3 | 0 || 4 | 0 || 2.323 || 0 ||
///|| 2 | 0 || 3 | 0 || 5 | 1 || 2.334 || 1 ||
///|| 2 | 0 || 4 | 1 || 4 | 0 || 2.325 || 2 ||
///|| 2 | 0 || 4 | 1 || 5 | 1 || 2.331 || 3 ||
///|| 3 | 1 || 3 | 0 || 4 | 0 || 2.323 || 4 ||
///|| 3 | 1 || 3 | 0 || 5 | 1 || 2.334 || 5 ||
///|| 3 | 1 || 4 | 1 || 4 | 0 || 2.325 || 6 ||
///|| 3 | 1 || 4 | 1 || 5 | 1 || 2.331 || 7 ||
///
/// @code
/// In this case the function would look like:
/// [](std::array<size_t, 3> binsXYZ, std::array<size_t, 3> nBinsXYZ) {
/// return (binsXYZ.at(0) * (nBinsXYZ.at(1) * nBinsXYZ.at(2))
/// + binsXYZ.at(1) * nBinsXYZ.at(2)
/// + binsXYZ.at(2));
/// }
/// @endcode
/// @param[in] fieldMapFile Path to file containing field map in txt format
/// @param[in] treeName The name of the root tree
/// @param[in] lengthUnit The unit of the grid points
/// @param[in] BFieldUnit The unit of the magnetic field
/// @param[in] firstOctant Flag if set to true indicating that only the
/// first
/// octant of the grid points and the BField values has been given and that
/// the BFieldMap should be created symmetrically for all quadrants.
/// e.g. we have the grid values z={0,1} with BFieldValues={2,3} on the r
/// axis.
/// If the flag is set to true the z-axis grid values will be set to
/// {-1,0,1}
/// and the BFieldValues will be set to {3,2,3}.
Acts::InterpolatedBFieldMapper<Acts::detail::Grid<
Acts::Vector3, Acts::detail::EquidistantAxis, Acts::detail::EquidistantAxis,
Acts::detail::EquidistantAxis>>
fieldMapperXYZ(std::function<size_t(std::array<size_t, 3> binsXYZ,
std::array<size_t, 3> nBinsXYZ)>
localToGlobalBin,
std::string fieldMapFile = "", std::string treeName = "",
double lengthUnit = Acts::UnitConstants::mm,
double BFieldUnit = Acts::UnitConstants::T,
bool firstOctant = false);
} // namespace root
} // namespace BField
} // namespace Jug
// This file is part of the Acts project.
//
// Copyright (C) 2016-2018 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 "Acts/Definitions/Algebra.hpp"
#include "Acts/MagneticField/MagneticFieldContext.hpp"
namespace Jug {
namespace BField {
/// The Context to be handed around
struct ScalableBFieldContext {
double scalor = 1.;
};
/// @ingroup MagneticField
///
/// @brief returns a given constant field value at every point
///
/// This class is based on the constant magnetic field class
/// but allows a event based context
class ScalableBField final {
public:
struct Cache {
double scalor = 1.;
/// @brief constructor with context
Cache(const Acts::MagneticFieldContext& mcfg) {
scalor = std::any_cast<const ScalableBFieldContext>(mcfg).scalor;
}
};
/// @brief construct constant magnetic field from field vector
///
/// @param [in] B magnetic field vector in global coordinate system
explicit ScalableBField(Acts::Vector3 B) : m_BField(std::move(B)) {}
/// @brief construct constant magnetic field from components
///
/// @param [in] Bx magnetic field component in global x-direction
/// @param [in] By magnetic field component in global y-direction
/// @param [in] Bz magnetic field component in global z-direction
ScalableBField(double Bx = 0., double By = 0., double Bz = 0.)
: m_BField(Bx, By, Bz) {}
/// @brief retrieve magnetic field value
///
/// @param [in] position global position
/// @return magnetic field vector
///
/// @note The @p position is ignored and only kept as argument to provide
/// a consistent interface with other magnetic field services.
Acts::Vector3 getField(const Acts::Vector3& /*position*/) const {
return m_BField;
}
/// @brief retrieve magnetic field value
///
/// @param [in] position global position
/// @param [in] cache Cache object (is ignored)
/// @return magnetic field vector
///
/// @note The @p position is ignored and only kept as argument to provide
/// a consistent interface with other magnetic field services.
Acts::Vector3 getField(const Acts::Vector3& /*position*/,
Cache& cache) const {
return m_BField * cache.scalor;
}
/// @brief retrieve magnetic field value & its gradient
///
/// @param [in] position global position
/// @param [out] derivative gradient of magnetic field vector as (3x3)
/// matrix
/// @return magnetic field vector
///
/// @note The @p position is ignored and only kept as argument to provide
/// a consistent interface with other magnetic field services.
/// @note currently the derivative is not calculated
/// @todo return derivative
Acts::Vector3 getFieldGradient(const Acts::Vector3& /*position*/,
Acts::ActsMatrix<3, 3>& /*derivative*/) const {
return m_BField;
}
/// @brief retrieve magnetic field value & its gradient
///
/// @param [in] position global position
/// @param [out] derivative gradient of magnetic field vector as (3x3)
/// matrix
/// @param [in] cache Cache object (is ignored)
/// @return magnetic field vector
///
/// @note The @p position is ignored and only kept as argument to provide
/// a consistent interface with other magnetic field services.
/// @note currently the derivative is not calculated
/// @todo return derivative
Acts::Vector3 getFieldGradient(const Acts::Vector3& /*position*/,
Acts::ActsMatrix<3, 3>& /*derivative*/,
Cache& cache) const {
return m_BField * cache.scalor;
}
/// @brief check whether given 3D position is inside look-up domain
///
/// @param [in] position global 3D position
/// @return @c true if position is inside the defined look-up grid,
/// otherwise @c false
/// @note The method will always return true for the constant B-Field
bool isInside(const Acts::Vector3& /*position*/) const { return true; }
/// @brief update magnetic field vector from components
///
/// @param [in] Bx magnetic field component in global x-direction
/// @param [in] By magnetic field component in global y-direction
/// @param [in] Bz magnetic field component in global z-direction
void setField(double Bx, double By, double Bz) { m_BField << Bx, By, Bz; }
/// @brief update magnetic field vector
///
/// @param [in] B magnetic field vector in global coordinate system
void setField(const Acts::Vector3& B) { m_BField = B; }
private:
/// magnetic field vector
Acts::Vector3 m_BField;
};
} // namespace BField
} // namespace Jug
// 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 "JugBase/Utilities/Range.hpp"
#include <algorithm>
#include <iterator>
#include <utility>
namespace Jug {
/// Proxy for iterating over groups of elements within a container.
///
/// @note Each group will contain at least one element.
///
/// Consecutive elements with the same key (as defined by the KeyGetter) are
/// placed in one group. The proxy should always be used as part of a
/// range-based for loop. In combination with structured bindings to reduce the
/// boilerplate, the group iteration can be written as
///
/// for (auto&& [key, elements] : GroupBy<...>(...)) {
/// // do something with just the key
/// ...
///
/// // iterate over the group elements
/// for (const auto& element : elements) {
/// ...
/// }
/// }
///
template <typename Iterator, typename KeyGetter>
class GroupBy {
public:
/// The key type that identifies elements within a group.
using Key = std::decay_t<decltype(KeyGetter()(*Iterator()))>;
/// A Group is an iterator range with the associated key.
using Group = std::pair<Key, Range<Iterator>>;
/// Iterator type representing the end of the groups.
///
/// The end iterator will not be dereferenced in C++17 range-based loops. It
/// can thus be a simpler type without the overhead of the full group iterator
/// below.
using GroupEndIterator = Iterator;
/// Iterator type representing a group of elements.
class GroupIterator {
public:
using iterator_category = std::input_iterator_tag;
using value_type = Group;
using difference_type = std::ptrdiff_t;
using pointer = Group*;
using reference = Group&;
constexpr GroupIterator(const GroupBy& groupBy, Iterator groupBegin)
: m_groupBy(groupBy),
m_groupBegin(groupBegin),
m_groupEnd(groupBy.findEndOfGroup(groupBegin)) {}
/// Pre-increment operator to advance to the next group.
constexpr GroupIterator& operator++() {