/* This file is part of MAUS: http://micewww.pp.rl.ac.uk/projects/maus * * MAUS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MAUS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MAUS. If not, see . */ #ifndef _SRC_COMMON_CPP_FIELDTOOLS_SECTORFIELD_HH_ #define _SRC_COMMON_CPP_FIELDTOOLS_SECTORFIELD_HH_ #include #include "src/legacy/BeamTools/BTField.hh" namespace MAUS { /** @class SectorField * * SectorField is an abstraction type for a sector field map i.e. a field map * with a bent geometry as in a ring. Functions are provided for converting * from cartesian coordinate systems to ring coordinate systems and vice versa * and field calculation functions are defined for the field in cartesian * coordinates and additionally ring coordinates. * * The sector field map holds two bounding boxes - the standard rectangular * bounding box in cartesian coordinates and additionally a sector bounding box * in polar coordinates. The bounding box should always be given in polar * coordinates - SectorField will do the conversion to cartesian coordinates * (note this is a lossy procedure) * * Ring coordinates are typically given as three vectors going like * (radius, y, angle) also denoted by (r, y, phi). The ring coordinate system * is defined with (x, y, z) = (0, 0, 0) the centre of the ring; y is the same * in ring and cartesian coordinate systems. Positive phi is anticlockwise in * the (x, z) plane. */ class SectorField : public BTField { public: /** Make an empty sector field; set bounding box to max double */ SectorField(); /** Make a sector field with the given bounding box */ SectorField(double bbMinR, double bbMinY, double bbMinPhi, double bbMaxR, double bbMaxY, double bbMaxPhi); /** Destructor (does nothing) */ virtual ~SectorField(); /** Return the field value in polar coordinates * * @param point_polar position in cylindrical coordinates at which to * evaluate the field. Should be an array of length 4 like * (r, y, phi, t) * @param field_polar pointer to an allocated block of at least 6 doubles. * The function will fill the block with the value of the field in * cylindrical polar coordinates, * (b_r, b_y, b_phi, e_r, e_y, e_phi) * Overwrites any existing data */ virtual void GetFieldValuePolar (const double* point_polar, double* field_polar) const = 0; /** Return the field value in cartesian coordinates * * @param point_cartes position in cartesian coordinates at which to * evaluate the field. Should be an array of length 4 like * (x, y, z, t) * @param field_cartes pointer to an allocated block of at least 6 doubles. * The function will fill the block with the value of the field in * cartesian polar coordinates, * (b_x, b_y, b_z, e_x, e_y, e_z) * Overwrites any existing data */ virtual void GetFieldValue (const double* point_cartes, double* field_cartes) const = 0; /** Convert a position from cartesian to polar coordinates * * @param position position in cartesian coordinates to convert to * cylindrical polar coordinates. Input should be an allocated block * of at least 3 doubles containing values (x, y, z). This is over * written with 3 double containing values (r, y, phi). */ static void ConvertToPolar(double* position); /** Convert a 3 vector from cartesian to polar coordinate system * * @param position position in polar coordinates at which the value is * valid * @param value pointer to an allocated block of at least 3 doubles. The * function will apply a rotation to the existing data to render it * from cartesian coordinates (a_x, a_y, a_z) to polar coordinates * (a_r, a_y, a_phi) appropriate for the specified position. */ static void ConvertToPolar(const double* position_polar, double* value); /** Convert a position from polar coordinates to cartesian * * @param position position in polar coordinates to convert to * cartesian polar coordinates. Input should be an allocated block * of at least 3 doubles containing values (r, y, phi). This is over * written with 3 double containing values (x, y, z). */ static void ConvertToCartesian(double* position); /** Convert a 3 vector from polar to cartesian coordinate system * * @param position position in polar coordinates at which the value is * valid * @param value pointer to an allocated block of at least 3 doubles. The * function will apply a rotation to the existing data to render it * from polar coordinates (a_r, a_y, a_phi) to polar coordinates * (a_x, a_y, a_z) appropriate for the specified position. */ static void ConvertToCartesian(const double* position_polar, double* value); /** Get the minimum bounding box in polar coordinates * * @returns bounding box minimum as a 3-vector like (r_min, y_min, phi_min) */ virtual std::vector GetPolarBoundingBoxMin() const; /** Get the maximum bounding box in polar coordinates * * @returns bounding box maximum as a 3-vector like (r_max, y_max, phi_max) */ virtual std::vector GetPolarBoundingBoxMax() const; protected: /** Set the bounding boxes from polar coordinates * * Sets the bounding boxes, both polar and cartesian, based on a set of * minimum and maximum polar coordinates * * @param bbMinR minimum radius - must be positive * @param bbMinY minimum y value * @param bbMinPhi minimum phi value - must be greater than -2*pi * @param bbMaxR maximum radius - must be greater than minimum radius * @param bbMaxY maximum y value - must be greater than minimum y value * @param bbMaxPhi maximum phi value - must be greater than minimum phi and * less than 2*pi */ void SetPolarBoundingBox(double bbMinR, double bbMinY, double bbMinPhi, double bbMaxR, double bbMaxY, double bbMaxPhi); /** bounding box minimum as a 3-vector like (r_min, y_min, phi_min) */ std::vector _polarBBMin; /** bounding box maximum as a 3-vector like (r_max, y_max, phi_max) */ std::vector _polarBBMax; private: std::vector< std::vector > GetCorners (double bbMinR, double bbMinPhi, double bbMaxR, double bbMaxPhi); }; } #endif