diff --git a/test/form/CMakeLists.txt b/test/form/CMakeLists.txt index 252817701..65f6e36ed 100644 --- a/test/form/CMakeLists.txt +++ b/test/form/CMakeLists.txt @@ -12,6 +12,7 @@ if(FORM_USE_ROOT_STORAGE) form_test_data_products TEST_ARGS "${CMAKE_CURRENT_BINARY_DIR}/toy.root" + "${CMAKE_CURRENT_BINARY_DIR}/toy_checksums.txt" ) target_include_directories(WriteVector PRIVATE ${PROJECT_SOURCE_DIR}/form) @@ -24,6 +25,7 @@ if(FORM_USE_ROOT_STORAGE) form_test_data_products TEST_ARGS "${CMAKE_CURRENT_BINARY_DIR}/toy.root" + "${CMAKE_CURRENT_BINARY_DIR}/toy_checksums.txt" TEST_PROPERTIES DEPENDS WriteVector diff --git a/test/form/reader.cpp b/test/form/reader.cpp index e27569bad..8d424732d 100644 --- a/test/form/reader.cpp +++ b/test/form/reader.cpp @@ -5,7 +5,10 @@ #include "form/technology.hpp" #include "test_helpers.hpp" -#include +#include +#include +#include +#include #include static int const NUMBER_EVENT = 4; @@ -13,12 +16,53 @@ static int const NUMBER_SEGMENT = 15; static char const* const evt_id = "[EVENT=%08X]"; static char const* const seg_id = "[EVENT=%08X;SEG=%08X]"; +static float const TOLERANCE = 1e-3f; + +// Structs to hold expected checksums +struct SegChecksum { + float check; + float cpx, cpy, cpz; +}; + +struct EvtChecksum { + float check; +}; int main(int argc, char** argv) { std::cout << "In main" << std::endl; std::string const filename = (argc > 1) ? argv[1] : "toy.root"; + std::string const checksum_filename = (argc > 2) ? argv[2] : "toy_checksums.txt"; + + // Load expected checksums from file + std::map, SegChecksum> expected_seg; + std::map expected_evt; + + std::ifstream checksum_file(checksum_filename); + if (!checksum_file.is_open()) { + std::cerr << "ERROR: Could not open checksum file: " << checksum_filename << std::endl; + return 1; + } + + std::string line; + while (std::getline(checksum_file, line)) { + std::istringstream iss(line); + std::string type; + iss >> type; + if (type == "SEG") { + int nevent, nseg; + SegChecksum cs; + iss >> nevent >> nseg >> cs.check >> cs.cpx >> cs.cpy >> cs.cpz; + expected_seg[{nevent, nseg}] = cs; + } else if (type == "EVT") { + int nevent; + EvtChecksum cs; + iss >> nevent >> cs.check; + expected_evt[nevent] = cs; + } + } + checksum_file.close(); // TODO: Read configuration from config file instead of hardcoding form::experimental::config::output_item_config output_config; @@ -31,6 +75,8 @@ int main(int argc, char** argv) form::experimental::form_interface form(output_config, tech_config); + bool all_passed = true; + for (int nevent = 0; nevent < NUMBER_EVENT; nevent++) { std::cout << "PHLEX: Read Event No. " << nevent << std::endl; @@ -82,6 +128,30 @@ int main(int argc, char** argv) std::cout << "PHLEX: Segment = " << nseg << ": seg_id_text = " << seg_id_text << ", checkPoints = " << checkPoints << std::endl; + // Verify segment checksums + auto key = std::make_pair(nevent, nseg); + if (expected_seg.count(key)) { + auto const& exp = expected_seg[key]; + bool seg_ok = (std::fabs(check - exp.check) <= TOLERANCE) && + (std::fabs(checkPoints.getX() - exp.cpx) <= TOLERANCE) && + (std::fabs(checkPoints.getY() - exp.cpy) <= TOLERANCE) && + (std::fabs(checkPoints.getZ() - exp.cpz) <= TOLERANCE); + if (seg_ok) { + std::cout << "VERIFY PASS: event=" << nevent << " seg=" << nseg << std::endl; + } else { + std::cerr << "VERIFY FAIL: event=" << nevent << " seg=" << nseg + << " expected check=" << exp.check << " got=" << check + << " expected cpx=" << exp.cpx << " got=" << checkPoints.getX() + << " expected cpy=" << exp.cpy << " got=" << checkPoints.getY() + << " expected cpz=" << exp.cpz << " got=" << checkPoints.getZ() << std::endl; + all_passed = false; + } + } else { + std::cerr << "VERIFY FAIL: no expected checksum for event=" << nevent << " seg=" << nseg + << std::endl; + all_passed = false; + } + delete track_start_x; delete track_n_hits; delete start_points; @@ -106,11 +176,34 @@ int main(int argc, char** argv) check += val; std::cout << "PHLEX: Event = " << nevent << ": evt_id_text = " << evt_id_text << ", check = " << check << std::endl; + + // Verify event checksum + if (expected_evt.count(nevent)) { + auto const& exp = expected_evt[nevent]; + bool evt_ok = (std::fabs(check - exp.check) <= TOLERANCE); + if (evt_ok) { + std::cout << "VERIFY PASS: event=" << nevent << std::endl; + } else { + std::cerr << "VERIFY FAIL: event=" << nevent << " expected check=" << exp.check + << " got=" << check << std::endl; + all_passed = false; + } + } else { + std::cerr << "VERIFY FAIL: no expected checksum for event=" << nevent << std::endl; + all_passed = false; + } + delete track_x; //FIXME: PHLEX owns this memory! std::cout << "PHLEX: Read Event done " << nevent << std::endl; } - std::cout << "PHLEX: Read done " << std::endl; - return 0; + // Report overall result + if (all_passed) { + std::cout << "PHLEX: All verification checks PASSED." << std::endl; + return 0; + } else { + std::cerr << "PHLEX: Some verification checks FAILED." << std::endl; + return 1; + } } diff --git a/test/form/writer.cpp b/test/form/writer.cpp index 91a74fefc..454622231 100644 --- a/test/form/writer.cpp +++ b/test/form/writer.cpp @@ -7,6 +7,8 @@ #include "toy_tracker.hpp" #include +#include +#include #include #include @@ -35,6 +37,7 @@ int main(int argc, char** argv) srand(time(0)); std::string const filename = (argc > 1) ? argv[1] : "toy.root"; + std::string const checksum_filename = (argc > 2) ? argv[2] : "toy_checksums.txt"; // TODO: Read configuration from config file instead of hardcoding form::experimental::config::output_item_config output_config; @@ -55,6 +58,13 @@ int main(int argc, char** argv) ToyTracker tracker(4 * 1024); + // Open checksum file for writing + std::ofstream checksum_file(checksum_filename); + if (!checksum_file.is_open()) { + std::cerr << "ERROR: Could not open checksum file: " << checksum_filename << std::endl; + return 1; + } + for (int nevent = 0; nevent < NUMBER_EVENT; nevent++) { std::cout << "PHLEX: Write Event No. " << nevent << std::endl; @@ -106,6 +116,10 @@ int main(int argc, char** argv) form.write(creator, segment_id, products); + // Save segment checksums + checksum_file << std::setprecision(10) << "SEG " << nevent << " " << nseg << " " << check + << " " << checkPoints.getX() << " " << checkPoints.getY() << " " + << checkPoints.getZ() << "\n"; track_x.insert(track_x.end(), track_start_x.begin(), track_start_x.end()); } @@ -129,9 +143,12 @@ int main(int argc, char** argv) form.write(creator, event_id, pb); + // Save event checksum + checksum_file << std::setprecision(10) << "EVT " << nevent << " " << check << "\n"; std::cout << "PHLEX: Write Event done " << nevent << std::endl; } - std::cout << "PHLEX: Write done " << std::endl; + checksum_file.close(); + std::cout << "PHLEX: Write done. Checksums saved to " << checksum_filename << std::endl; return 0; }