From 63bb29cec01ff315c7f0a188380a65e05e1b51d8 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Mon, 14 Aug 2023 12:31:52 -0500 Subject: [PATCH] feat: setup testing framework --- CMakeLists.txt | 1 + test/CMakeLists.txt | 73 ++++++++++++++++++++++++++++++++++++++++++++ test/read_events.cc | 10 ++++++ test/read_events.h | 59 +++++++++++++++++++++++++++++++++++ test/test_rdf.cc | 35 +++++++++++++++++++++ test/test_rdf.py | 31 +++++++++++++++++++ test/write_events.cc | 9 ++++++ test/write_events.h | 53 ++++++++++++++++++++++++++++++++ 8 files changed, 271 insertions(+) create mode 100644 test/CMakeLists.txt create mode 100644 test/read_events.cc create mode 100644 test/read_events.h create mode 100644 test/test_rdf.cc create mode 100644 test/test_rdf.py create mode 100644 test/write_events.cc create mode 100644 test/write_events.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 735947c..5e75298 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ add_library(edm4eic::edm4eicDict ALIAS edm4eicDict ) list(APPEND EDM4EIC_INSTALL_LIBS edm4eic edm4eicDict) add_subdirectory(utils) +add_subdirectory(test) install(TARGETS ${EDM4EIC_INSTALL_LIBS} EXPORT ${PROJECT_NAME}Targets diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..4d39a84 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: Apache-2.0 + +IF(NOT BUILD_TESTING) + RETURN() +ENDIF() + +function(set_test_env _testname) + set_property(TEST ${_testname} APPEND PROPERTY ENVIRONMENT + LD_LIBRARY_PATH=$:$:$<$:$:>$:$ENV{LD_LIBRARY_PATH} + ROOT_INCLUDE_PATH=${PROJECT_SOURCE_DIR}/edm4hep:${PROJECT_SOURCE_DIR}/utils/include:$ENV{ROOT_INCLUDE_PATH} + ) + set_tests_properties(${_testname} PROPERTIES + FAIL_REGULAR_EXPRESSION "[^a-z]Error;ERROR;error;Failed" + ) +endfunction() + +add_executable(write_events write_events.cc) +target_include_directories(write_events PUBLIC ${PROJECT_SOURCE_DIR}/edm4hep ) +target_link_libraries(write_events edm4hep podio::podioRootIO) +add_test(NAME write_events COMMAND write_events) +set_test_env(write_events) + +add_executable(read_events read_events.cc) +target_include_directories(read_events PUBLIC ${PROJECT_SOURCE_DIR}/edm4hep ) +target_link_libraries(read_events edm4hep podio::podioRootIO) +add_test(NAME read_events COMMAND read_events) + set_property(TEST read_events PROPERTY + DEPENDS write_events + ) +set_test_env(read_events) + +IF(TARGET ROOT::ROOTDataFrame) + add_executable(test_rdf test_rdf.cc) + target_include_directories(test_rdf PUBLIC ${PROJECT_SOURCE_DIR}/edm4hep ${PROJECT_SOURCE_DIR}/dataframe ) + target_link_libraries(test_rdf edm4hepRDF ROOT::ROOTDataFrame podio::podioRootIO) + add_test(NAME test_rdf COMMAND test_rdf) + set_test_env(test_rdf) + set_property(TEST test_rdf PROPERTY + DEPENDS write_events + ) + + add_test(NAME py_test_rdf COMMAND python ${CMAKE_CURRENT_LIST_DIR}/test_rdf.py) + set_test_env(py_test_rdf) + get_property(ENVIRONMENT TEST py_test_rdf PROPERTY ENVIRONMENT) + set_property(TEST py_test_rdf PROPERTY ENVIRONMENT + ${ENVIRONMENT} + PYTHONPATH=${PROJECT_SOURCE_DIR}/python:$ENV{PYTHONPATH} + ) + set_tests_properties(py_test_rdf PROPERTIES DEPENDS write_events) +endif() + + +find_package(HepMC3) +find_package(HepPDT) + +if(HepMC3_FOUND AND HepPDT_FOUND ) + add_executable(edm4hep_testhepmc hepmc/edm4hep_testhepmc.cc) + target_include_directories(edm4hep_testhepmc PUBLIC ${HEPMC3_INCLUDE_DIR} ${HEPPDT_INCLUDE_DIR} ) + target_link_libraries(edm4hep_testhepmc edm4hep podio::podioRootIO ${HEPPDT_LIBRARIES} ${HEPMC3_LIBRARIES}) + add_test(NAME edm4hep_testhepmc COMMAND edm4hep_testhepmc) + set_test_env(edm4hep_testhepmc) + set_property(TEST edm4hep_testhepmc APPEND PROPERTY ENVIRONMENT + ROOT_INCLUDE_PATH=${HEPMC3_INCLUDE_DIR}:$ENV{ROOT_INCLUDE_PATH} + ) +endif() + +if (nlohmann_json_FOUND) + add_test(NAME convert_events COMMAND edm4hep2json edm4hep_events.root) + set_property(TEST convert_events PROPERTY DEPENDS write_events) + set_test_env(convert_events) +endif() + +add_subdirectory(utils) \ No newline at end of file diff --git a/test/read_events.cc b/test/read_events.cc new file mode 100644 index 0000000..9d01d47 --- /dev/null +++ b/test/read_events.cc @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: Apache-2.0 + +#include "read_events.h" +#include "podio/ROOTFrameReader.h" + +int main() { + read_events("edm4eic_events.root"); + + return 0; +} diff --git a/test/read_events.h b/test/read_events.h new file mode 100644 index 0000000..fbd2d31 --- /dev/null +++ b/test/read_events.h @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: Apache-2.0 + +#ifndef EDM4EIC_TEST_READ_EVENTS_H__ +#define EDM4EIC_TEST_READ_EVENTS_H__ + +// test data model +#include "edm4eic/RawTrackerHitCollection.h" + +// podio specific includes +#include "podio/Frame.h" + +// STL +#include +#include +#include +#include + +void processEvent(const podio::Frame& event, bool verboser, unsigned eventNum) { + auto& raw_hits = event.get("RawTrackerHits"); + + if (raw_hits.isValid()) { + + //-------- print particles for debugging: + + std::cout << "\n collection: " + << "RawTrackerHits" + << " of type " << raw_hits.getValueTypeName() << "\n\n" + << raw_hits << std::endl; + //------------------------------- + + // check a few things (to be completed ...) + auto raw_hit = raw_hits[0]; + if (raw_hit.getCellID() != 0x0123456789abcdefLL) + throw std::runtime_error("wrong CellID for first hit - should be 0x0123456789abcdefLL "); + + } else { + throw std::runtime_error("Collection 'RawTrackerHits' should be present"); + } + + //=============================================================================== + + const auto& evtType = event.getParameter("EventType"); + std::cout << "Event Type: " << evtType << std::endl; +} + +template +void read_events(const std::string& filename) { + ReaderT reader; + reader.openFile(filename); + + unsigned nEvents = reader.getEntries("events"); + for (unsigned i = 0; i < nEvents; ++i) { + std::cout << "reading event " << i << std::endl; + const auto event = podio::Frame(reader.readNextEntry("events")); + processEvent(event, true, i); + } +} + +#endif diff --git a/test/test_rdf.cc b/test/test_rdf.cc new file mode 100644 index 0000000..9feecc9 --- /dev/null +++ b/test/test_rdf.cc @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 + +#include "edm4eic/utils/dataframe.h" + +#include "edm4eic/RawTrackerHitData.h" + +#include + +#include + +int main(int argc, char* argv[]) { + + ROOT::EnableImplicitMT(); + + std::cout << "Create RDataFrame ..." << std::endl; + + ROOT::RDataFrame df("events", "edm4eic_events.root"); + + std::cout << "Apply selectors and define new branches ..." << std::endl; + auto df2 = df.Define("MCParticles_pt", edm4eic::utils::pt, {"MCParticles"}) + .Define("MCParticles_eta", edm4eic::utils::eta, {"MCParticles"}) + .Define("MCParticles_cosTheta", edm4eic::utils::cos_theta, {"MCParticles"}) + .Define("SimTrackerHits_r", edm4eic::utils::r, {"SimTrackerHits"}) + .Define("SimTrackerHit_pt", edm4eic::utils::pt, {"SimTrackerHits"}) + .Define("TrackerHits_r", edm4eic::utils::r, {"TrackerHitPlanes"}); + + std::string outfilename = "edm4eic_events_rdf.root"; + std::cout << "Writing snapshot to disk ... \t" << outfilename << std::endl; + + df2.Snapshot("events", outfilename, + {"MCParticles_pt", "MCParticles_eta", "MCParticles_cosTheta", "SimTrackerHits_r", "SimTrackerHit_pt", + "TrackerHits_r"}); + + return 0; +} diff --git a/test/test_rdf.py b/test/test_rdf.py new file mode 100644 index 0000000..e4d8e04 --- /dev/null +++ b/test/test_rdf.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 + +# SPDX-License-Identifier: Apache-2.0 + +import ROOT +import edm4eic + +ROOT.EnableImplicitMT() + +print('Create RDataFrame ...') +df = ROOT.RDataFrame('events', 'edm4eic_events.root') + +print('Apply selectors and define new branches ...') +df2 = (df.Define('MCParticles_pt', 'edm4eic::utils::pt(MCParticles)') + .Define('MCParticles_eta', 'edm4eic::utils::eta(MCParticles)') + .Define('MCParticles_cosTheta', 'edm4eic::utils::cos_theta(MCParticles)') + .Define('SimTrackerHits_r', 'edm4eic::utils::r(SimTrackerHits)') + .Define('SimTrackerHits_pt', 'edm4eic::utils::pt(SimTrackerHits)') + .Define('TrackerHits_r', 'edm4eic::utils::r(TrackerHitPlanes)') + ) + +filename = 'edm4eic_events_py_rdf.root' +print(f'Writing snapshot to disk ... \t{filename}') + +df2.Snapshot('events', filename, + ['MCParticles_pt', + 'MCParticles_eta', + 'MCParticles_cosTheta', + 'SimTrackerHits_r', + 'SimTrackerHits_pt', + 'TrackerHits_r']) diff --git a/test/write_events.cc b/test/write_events.cc new file mode 100644 index 0000000..05f6eb4 --- /dev/null +++ b/test/write_events.cc @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: Apache-2.0 + +#include "write_events.h" +#include "podio/ROOTFrameWriter.h" + +int main(int argc, char* argv[]) { + + write("edm4eic_events.root"); +} diff --git a/test/write_events.h b/test/write_events.h new file mode 100644 index 0000000..ee19521 --- /dev/null +++ b/test/write_events.h @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 + +#ifndef EDM4EIC_TEST_WRITE_EVENTS_H +#define EDM4EIC_TEST_WRITE_EVENTS_H + +// Data model +#include "edm4eic/RawTrackerHitCollection.h" + +// STL +#include +#include + +// podio specific includes +#include "podio/Frame.h" + +template +void write(std::string outfilename) { + std::cout << "start processing" << std::endl; + + WriterT writer(outfilename); + + unsigned nevents = 10; + + // =============== event loop ================================ + for (unsigned i = 0; i < nevents; ++i) { + std::cout << " --- processing event " << i << std::endl; + auto event = podio::Frame(); + + auto raw_hits = edm4eic::RawTrackerHitCollection(); + auto raw_hit = raw_hits.create(); + raw_hit.setCellID(0x0123456789abcdefLL); + raw_hit.setCharge(0x01234567); + raw_hit.setTimeStamp(0x89abcdef); + + //-------- print hits for debugging: + std::cout << "\n collection: " + << "RawTrackerHits" + << " of type " << raw_hits.getValueTypeName() << "\n\n" + << raw_hits << std::endl; + + event.put(std::move(raw_hits), "RawTrackerHits"); + + //=============================================================================== + + event.putParameter("EventType", "test"); + + writer.writeFrame(event, "events"); + } + + writer.finish(); +} + +#endif \ No newline at end of file