Commit 1aa8f1f5 authored by Simon Spannagel's avatar Simon Spannagel
Browse files

DetectorField: move mapping coordinates into separate function

parent cd18ce9a
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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
+54 −42
Original line number Diff line number Diff line
@@ -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 =
@@ -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.