/* 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 . */ /* Author: Peter Lane */ #include #include #include #include #include #include "CLHEP/Vector/ThreeVector.h" #include "gtest/gtest.h" #include "json/reader.h" #include "json/value.h" #include "Config/MiceModule.hh" #include "DataStructure/Global/ReconEnums.hh" #include "DataStructure/Global/TrackPoint.hh" #include "Globals/GlobalsManager.hh" #include "Optics/PhaseSpaceVector.hh" #include "Recon/Global/DataStructureHelper.hh" #include "Recon/Global/Detector.hh" #include "Utils/Exception.hh" #include "Utils/Globals.hh" using MAUS::recon::global::DataStructureHelper; namespace Recon = MAUS::recon::global; namespace GlobalDS = MAUS::DataStructure::Global; class DataStructureHelperTest : public testing::Test { public: DataStructureHelperTest() { } ~DataStructureHelperTest() { } protected: }; // ************************************************* // DataStructureHelperTest static const initializations // ************************************************* // *********** // test cases // *********** TEST_F(DataStructureHelperTest, FindModulesByName) { MiceModule root(NULL, "root"); MiceModule * orwell = new MiceModule(&root, "Orwell"); MiceModule * george_orwell = new MiceModule(orwell, "George"); MiceModule * curie = new MiceModule(&root, "Curie"); MiceModule * marie_curie = new MiceModule(curie, "Marie"); MiceModule * washington = new MiceModule(&root, "Washington"); MiceModule * george_washington = new MiceModule(washington, "George"); MiceModule * nother = new MiceModule(&root, "Nother"); MiceModule * emmy_nother = new MiceModule(curie, "Nother"); MiceModule * scott = new MiceModule(&root, "Scott"); MiceModule * c_scott = new MiceModule(scott, "C"); MiceModule * george_c_scott = new MiceModule(c_scott, "George"); root.addDaughter(orwell); orwell->addDaughter(george_orwell); root.addDaughter(curie); curie->addDaughter(marie_curie); root.addDaughter(washington); washington->addDaughter(george_washington); root.addDaughter(nother); nother->addDaughter(emmy_nother); root.addDaughter(scott); scott->addDaughter(c_scott); c_scott->addDaughter(george_c_scott); const std::vector georges = DataStructureHelper::GetInstance().FindModulesByName(&root, "George"); const size_t number_of_georges = georges.size(); ASSERT_EQ(number_of_georges, static_cast(3)); const std::string names[3] = { "root/Orwell/George", "root/Washington/George", "root/Scott/C/George" }; for (size_t index = 0; index < 3; ++index) { std::string actual_name = georges[index]->fullName(); std::string expected_name = names[index]; EXPECT_EQ(expected_name, actual_name); } } TEST_F(DataStructureHelperTest, GetDetectorZPosition) { const GlobalDS::DetectorPoint detector_ids[14] = { GlobalDS::kTOF0, GlobalDS::kTOF1, GlobalDS::kTracker0_1, GlobalDS::kTracker0_2, GlobalDS::kTracker0_3, GlobalDS::kTracker0_4, GlobalDS::kTracker0_5, GlobalDS::kTracker1_1, GlobalDS::kTracker1_2, GlobalDS::kTracker1_3, GlobalDS::kTracker1_4, GlobalDS::kTracker1_5, GlobalDS::kTOF2, GlobalDS::kEMR // used for testing unsupported detector failure }; MAUS::Globals * old_globals = MAUS::Globals::GetInstance(); // Deep copy since GlobalsManager deletes Globals' old modules // on call to SetReconstructionMiceModules() MiceModule * old_modules = MiceModule::deepCopy(*old_globals->GetReconstructionMiceModules()); MiceModule * recon_modules = new MiceModule(NULL, "root"); // *** Test missing module exception *** MAUS::GlobalsManager::SetReconstructionMiceModules(recon_modules); for (int index = 0; index < 14; ++index) { bool success = false; try { DataStructureHelper::GetInstance().GetDetectorZPosition( detector_ids[index]); } catch (MAUS::Exceptions::Exception& exc) { success = true; } EXPECT_TRUE(success); } // *** Test duplicate module exception *** recon_modules = new MiceModule(NULL, "root"); for (int index = 0; index < 3; ++index) { std::stringstream detector_name; detector_name << "TOF" << index << ".dat"; recon_modules->addDaughter( new MiceModule(recon_modules, detector_name.str())); recon_modules->addDaughter( new MiceModule(recon_modules, detector_name.str())); } for (int index = 0; index < 2; ++index) { for (int station = 0; station < 5; ++station) { std::stringstream detector_name; detector_name << "Tracker"; if (index > 0) detector_name << index; detector_name << "Station" << (station+1) << ".dat"; recon_modules->addDaughter( new MiceModule(recon_modules, detector_name.str())); recon_modules->addDaughter( new MiceModule(recon_modules, detector_name.str())); } } MAUS::GlobalsManager::SetReconstructionMiceModules(recon_modules); for (int index = 0; index < 13; ++index) { bool success = false; try { DataStructureHelper::GetInstance().GetDetectorZPosition( detector_ids[index]); } catch (MAUS::Exceptions::Exception& exc) { success = true; } EXPECT_TRUE(success); } // create a new root module since the next SetReconstructionMiceModules() call // will delete the original used during the above missing module tests recon_modules = new MiceModule(NULL, "root"); // Setup a minimal MiceModule tree manually MiceModule * tof0 = new MiceModule(recon_modules, "TOF0.dat"); tof0->addPropertyHep3Vector("Position", Hep3Vector(0., 0., -2000.)); recon_modules->addDaughter(tof0); MiceModule * tof1 = new MiceModule(recon_modules, "TOF1.dat"); tof1->addPropertyHep3Vector("Position", Hep3Vector(0., 0., -900.)); recon_modules->addDaughter(tof1); MiceModule * tof1_detector = new MiceModule(tof1, "TOF1Detector.dat"); tof1_detector->addPropertyHep3Vector("Position", Hep3Vector(0., 0., -100.)); tof1->addDaughter(tof1_detector); MiceModule * tracker0 = new MiceModule(recon_modules, "Tracker0.dat"); tracker0->addPropertyHep3Vector("Position", Hep3Vector(0., 0., 1000.)); recon_modules->addDaughter(tracker0); MiceModule * tracker0_stations[5]; for (int index = 0; index < 5; ++index) { std::stringstream detector_name; detector_name << "TrackerStation" << (index+1) << ".dat"; tracker0_stations[index] = new MiceModule(tracker0, detector_name.str()); tracker0_stations[index]->addPropertyHep3Vector("Position", Hep3Vector(0., 0., 10*(index-2))); tracker0->addDaughter(tracker0_stations[index]); MiceModule * tracker_view_w = NULL; if (index == 4) { // Station 5 tracker_view_w = new MiceModule(tracker0_stations[index], "Tracker0Station5ViewW.dat"); } else { tracker_view_w = new MiceModule(tracker0_stations[index], "TrackerViewW.dat"); } tracker_view_w->addPropertyHep3Vector("Position", Hep3Vector(0., 0., 0.)); tracker0_stations[index]->addDaughter(tracker_view_w); } MiceModule * tracker1 = new MiceModule(recon_modules, "Tracker1.dat"); tracker1->addPropertyHep3Vector("Position", Hep3Vector(0., 0., 2000.)); recon_modules->addDaughter(tracker1); MiceModule * tracker1_stations[5]; for (int index = 0; index < 5; ++index) { std::stringstream detector_name; detector_name << "Tracker1Station" << (index+1) << ".dat"; tracker1_stations[index] = new MiceModule(tracker1, detector_name.str()); tracker1_stations[index]->addPropertyHep3Vector("Position", Hep3Vector(0., 0., 10*(index-2))); tracker1->addDaughter(tracker1_stations[index]); MiceModule * tracker_view_w = new MiceModule(tracker1_stations[index], "TrackerViewW.dat"); tracker_view_w->addPropertyHep3Vector("Position", Hep3Vector(0., 0., 0.)); tracker1_stations[index]->addDaughter(tracker_view_w); } MiceModule * tof2 = new MiceModule(recon_modules, "TOF2.dat"); tof2->addPropertyHep3Vector("Position", Hep3Vector(0., 0., 3100.)); recon_modules->addDaughter(tof2); MiceModule * tof2_detector = new MiceModule(tof2, "TOF2Detector.dat"); tof2_detector->addPropertyHep3Vector("Position", Hep3Vector(0., 0., -100.)); tof2->addDaughter(tof2_detector); MAUS::GlobalsManager::SetReconstructionMiceModules(recon_modules); // *** Test getting z positions for all TOF and Tracker stations const double z_positions[13] = { -2000, -1000, // TOF0, TOF1 980, 990, 1000, 1010, 1020, // Tracker0, Station1-5 1980, 1990, 2000, 2010, 2020, // Tracker1, Station1-5 3000 // TOF2 }; for (int index = 0; index < 13; ++index) { const double detector_z = DataStructureHelper::GetInstance() .GetDetectorZPosition(detector_ids[index]); EXPECT_EQ(z_positions[index], detector_z); } // Restore the original modules MAUS::GlobalsManager::SetReconstructionMiceModules(old_modules); } TEST_F(DataStructureHelperTest, GetDetectorAttributes) { std::stringstream configuration_string; configuration_string << "{" << "\"global_recon_detector_attributes\":[" << "{" << "\"id\":2," << "\"uncertainties\":[" << "[4.0, 0.0, 0.0, 0.0, 0.0, 0.0]," << "[0.0, 1.44e7, 0.0, 0.0, 0.0, 0.0]," << "[0.0, 0.0, 300.0, 0.0, 0.0, 0.0]," << "[0.0, 0.0, 0.0, 1.0e7, 0.0, 0.0]," << "[0.0, 0.0, 0.0, 0.0, 300.0, 0.0]," << "[0.0, 0.0, 0.0, 0.0, 0.0, 1.0e7]" << "]" << "}," << "{" << "\"id\":7," << "\"uncertainties\":[" << "[4.0, 0.0, 0.0, 0.0, 0.0, 0.0]," << "[0.0, 1.44e7, 0.0, 0.0, 0.0, 0.0]," << "[0.0, 0.0, 300.0, 0.0, 0.0, 0.0]," << "[0.0, 0.0, 0.0, 1.0e7, 0.0, 0.0]," << "[0.0, 0.0, 0.0, 0.0, 300.0, 0.0]," << "[0.0, 0.0, 0.0, 0.0, 0.0, 1.0e7]" << "]" << "}]}"; MAUS::recon::global::DetectorMap detectors; bool success = true; try { const Json::Value configuration = JsonWrapper::StringToJson(configuration_string.str()); DataStructureHelper::GetInstance().GetDetectorAttributes( configuration, detectors); } catch (MAUS::Exceptions::Exception& exception) { success = false; } catch (std::exception& exc) { success = false; } ASSERT_TRUE(success); Recon::DetectorMap::iterator detector = detectors.begin(); const GlobalDS::DetectorPoint ids[2] = {GlobalDS::kTOF0, GlobalDS::kTOF1}; const double uncertainty_data[36] = { 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.44e7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 300.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0e7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 300.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0e7 }; size_t index = 0; while (detector != detectors.end()) { const GlobalDS::DetectorPoint id = detector->first; EXPECT_EQ(ids[index], id); const MAUS::CovarianceMatrix uncertainties = detector->second.uncertainties(); for (size_t row = 0; row < 6; ++row) { for (size_t column = 0; column < 6; ++column) { EXPECT_EQ(uncertainty_data[row*6+column], uncertainties(row+1, column+1)); } } ++index; ++detector; } // *** Test wrong size uncertainty matrices (GetJsonCovariance failure) *** std::stringstream bad_rows_string; bad_rows_string << "{" << "\"global_recon_detector_attributes\":[" << "{" << "\"id\":2," << "\"uncertainties\":[" << "[4.0, 0.0, 0.0, 0.0, 0.0, 0.0]," << "[0.0, 1.44e7, 0.0, 0.0, 0.0, 0.0]," << "[0.0, 0.0, 300.0, 0.0, 0.0, 0.0]," << "[0.0, 0.0, 0.0, 0.0, 300.0, 0.0]," << "[0.0, 0.0, 0.0, 0.0, 0.0, 1.0e7]" << "]" << "}]}"; success = false; try { const Json::Value configuration = JsonWrapper::StringToJson(bad_rows_string.str()); DataStructureHelper::GetInstance().GetDetectorAttributes( configuration, detectors); } catch (MAUS::Exceptions::Exception& exception) { success = true; } catch (std::exception& exc) { success = true; } ASSERT_TRUE(success); std::stringstream bad_columns_string; bad_columns_string << "{" << "\"global_recon_detector_attributes\":[" << "{" << "\"id\":2," << "\"uncertainties\":[" << "[4.0, 0.0, 0.0, 0.0, 0.0, 0.0]," << "[0.0, 1.44e7, 0.0, 0.0, 0.0, 0.0]," << "[0.0, 0.0, 300.0, 0.0, 0.0, 0.0]," << "[0.0, 0.0, 0.0, 1.0e7, 0.0]," << "[0.0, 0.0, 0.0, 0.0, 300.0, 0.0]," << "[0.0, 0.0, 0.0, 0.0, 0.0, 1.0e7]" << "]" << "}]}"; success = false; try { const Json::Value configuration = JsonWrapper::StringToJson(bad_columns_string.str()); DataStructureHelper::GetInstance().GetDetectorAttributes( configuration, detectors); } catch (MAUS::Exceptions::Exception& exception) { success = true; } catch (std::exception& exc) { success = true; } ASSERT_TRUE(success); } TEST_F(DataStructureHelperTest, TrackPoint2PhaseSpaceVector) { // t, E, x, Px, y, Py const double coordinates[6] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; GlobalDS::TrackPoint track_point; TLorentzVector position(coordinates[2], coordinates[4], 0., coordinates[0]); track_point.set_position(position); TLorentzVector momentum(coordinates[3], coordinates[5], 0., coordinates[1]); track_point.set_momentum(momentum); MAUS::PhaseSpaceVector phase_space_vector = DataStructureHelper::GetInstance() .TrackPoint2PhaseSpaceVector(track_point); for (int index = 0; index < 6; ++index) { std::cout << "Coordinate " << index << "..." << std::endl; // Order is t, E, x, Px, y, Py EXPECT_EQ(coordinates[index], phase_space_vector[index]); } } TEST_F(DataStructureHelperTest, PhaseSpaceVector2TrackPoint) { // *** Test on-mass-shell conversion *** const double positions[4] = {1.0, 3.0, 5.0, 7.0}; // x, y, z, t const double momenta[4] = {2.0, 4.0, 792.979388, 800.0}; // Px, Py, Pz, E MAUS::PhaseSpaceVector phase_space_vector(positions[3], momenta[3], positions[0], momenta[0], positions[1], momenta[1]); GlobalDS::TrackPoint track_point = DataStructureHelper::GetInstance() .PhaseSpaceVector2TrackPoint(phase_space_vector, positions[2], GlobalDS::kMuMinus); TLorentzVector position = track_point.get_position(); TLorentzVector momentum = track_point.get_momentum(); for (int index = 0; index < 4; ++index) { // Order is x, y, z, t EXPECT_NEAR(positions[index], position[index], 1.e-6); EXPECT_NEAR(momenta[index], momentum[index], 1.e-6); } // *** Test off-mass-shell conversion (Pz set to 0.) *** const double bad_momenta[4] = {2.0, 4.0, 0.0, 8.0}; // Px, Py, Pz, E phase_space_vector = MAUS::PhaseSpaceVector(positions[3], bad_momenta[3], positions[0], bad_momenta[0], positions[1], bad_momenta[1]); track_point = DataStructureHelper::GetInstance().PhaseSpaceVector2TrackPoint( phase_space_vector, positions[2], GlobalDS::kMuMinus); position = track_point.get_position(); momentum = track_point.get_momentum(); for (int index = 0; index < 4; ++index) { // Order is x, y, z, t EXPECT_NEAR(positions[index], position[index], 1.e-6); EXPECT_NEAR(bad_momenta[index], momentum[index], 1.e-6); } }