/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/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 "src/common_cpp/DataStructure/ThreeVector.hh" #include "src/common_cpp/DataStructure/SciFiSpacePoint.hh" #include "src/common_cpp/DataStructure/SciFiHelicalPRTrack.hh" #include "src/common_cpp/Recon/SciFi/SciFiTools.hh" namespace MAUS { class SciFiToolsTest : public ::testing::Test { protected: SciFiToolsTest() {} virtual ~SciFiToolsTest() {} }; TEST_F(SciFiToolsTest, test_calc_circle_residual) { SciFiSpacePoint *sp = new SciFiSpacePoint(); ThreeVector pos(1.0, 4.0, 0.0); sp->set_position(pos); double xc = 3.0; double yc = 2.0; double r = 2.0; double delta = SciFiTools::calc_circle_residual(sp, xc, yc, r); EXPECT_NEAR(0.8284, delta, 0.01); } TEST_F(SciFiToolsTest, test_calc_xy_pulls) { // Test the spacepoint pull calculation using a circle of rad = 5, centered on (0, 0) SciFiHelicalPRTrack* trk = new SciFiHelicalPRTrack(); trk->set_circle_x0(0.0); trk->set_circle_y0(0.0); trk->set_R(5.0); // Set up spacepoints which lie exactly (to 4 sig fig) on this circle std::vector spnts; for (int i = 0; i < 4; ++i) { spnts.push_back(new SciFiSpacePoint); spnts[i]->set_prxy_pull(-1.0); } spnts[0]->set_position(ThreeVector(1.0, 4.899, 0.0)); spnts[1]->set_position(ThreeVector(2.0, 4.583, 0.0)); spnts[2]->set_position(ThreeVector(3.0, 4.0, 0.0)); spnts[3]->set_position(ThreeVector(4.0, 3.0, 0.0)); trk->set_spacepoints_pointers(spnts); bool result = SciFiTools::calc_xy_pulls(trk); EXPECT_TRUE(result); // Check the pulls are all 0 for (auto sp : spnts) { EXPECT_NEAR(0.0, sp->get_prxy_pull(), 0.1); } // Clean up for (auto sp : spnts) { delete sp; } delete trk; } TEST_F(SciFiToolsTest, test_make_3pt_circle) { SciFiSpacePoint *sp1 = new SciFiSpacePoint(); SciFiSpacePoint *sp2 = new SciFiSpacePoint(); SciFiSpacePoint *sp3 = new SciFiSpacePoint(); // Set up spacepoints corresponding to circle of radius 2 mm, centred at (1,2) ThreeVector pos(1.0, 4.0, 0.0); sp1->set_position(pos); pos.set(3.0, 2.0, 0.0); sp2->set_position(pos); pos.set(1.0, 0.0, 0.0); sp3->set_position(pos); SimpleCircle c = SciFiTools::make_3pt_circle(sp1, sp2, sp3); double x0 = 1.0; double y0 = 2.0; double R = 2.0; double epsilon = 0.01; EXPECT_NEAR(c.get_x0(), x0, epsilon); EXPECT_NEAR(c.get_y0(), y0, epsilon); EXPECT_NEAR(c.get_R(), R, epsilon); // Now check for a circle of radius 2mm, centred at (0,0) (involves singular matrices) pos.set(0.0, 2.0, 0.0); sp1->set_position(pos); pos.set(2.0, 0.0, 0.0); sp2->set_position(pos); pos.set(0.0, -2.0, 0.0); sp3->set_position(pos); c = SciFiTools::make_3pt_circle(sp1, sp2, sp3); x0 = 0.0; y0 = 0.0; R = 2.0; epsilon = 0.01; EXPECT_NEAR(c.get_x0(), x0, epsilon); EXPECT_NEAR(c.get_y0(), y0, epsilon); EXPECT_NEAR(c.get_R(), R, epsilon); delete sp1; delete sp2; delete sp3; } TEST_F(SciFiToolsTest, test_sort_by_station) { SciFiSpacePoint *sp1 = new SciFiSpacePoint(); SciFiSpacePoint *sp2 = new SciFiSpacePoint(); SciFiSpacePoint *sp3 = new SciFiSpacePoint(); SciFiSpacePoint *sp4 = new SciFiSpacePoint(); SciFiSpacePoint *sp5 = new SciFiSpacePoint(); sp1->set_station(1); sp2->set_station(2); sp3->set_station(3); sp4->set_station(4); sp5->set_station(5); std::vector spnts; spnts.push_back(sp5); spnts.push_back(sp2); spnts.push_back(sp3); spnts.push_back(sp1); spnts.push_back(sp4); std::vector< std::vector > spnts_by_station(5); SciFiTools::sort_by_station(spnts, spnts_by_station); EXPECT_EQ(sp1, spnts_by_station[0][0]); EXPECT_EQ(sp2, spnts_by_station[1][0]); EXPECT_EQ(sp3, spnts_by_station[2][0]); EXPECT_EQ(sp4, spnts_by_station[3][0]); EXPECT_EQ(sp5, spnts_by_station[4][0]); delete sp1; delete sp2; delete sp3; delete sp4; delete sp5; } TEST_F(SciFiToolsTest, test_stations_with_unused_sp) { // Set up spacepoints, leaving station 3 empty to check function copes with an empty station SciFiSpacePoint *sp1 = new SciFiSpacePoint(); SciFiSpacePoint *sp2 = new SciFiSpacePoint(); // SciFiSpacePoint *sp3 = new SciFiSpacePoint(); SciFiSpacePoint *sp4 = new SciFiSpacePoint(); SciFiSpacePoint *sp4_1 = new SciFiSpacePoint(); SciFiSpacePoint *sp5 = new SciFiSpacePoint(); sp1->set_station(1); sp2->set_station(2); // sp3->set_station(3); sp4->set_station(4); sp4_1->set_station(4); sp5->set_station(5); sp1->set_used(true); sp2->set_used(true); // sp3->set_used(true); sp4->set_used(false); sp4_1->set_used(true); sp5->set_used(false); std::vector spnts; spnts.push_back(sp5); spnts.push_back(sp2); // spnts.push_back(sp3); spnts.push_back(sp1); spnts.push_back(sp4); spnts.push_back(sp4_1); SpacePoint2dPArray spnts_by_station(5); SciFiTools::sort_by_station(spnts, spnts_by_station); ASSERT_EQ(5u, spnts_by_station.size()); ASSERT_EQ(1u, spnts_by_station[0].size()); ASSERT_EQ(1u, spnts_by_station[1].size()); ASSERT_EQ(2u, spnts_by_station[3].size()); ASSERT_EQ(1u, spnts_by_station[4].size()); std::vector stations_hit, stations_not_hit; SciFiTools::stations_with_unused_spnts(spnts_by_station, stations_hit, stations_not_hit); ASSERT_EQ(2u, stations_hit.size()); ASSERT_EQ(3u, stations_not_hit.size()); EXPECT_EQ(3, stations_hit[0]); EXPECT_EQ(4, stations_hit[1]); EXPECT_EQ(0, stations_not_hit[0]); EXPECT_EQ(1, stations_not_hit[1]); EXPECT_EQ(2, stations_not_hit[2]); int stats_with_unused = SciFiTools::num_stations_with_unused_spnts(spnts_by_station); EXPECT_EQ(2, stats_with_unused); delete sp1; delete sp2; delete sp4; delete sp4_1; delete sp5; } } // ~namespace MAUS