/* 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 .
*/
#include
#include "gtest/gtest.h"
#include "Utils/Exception.hh"
#include "src/common_cpp/FieldTools/SectorField.hh"
namespace MAUS {
class SectorFieldTestClass : public SectorField {
public:
virtual void GetFieldValuePolar
(const double* point_polar, double* field_polar) const {}
virtual void GetFieldValue
(const double* point_cartes, double* field_cartes) const {}
void SetPolarBoundingBox(double bbMinR, double bbMinY, double bbMinPhi,
double bbMaxR, double bbMaxY, double bbMaxPhi) {
SectorField::SetPolarBoundingBox(bbMinR, bbMinY, bbMinPhi,
bbMaxR, bbMaxY, bbMaxPhi);
}
std::vector GetBoundingBoxMin() {return BTField::bbMin;}
std::vector GetBoundingBoxMax() {return BTField::bbMax;}
};
void __testConvertPosToPolarAndCartesian(const double* position_in,
const double* position_expected) {
double position_test[3];
position_test[0] = position_in[0];
position_test[1] = position_in[1];
position_test[2] = position_in[2];
SectorField::ConvertToPolar(position_test);
if (position_expected != NULL) {
EXPECT_NEAR(position_test[0], position_expected[0], 1e-9)
<< position_in[0] << " " << position_in[1] << " " << position_in[2];
EXPECT_NEAR(position_test[1], position_expected[1], 1e-9)
<< position_in[0] << " " << position_in[1] << " " << position_in[2];
EXPECT_NEAR(position_test[2], position_expected[2], 1e-9)
<< position_in[0] << " " << position_in[1] << " " << position_in[2];
}
SectorField::ConvertToCartesian(position_test);
EXPECT_NEAR(position_test[0], position_in[0], 1e-9)
<< position_in[0] << " " << position_in[1] << " " << position_in[2];
EXPECT_NEAR(position_test[1], position_in[1], 1e-9)
<< position_in[0] << " " << position_in[1] << " " << position_in[2];
EXPECT_NEAR(position_test[2], position_in[2], 1e-9)
<< position_in[0] << " " << position_in[1] << " " << position_in[2];
}
void __testConvertValueToPolarAndCartesian(const double* position,
const double* value_in,
const double* value_expected) {
double value_test[3];
value_test[0] = value_in[0];
value_test[1] = value_in[1];
value_test[2] = value_in[2];
SectorField::ConvertToPolar(position, value_test);
if (value_expected != NULL) {
EXPECT_NEAR(value_test[0], value_expected[0], 1e-9)
<< value_in[0] << " " << value_in[1] << " " << value_in[2];
EXPECT_NEAR(value_test[1], value_expected[1], 1e-9)
<< value_in[0] << " " << value_in[1] << " " << value_in[2];
EXPECT_NEAR(value_test[2], value_expected[2], 1e-9)
<< value_in[0] << " " << value_in[1] << " " << value_in[2];
}
SectorField::ConvertToCartesian(position, value_test);
EXPECT_NEAR(value_test[0], value_in[0], 1e-9)
<< value_in[0] << " " << value_in[1] << " " << value_in[2];
EXPECT_NEAR(value_test[1], value_in[1], 1e-9)
<< value_in[0] << " " << value_in[1] << " " << value_in[2];
EXPECT_NEAR(value_test[2], value_in[2], 1e-9)
<< value_in[0] << " " << value_in[1] << " " << value_in[2];
}
TEST(SectorFieldTest, ConvertPositionToPolarAndCartesianTest) {
double position_in_1[3] = {1., -1., 0.};
double position_ex_1[3] = {1., -1., 0.};
__testConvertPosToPolarAndCartesian(position_in_1, position_ex_1);
double position_in_2[3] = {7., 17., 7.};
double position_ex_2[3] = {::sqrt(2.)*7., 17., 0.25*M_PI};
__testConvertPosToPolarAndCartesian(position_in_2, position_ex_2);
double position_in_3[3] = {-1., 21., 1.};
double position_ex_3[3] = {::sqrt(2.), 21., 0.75*M_PI};
__testConvertPosToPolarAndCartesian(position_in_3, position_ex_3);
double position_in_4[3] = {-1., -21., -1.};
double position_ex_4[3] = {::sqrt(2.), -21., -0.75*M_PI};
__testConvertPosToPolarAndCartesian(position_in_4, position_ex_4);
double position_in_5[3] = {1., 0., -1.};
double position_ex_5[3] = {::sqrt(2.), 0., -0.25*M_PI};
__testConvertPosToPolarAndCartesian(position_in_5, position_ex_5);
double position_in_6[3] = {0., 0., 0.};
double position_ex_6[3] = {0., 0., 0.};
__testConvertPosToPolarAndCartesian(position_in_6, position_ex_6);
}
TEST(SectorFieldTest, ConvertValueToPolarAndCartesianTest) {
double position_1[3] = {2., 0., 0.25*M_PI};
double position_2[3] = {3., -2., 0.75*M_PI};
double position_3[3] = {4., 4., 1.25*M_PI};
double position_4[3] = {5., -6., 1.75*M_PI};
double* position[4] = {position_1, position_2, position_3, position_4};
double value_in_1[3] = {1., 0., 1.};
double value_in_2[3] = {-1., -2., 1.};
double value_in_3[3] = {-1., 4., -1.};
double value_in_4[3] = {1., -6., -1.};
double* value_in[4] = {value_in_1, value_in_2, value_in_3, value_in_4};
double value_ex_2_1[3] = {0., 0., -::sqrt(2)};
double value_ex_2_2[3] = {::sqrt(2.), -2., 0.};
double value_ex_2_3[3] = {0., 4., ::sqrt(2)};
double value_ex_2_4[3] = {-::sqrt(2.), -6., 0.};
double* value_ex_2[4] =
{value_ex_2_1, value_ex_2_2, value_ex_2_3, value_ex_2_4};
double value_ex_4_1[3] = {0., 0., ::sqrt(2)};
double value_ex_4_2[3] = {-::sqrt(2.), -2., 0.};
double value_ex_4_3[3] = {0., 4., -::sqrt(2)};
double value_ex_4_4[3] = {::sqrt(2.), -6., 0.};
double* value_ex_4[4] =
{value_ex_4_1, value_ex_4_2, value_ex_4_3, value_ex_4_4};
// check for selected values
for (size_t i = 0; i < 4; ++i) {
__testConvertValueToPolarAndCartesian
(position[1], value_in[i], value_ex_2[i]);
__testConvertValueToPolarAndCartesian
(position[3], value_in[i], value_ex_4[i]);
}
// check that the routine inverts properly
for (size_t i = 0; i < 4; ++i) {
for (size_t j = 0; j < 4; ++j) {
__testConvertValueToPolarAndCartesian
(position[i], value_in[j], NULL);
}
}
}
void __testBB(const double* bb_polar_in, const double* bb_cart_expected) {
SectorFieldTestClass test;
test.SetPolarBoundingBox(bb_polar_in[0], bb_polar_in[1], bb_polar_in[2],
bb_polar_in[3], bb_polar_in[4], bb_polar_in[5]);
std::vector bb_polar_min_out = test.GetPolarBoundingBoxMin();
std::vector bb_polar_max_out = test.GetPolarBoundingBoxMax();
std::vector bb_cart_min_out = test.GetBoundingBoxMin();
std::vector bb_cart_max_out = test.GetBoundingBoxMax();
for (size_t i = 0; i < 3; ++i) {
EXPECT_NEAR(bb_polar_min_out[i], bb_polar_in[i], 1e-12);
EXPECT_NEAR(bb_polar_max_out[i], bb_polar_in[i+3], 1e-12);
}
std::string xyz[3] = {"x", "y", "z"};
for (size_t i = 0; i < 3; ++i) {
EXPECT_NEAR(bb_cart_min_out[i], bb_cart_expected[i], 1e-3)
<< xyz[i] << "-min r_min " << bb_polar_in[0] << " r_max "
<< bb_polar_in[3] << " phi_min " << bb_polar_in[2]/M_PI*180.
<< " phi_max " << bb_polar_in[5]/M_PI*180.;
EXPECT_NEAR(bb_cart_max_out[i], bb_cart_expected[i+3], 1e-3)
<< xyz[i] << "-max r_min " << bb_polar_in[0] << " r_max "
<< bb_polar_in[3] << " phi_min " << bb_polar_in[2]/M_PI*180.
<< " phi_max " << bb_polar_in[5]/M_PI*180.;
EXPECT_GT(bb_cart_max_out[i], bb_cart_min_out[i]);
}
}
TEST(SectorFieldTest, SetPolarBoundingBoxTest) {
// basic check - unit circle
double bb_polar_1[6] = {0., 0., 0., 1., 1., M_PI/2.};
double bb_cart_1[6] = {0., 0., 0., 1., 1., 1.};
__testBB(bb_polar_1, bb_cart_1);
// check coordinates are okay
double bb_polar_3[6] = {0.5, 1., M_PI*(0.75-1e-9),
1.5, 3., M_PI*(0.75+1e-9)};
double bb_cart_3[6] = {-1.5/::sqrt(2.), 1., 0.5/::sqrt(2.),
-0.5/::sqrt(2.), 3., 1.5/::sqrt(2.)};
__testBB(bb_polar_3, bb_cart_3);
// check detect axis crossing correctly
double bb_polar_2[6] = {0.5, -3., -M_PI*1.999, 1.5, 3., M_PI*1.999};
double bb_cart_2[6] = {-1.5, -3., -1.5, 1.5, 3., 1.5};
__testBB(bb_polar_2, bb_cart_2);
double bb_polar_4[6] = {0.5, 1., M_PI*(-0.25),
1.5, 3., M_PI*(0.75)};
double bb_cart_4[6] = {-1.5/::sqrt(2.), 1., -1.5/::sqrt(2.),
1.5, 3., 1.5};
__testBB(bb_polar_4, bb_cart_4);
double bb_polar_5[6] = {0.5, 1., M_PI*(-1.25),
1.5, 3., M_PI*(-0.25)};
double bb_cart_5[6] = {-1.5, 1., -1.5,
1.5/::sqrt(2.), 3., 1.5/::sqrt(2.)};
__testBB(bb_polar_5, bb_cart_5);
double bb_polar_6[6] = {0.5, 1., M_PI*(0.75),
1.5, 3., M_PI*(1.75)};
double bb_cart_6[6] = {-1.5, 1., -1.5,
1.5/::sqrt(2.), 3., 1.5/::sqrt(2.)};
__testBB(bb_polar_6, bb_cart_6);
}
TEST(SectorFieldTest, SetPolarBoundingBoxThrowTest) {
double bb_polar_0[6] = {0.5, 3., M_PI*(-0.25),
1.5, 1., M_PI*(0.75)};
double bb_polar_1[6] = {1.5, 1., M_PI*(-0.25),
0.5, 3., M_PI*(0.75)};
double bb_polar_2[6] = {-0.5, 1., M_PI*(-0.25),
0.5, 3., M_PI*(0.75)};
double bb_polar_3[6] = {1.5, 1., M_PI*(-0.25),
-0.5, 3., M_PI*(0.75)};
double bb_polar_4[6] = {1.5, 1., M_PI*(0.25),
-0.5, 3., M_PI*(-0.25)};
double bb_polar_5[6] = {1.5, 1., M_PI*(-2.1),
-0.5, 3., M_PI*(-0.25)};
double bb_polar_6[6] = {1.5, 1., M_PI*(0.),
-0.5, 3., M_PI*(2.1)};
double * bb_polar[] = {bb_polar_0, bb_polar_1, bb_polar_2, bb_polar_3,
bb_polar_4, bb_polar_5, bb_polar_6};
for (size_t i = 0; i < 7; ++i) {
SectorFieldTestClass test;
EXPECT_THROW(test.SetPolarBoundingBox(bb_polar[i][0], bb_polar[i][1],
bb_polar[i][2], bb_polar[i][3],
bb_polar[i][4], bb_polar[i][5]),
MAUS::Exceptions::Exception) << i;
}
}
}