Loading src/core/geometry/DetectorField.hpp +12 −0 Original line number Diff line number Diff line Loading @@ -209,6 +209,18 @@ namespace allpix { */ T get_field_from_grid(const double x, const double y, const double z, const bool extrapolate_z) const noexcept; /** * @brief Map x and y coordinates of a position and a reference point onto a pixel given the chosen mapping. * * @param pos Position to calculate coordinates for * @param ref Reference position to calculate relative position to * * @return Tuple with relative x and y coordinates, mapped into the chosen area, and booleans indicating whether * flipping of vector components is necessary */ std::tuple<double, double, bool, bool> map_coordinates(const ROOT::Math::XYZPoint& pos, const ROOT::Math::XYPoint& ref) const; /** * @brief Fast floor-to-int implementation without overflow protection as std::floor * @param x Double-precision floating point value Loading src/core/geometry/DetectorField.tpp +54 −42 Original line number Diff line number Diff line Loading @@ -112,12 +112,37 @@ namespace allpix { return {}; } T ret_val; if(type_ == FieldType::GRID) { // Map the coordinates onto the chosen pixel fraction auto [px, py, flip_x, flip_y] = map_coordinates(pos, ref); // Intentionally do floating-point equality comparison to avoid us landing on the edge of the field px -= (px == 1.0 ? std::numeric_limits<double>::epsilon() : 0.); py -= (py == 1.0 ? std::numeric_limits<double>::epsilon() : 0.); ret_val = get_field_from_grid(px, py, z, extrapolate_z); // Flip vector if necessary flip_vector_components(ret_val, flip_x, flip_y); } else { // Calculate the coordinates relative to the reference point: auto x = pos.x() - ref.x() + offset_[0]; auto y = pos.y() - ref.y() + offset_[1]; T ret_val; if(type_ == FieldType::GRID) { // Calculate the field from the configured function: ret_val = function_(ROOT::Math::XYZPoint(x, y, z)); } return ret_val; } template <typename T, size_t N> std::tuple<double, double, bool, bool> DetectorField<T, N>::map_coordinates(const ROOT::Math::XYZPoint& pos, const ROOT::Math::XYPoint& ref) const { // Calculate the coordinates relative to the reference point: auto x = pos.x() - ref.x() + offset_[0]; auto y = pos.y() - ref.y() + offset_[1]; // Do we need to flip the position vector components? auto flip_x = Loading Loading @@ -157,20 +182,7 @@ namespace allpix { py += (y >= 0 ? 0. : 1.0); } // Intentionally do floating-point equality comparison to avoid us landing on the edge of the field px -= (px == 1.0 ? std::numeric_limits<double>::epsilon() : 0.); py -= (py == 1.0 ? std::numeric_limits<double>::epsilon() : 0.); ret_val = get_field_from_grid(px, py, z, extrapolate_z); // Flip vector if necessary flip_vector_components(ret_val, flip_x, flip_y); } else { // Calculate the field from the configured function: ret_val = function_(ROOT::Math::XYZPoint(x, y, z)); } return ret_val; return {px, py, flip_x, flip_y}; } // Maps the field indices onto the range of -d/2 < x < d/2, where d is the scale of the field in coordinate x. Loading Loading
src/core/geometry/DetectorField.hpp +12 −0 Original line number Diff line number Diff line Loading @@ -209,6 +209,18 @@ namespace allpix { */ T get_field_from_grid(const double x, const double y, const double z, const bool extrapolate_z) const noexcept; /** * @brief Map x and y coordinates of a position and a reference point onto a pixel given the chosen mapping. * * @param pos Position to calculate coordinates for * @param ref Reference position to calculate relative position to * * @return Tuple with relative x and y coordinates, mapped into the chosen area, and booleans indicating whether * flipping of vector components is necessary */ std::tuple<double, double, bool, bool> map_coordinates(const ROOT::Math::XYZPoint& pos, const ROOT::Math::XYPoint& ref) const; /** * @brief Fast floor-to-int implementation without overflow protection as std::floor * @param x Double-precision floating point value Loading
src/core/geometry/DetectorField.tpp +54 −42 Original line number Diff line number Diff line Loading @@ -112,12 +112,37 @@ namespace allpix { return {}; } T ret_val; if(type_ == FieldType::GRID) { // Map the coordinates onto the chosen pixel fraction auto [px, py, flip_x, flip_y] = map_coordinates(pos, ref); // Intentionally do floating-point equality comparison to avoid us landing on the edge of the field px -= (px == 1.0 ? std::numeric_limits<double>::epsilon() : 0.); py -= (py == 1.0 ? std::numeric_limits<double>::epsilon() : 0.); ret_val = get_field_from_grid(px, py, z, extrapolate_z); // Flip vector if necessary flip_vector_components(ret_val, flip_x, flip_y); } else { // Calculate the coordinates relative to the reference point: auto x = pos.x() - ref.x() + offset_[0]; auto y = pos.y() - ref.y() + offset_[1]; T ret_val; if(type_ == FieldType::GRID) { // Calculate the field from the configured function: ret_val = function_(ROOT::Math::XYZPoint(x, y, z)); } return ret_val; } template <typename T, size_t N> std::tuple<double, double, bool, bool> DetectorField<T, N>::map_coordinates(const ROOT::Math::XYZPoint& pos, const ROOT::Math::XYPoint& ref) const { // Calculate the coordinates relative to the reference point: auto x = pos.x() - ref.x() + offset_[0]; auto y = pos.y() - ref.y() + offset_[1]; // Do we need to flip the position vector components? auto flip_x = Loading Loading @@ -157,20 +182,7 @@ namespace allpix { py += (y >= 0 ? 0. : 1.0); } // Intentionally do floating-point equality comparison to avoid us landing on the edge of the field px -= (px == 1.0 ? std::numeric_limits<double>::epsilon() : 0.); py -= (py == 1.0 ? std::numeric_limits<double>::epsilon() : 0.); ret_val = get_field_from_grid(px, py, z, extrapolate_z); // Flip vector if necessary flip_vector_components(ret_val, flip_x, flip_y); } else { // Calculate the field from the configured function: ret_val = function_(ROOT::Math::XYZPoint(x, y, z)); } return ret_val; return {px, py, flip_x, flip_y}; } // Maps the field indices onto the range of -d/2 < x < d/2, where d is the scale of the field in coordinate x. Loading