From d6e76ce8a1c863d1784d8ae03ee810f53fe185d2 Mon Sep 17 00:00:00 2001 From: Nathan Brei Date: Tue, 18 Jun 2024 13:06:55 -0400 Subject: [PATCH 1/2] Skeleton of timeframe splitter --- src/global/CMakeLists.txt | 1 + src/global/splitting/CMakeLists.txt | 37 +++++++++++++++ src/global/splitting/TimeframeSplitter.h | 47 +++++++++++++++++++ src/global/splitting/splitting.cc | 30 ++++++++++++ .../io/podio/JEventSourcePODIO_generator.h | 36 ++++++++++++++ src/services/io/podio/podio.cc | 5 +- src/utilities/eicrecon/eicrecon.cc | 1 + 7 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 src/global/splitting/CMakeLists.txt create mode 100644 src/global/splitting/TimeframeSplitter.h create mode 100644 src/global/splitting/splitting.cc create mode 100644 src/services/io/podio/JEventSourcePODIO_generator.h diff --git a/src/global/CMakeLists.txt b/src/global/CMakeLists.txt index 4d12e01fc8..72ad0cea07 100644 --- a/src/global/CMakeLists.txt +++ b/src/global/CMakeLists.txt @@ -5,3 +5,4 @@ add_subdirectory(reco) add_subdirectory(pid) add_subdirectory(pid_lut) add_subdirectory(beam) +add_subdirectory(splitting) diff --git a/src/global/splitting/CMakeLists.txt b/src/global/splitting/CMakeLists.txt new file mode 100644 index 0000000000..285b0f2e9f --- /dev/null +++ b/src/global/splitting/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.16) + +get_filename_component(PLUGIN_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) + +# Function creates ${PLUGIN_NAME}_plugin and ${PLUGIN_NAME}_library targets +# Setting default includes, libraries and installation paths +plugin_add(${PLUGIN_NAME} PLUGIN_USE_CC_ONLY) + +# The macro grabs sources as *.cc *.cpp *.c and headers as *.h *.hh *.hpp Then +# correctly sets sources for ${_name}_plugin and ${_name}_library targets Adds +# headers to the correct installation directory +plugin_glob_all(${PLUGIN_NAME}) + +# Find dependencies +#plugin_add_dd4hep(${PLUGIN_NAME}#) +#plugin_add_acts(${PLUGIN_NAME}) +#plugin_add_cern_root(${PLUGIN_NAME}) +plugin_add_event_model(${PLUGIN_NAME}) + +# Add include directories (works same as target_include_directories) +# plugin_include_directories(${PLUGIN_NAME} SYSTEM PUBLIC ... ) + +# Add libraries (same as target_include_directories but for both plugin and +# library) +plugin_link_libraries(${PLUGIN_NAME} + algorithms_digi_library + algorithms_tracking_library) +# +# Add include directories (works same as target_include_directories) +# plugin_include_directories(${PLUGIN_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR} +# SYSTEM PUBLIC ${podio_INCLUDE_DIR} ${EDM4HEP_INCLUDE_DIR} +# ${DD4hep_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} ${EDM4EIC_INCLUDE_DIRS}) +# +# Add libraries (works same as target_include_directories) +# plugin_link_libraries(${PLUGIN_NAME} ${ROOT_LIBRARIES} +# algorithms_tracking_library EDM4HEP::edm4hep EDM4EIC::edm4eic spdlog::spdlog +# Boost::boost ${ROOT_EG_LIBRARY}) diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h new file mode 100644 index 0000000000..2245713d71 --- /dev/null +++ b/src/global/splitting/TimeframeSplitter.h @@ -0,0 +1,47 @@ +// Copyright 2024, Jefferson Science Associates, LLC. +// Subject to the terms in the LICENSE file found in the top-level directory. + +#pragma once + +#include + +struct TimeframeSplitter : public JEventUnfolder { + + // PodioInput m_timeslice_clusters_in {this, {.name = "ts_protoclusters", .level = JEventLevel::Timeslice}}; + + // PodioOutput m_event_clusters_out {this, "evt_protoclusters"}; + // PodioOutput m_event_info_out {this, "evt_info"}; + + TimeframeSplitter() { + SetTypeName(NAME_OF_THIS); + SetParentLevel(JEventLevel::Timeslice); + SetChildLevel(JEventLevel::PhysicsEvent); + } + + + Result Unfold(const JEvent& parent, JEvent& child, int child_idx) override { + + auto timeslice_nr = parent.GetEventNumber(); + size_t event_nr = 100*timeslice_nr + child_idx; + child.SetEventNumber(event_nr); + + // For now, a one-to-one relationship between timeslices and events + + /* + auto event_clusters_out = std::make_unique(); + event_clusters_out->setSubsetCollection(true); + event_clusters_out->push_back(m_timeslice_clusters_in()->at(child_idx)); + + auto event_info_out = std::make_unique(); + event_info_out->push_back(MutableEventInfo(event_nr, timeslice_nr, 0)); + + m_event_clusters_out() = std::move(event_clusters_out); + m_event_info_out() = std::move(event_info_out); + */ + + return (child_idx == 2) ? Result::NextChildNextParent : Result::NextChildKeepParent; + } +}; + + + diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc new file mode 100644 index 0000000000..ed09d9cec5 --- /dev/null +++ b/src/global/splitting/splitting.cc @@ -0,0 +1,30 @@ +// Copyright 2024, Jefferson Science Associates, LLC. +// Subject to the terms in the LICENSE file found in the top-level directory. + + +#include "TimeframeSplitter.h" +#include + + +extern "C"{ +void InitPlugin(JApplication *app) { + + InitJANAPlugin(app); + + // Unfolder that takes timeframes and splits them into physics events. + app->Add(new TimeframeSplitter()); + + // Factory that produces timeslice-level protoclusters from timeslice-level hits + /* + app->Add(new JOmniFactoryGeneratorT( + { .tag = "timeslice_protoclusterizer", + .level = JEventLevel::Timeslice, + .input_names = {"hits"}, + .output_names = {"ts_protoclusters"} + })); + */ + +} +} // "C" + + diff --git a/src/services/io/podio/JEventSourcePODIO_generator.h b/src/services/io/podio/JEventSourcePODIO_generator.h new file mode 100644 index 0000000000..c790d4a8e0 --- /dev/null +++ b/src/services/io/podio/JEventSourcePODIO_generator.h @@ -0,0 +1,36 @@ + + +#include +#include "JEventSourcePODIO.h" + + +class JEventSourcePODIO_generator : public JEventSourceGenerator { + + JEventSource* MakeJEventSource(std::string resource_name) override { + + auto* source = new JEventSourcePODIO(resource_name, nullptr); + source->SetResourceName(resource_name); + + // Check if the string "timeslices" appears anywhere in our filename. + // If so, we assume the file contains timeslices, otherwise it contains physics events. + // Another approach might be to peek at the file's contents + if (resource_name.find("timeslices") != std::string::npos) { + source->SetLevel(JEventLevel::Timeslice); + } + else { + source->SetLevel(JEventLevel::PhysicsEvent); + } + return source; + } + + double CheckOpenable(std::string resource_name) override { + // In theory, we should check whether PODIO can open the file and + // whether it contains an 'events' or 'timeslices' tree. If not, return 0. + if (resource_name.find(".root") != std::string::npos) { + return 0.01; + } + return 0; + } +}; + + diff --git a/src/services/io/podio/podio.cc b/src/services/io/podio/podio.cc index 829527f104..d60b03781a 100644 --- a/src/services/io/podio/podio.cc +++ b/src/services/io/podio/podio.cc @@ -4,17 +4,16 @@ // #include -#include #include "JEventProcessorPODIO.h" -#include "JEventSourcePODIO.h" +#include "JEventSourcePODIO_generator.h" // Make this a JANA plugin extern "C" { void InitPlugin(JApplication *app) { InitJANAPlugin(app); - app->Add(new JEventSourceGeneratorT()); + app->Add(new JEventSourcePODIO_generator); // Disable this behavior for now so one can run eicrecon with only the // input file as an argument. diff --git a/src/utilities/eicrecon/eicrecon.cc b/src/utilities/eicrecon/eicrecon.cc index e8c75c6948..7783007464 100644 --- a/src/utilities/eicrecon/eicrecon.cc +++ b/src/utilities/eicrecon/eicrecon.cc @@ -49,6 +49,7 @@ std::vector EICRECON_DEFAULT_PLUGINS = { "LUMISPECCAL", "podio", "janatop", + "splitter" }; int main( int narg, char **argv) From b84b54d83e0ec5383b5e1797da5e69a47f58d8ce Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:22:16 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/global/splitting/CMakeLists.txt | 11 ++++------- src/global/splitting/TimeframeSplitter.h | 3 --- src/global/splitting/splitting.cc | 6 ++---- src/services/io/podio/JEventSourcePODIO_generator.h | 6 ++---- 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/global/splitting/CMakeLists.txt b/src/global/splitting/CMakeLists.txt index 285b0f2e9f..55aed9ba3f 100644 --- a/src/global/splitting/CMakeLists.txt +++ b/src/global/splitting/CMakeLists.txt @@ -11,10 +11,8 @@ plugin_add(${PLUGIN_NAME} PLUGIN_USE_CC_ONLY) # headers to the correct installation directory plugin_glob_all(${PLUGIN_NAME}) -# Find dependencies -#plugin_add_dd4hep(${PLUGIN_NAME}#) -#plugin_add_acts(${PLUGIN_NAME}) -#plugin_add_cern_root(${PLUGIN_NAME}) +# Find dependencies plugin_add_dd4hep(${PLUGIN_NAME}#) +# plugin_add_acts(${PLUGIN_NAME}) plugin_add_cern_root(${PLUGIN_NAME}) plugin_add_event_model(${PLUGIN_NAME}) # Add include directories (works same as target_include_directories) @@ -22,9 +20,8 @@ plugin_add_event_model(${PLUGIN_NAME}) # Add libraries (same as target_include_directories but for both plugin and # library) -plugin_link_libraries(${PLUGIN_NAME} - algorithms_digi_library - algorithms_tracking_library) +plugin_link_libraries(${PLUGIN_NAME} algorithms_digi_library + algorithms_tracking_library) # # Add include directories (works same as target_include_directories) # plugin_include_directories(${PLUGIN_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR} diff --git a/src/global/splitting/TimeframeSplitter.h b/src/global/splitting/TimeframeSplitter.h index 2245713d71..5f82d00c46 100644 --- a/src/global/splitting/TimeframeSplitter.h +++ b/src/global/splitting/TimeframeSplitter.h @@ -42,6 +42,3 @@ struct TimeframeSplitter : public JEventUnfolder { return (child_idx == 2) ? Result::NextChildNextParent : Result::NextChildKeepParent; } }; - - - diff --git a/src/global/splitting/splitting.cc b/src/global/splitting/splitting.cc index ed09d9cec5..acce6b2440 100644 --- a/src/global/splitting/splitting.cc +++ b/src/global/splitting/splitting.cc @@ -17,14 +17,12 @@ void InitPlugin(JApplication *app) { // Factory that produces timeslice-level protoclusters from timeslice-level hits /* app->Add(new JOmniFactoryGeneratorT( - { .tag = "timeslice_protoclusterizer", + { .tag = "timeslice_protoclusterizer", .level = JEventLevel::Timeslice, - .input_names = {"hits"}, + .input_names = {"hits"}, .output_names = {"ts_protoclusters"} })); */ } } // "C" - - diff --git a/src/services/io/podio/JEventSourcePODIO_generator.h b/src/services/io/podio/JEventSourcePODIO_generator.h index c790d4a8e0..a6df6e762d 100644 --- a/src/services/io/podio/JEventSourcePODIO_generator.h +++ b/src/services/io/podio/JEventSourcePODIO_generator.h @@ -11,7 +11,7 @@ class JEventSourcePODIO_generator : public JEventSourceGenerator { auto* source = new JEventSourcePODIO(resource_name, nullptr); source->SetResourceName(resource_name); - // Check if the string "timeslices" appears anywhere in our filename. + // Check if the string "timeslices" appears anywhere in our filename. // If so, we assume the file contains timeslices, otherwise it contains physics events. // Another approach might be to peek at the file's contents if (resource_name.find("timeslices") != std::string::npos) { @@ -24,7 +24,7 @@ class JEventSourcePODIO_generator : public JEventSourceGenerator { } double CheckOpenable(std::string resource_name) override { - // In theory, we should check whether PODIO can open the file and + // In theory, we should check whether PODIO can open the file and // whether it contains an 'events' or 'timeslices' tree. If not, return 0. if (resource_name.find(".root") != std::string::npos) { return 0.01; @@ -32,5 +32,3 @@ class JEventSourcePODIO_generator : public JEventSourceGenerator { return 0; } }; - -