-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #192 from JeffersonLab/nbrei_podio
WIP: PODIO integration
- Loading branch information
Showing
32 changed files
with
1,336 additions
and
109 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
|
||
# Docker image for testing JANA/PODIO integration | ||
|
||
FROM rootproject/root:latest | ||
#root:6.26.10-ubuntu22.04 | ||
|
||
USER root | ||
RUN mkdir /app | ||
WORKDIR /app | ||
|
||
RUN apt update -y \ | ||
&& apt install -y build-essential gdb valgrind cmake wget unzip vim libasan6 less exa bat git zlib1g-dev pip | ||
|
||
#ENV JANA_HOME /app/JANA2/install | ||
|
||
#RUN git clone -b nbrei_podio https://github.com/JeffersonLab/JANA2 /app/JANA2 | ||
#RUN git clone -b v00-16-02 https://github.com/AIDASoft/podio /app/podio | ||
RUN git clone -b nbrei_jana_integration https://github.com/nathanwbrei/podio /app/podio | ||
|
||
# RUN cd /app/JANA2 \ | ||
# && mkdir build install \ | ||
# && cmake -S . -B build \ | ||
# && cmake --build build -j 10 --target install | ||
|
||
RUN apt install -y libyaml-dev \ | ||
&& pip install jinja2 pyyaml | ||
|
||
# Suddenly incompatible with Catch somehow, in between v00-16-02 and tip of master: nlohmann-json3-dev \ | ||
|
||
RUN cd /app/podio \ | ||
&& mkdir build install \ | ||
&& cd build \ | ||
&& cmake -DCMAKE_INSTALL_PREFIX=../install -DUSE_EXTERNAL_CATCH2=OFF .. \ | ||
&& make -j4 install | ||
|
||
|
||
|
||
CMD bash | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
|
||
set(PodioExample_SOURCES | ||
PodioExample.cc | ||
PodioExampleProcessor.cc | ||
PodioExampleSource.cc | ||
ExampleClusterFactory.cc | ||
) | ||
|
||
if (USE_PODIO) | ||
|
||
foreach( _conf ${CMAKE_CONFIGURATION_TYPES} ) | ||
string(TOUPPER ${_conf} _conf ) | ||
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${_conf} ${CMAKE_CURRENT_BINARY_DIR} ) | ||
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${_conf} ${CMAKE_CURRENT_BINARY_DIR} ) | ||
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${_conf} ${CMAKE_CURRENT_BINARY_DIR} ) | ||
endforeach() | ||
PODIO_GENERATE_DATAMODEL(datamodel layout.yaml DATAMODEL_HEADERS DATAMODEL_SOURCES IO_BACKEND_HANDLERS ROOT) | ||
PODIO_ADD_DATAMODEL_CORE_LIB(DataModelLib "${DATAMODEL_HEADERS}" "${DATAMODEL_SOURCES}") | ||
PODIO_ADD_ROOT_IO_DICT(DataModelDict DataModelLib "${DATAMODEL_HEADERS}" src/selection.xml) | ||
|
||
find_package(podio REQUIRED) | ||
add_executable(PodioExample ${PodioExample_SOURCES}) | ||
target_include_directories(PodioExample PUBLIC .) | ||
target_link_libraries(PodioExample jana2 podio::podio DataModelLib DataModelDict podio::podioRootIO) | ||
set_target_properties(PodioExample PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) | ||
|
||
install(TARGETS PodioExample DESTINATION bin) | ||
else() | ||
message(STATUS "Skipping examples/PodioExample because USE_PODIO=Off") | ||
|
||
endif() | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
|
||
// Copyright 2023, Jefferson Science Associates, LLC. | ||
// Subject to the terms in the LICENSE file found in the top-level directory. | ||
|
||
|
||
#ifndef JANA2_DATAMODELGLUE_H | ||
#define JANA2_DATAMODELGLUE_H | ||
|
||
#include <datamodel/ExampleHit.h> | ||
#include <datamodel/ExampleHitCollection.h> | ||
#include <datamodel/ExampleCluster.h> | ||
#include <datamodel/ExampleClusterCollection.h> | ||
#include <datamodel/EventInfo.h> | ||
#include <datamodel/EventInfoCollection.h> | ||
|
||
template <typename T> | ||
struct PodioCollectionMap { | ||
}; | ||
|
||
template <> | ||
struct PodioCollectionMap<ExampleHitCollection> { | ||
using contents_t = ExampleHit; | ||
}; | ||
template <> | ||
struct PodioCollectionMap<ExampleClusterCollection> { | ||
using contents_t = ExampleCluster; | ||
}; | ||
template <> | ||
struct PodioCollectionMap<EventInfoCollection> { | ||
using contents_t = EventInfo; | ||
}; | ||
|
||
template <typename T> | ||
struct PodioTypeMap { | ||
}; | ||
|
||
template <> | ||
struct PodioTypeMap<ExampleHit> { | ||
using mutable_t = MutableExampleHit; | ||
using collection_t = ExampleHitCollection; | ||
}; | ||
|
||
template <> | ||
struct PodioTypeMap<ExampleCluster> { | ||
using mutable_t = MutableExampleCluster; | ||
using collection_t = ExampleClusterCollection; | ||
}; | ||
|
||
template <> | ||
struct PodioTypeMap<EventInfo> { | ||
using mutable_t = MutableEventInfo; | ||
using collection_t = EventInfoCollection; | ||
}; | ||
|
||
|
||
template<typename ... Ts> | ||
struct Overload : Ts ... { | ||
using Ts::operator() ...; | ||
}; | ||
template<class... Ts> Overload(Ts...) -> Overload<Ts...>; | ||
|
||
|
||
template <typename F, typename... ArgsT> | ||
void visitPodioType(const std::string& podio_typename, F& helper, ArgsT... args) { | ||
if (podio_typename == "EventInfo") { | ||
return helper.template operator()<EventInfo>(std::forward<ArgsT>(args)...); | ||
} | ||
else if (podio_typename == "ExampleHit") { | ||
return helper.template operator()<ExampleHit>(std::forward<ArgsT>(args)...); | ||
} | ||
else if (podio_typename == "ExampleCluster") { | ||
return helper.template operator()<ExampleCluster>(std::forward<ArgsT>(args)...); | ||
} | ||
throw std::runtime_error("Not a podio typename!"); | ||
} | ||
|
||
// If you are using C++20, you can use templated lambdas to write your visitor completely inline like so: | ||
/* | ||
visitPodioType(coll->getValueTypeName(), | ||
[&]<typename T>(const podio::CollectionBase* coll, std::string name) { | ||
using CollT = const typename PodioTypeMap<T>::collection_t; | ||
CollT* typed_col = static_cast<CollT*>(coll); | ||
std::cout << name << std::endl; | ||
for (const T& object : *typed_col) { | ||
std::cout << coll->getValueTypeName() << std::endl; | ||
std::cout << object << std::endl; | ||
} | ||
}, coll, coll_name); | ||
*/ | ||
|
||
template <typename Visitor> | ||
struct DatamodelCollectionVisit { | ||
void operator()(const podio::CollectionBase &collection, Visitor& visitor) { | ||
std::string podio_typename = collection.getTypeName(); | ||
if (podio_typename == "EventInfoCollection") { | ||
return visitor(static_cast<const EventInfoCollection &>(collection)); | ||
} else if (podio_typename == "ExampleHitCollection") { | ||
return visitor(static_cast<const ExampleHitCollection &>(collection)); | ||
} else if (podio_typename == "ExampleClusterCollection") { | ||
return visitor(static_cast<const ExampleClusterCollection &>(collection)); | ||
} | ||
throw std::runtime_error("Unrecognized podio typename!"); | ||
} | ||
}; | ||
|
||
// TODO: Change argument to collection pointer instead of reference because that is what we do everywhere else? | ||
|
||
#endif //JANA2_DATAMODELGLUE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
|
||
// Copyright 2023, Jefferson Science Associates, LLC. | ||
// Subject to the terms in the LICENSE file found in the top-level directory. | ||
|
||
|
||
#include "ExampleClusterFactory.h" | ||
#include "datamodel/ExampleHit.h" | ||
#include <JANA/JEvent.h> | ||
|
||
ExampleClusterFactory::ExampleClusterFactory() { | ||
SetTag("clusters"); | ||
// TODO: Need to throw an exception if you try to register a PODIO factory with an empty or non-unique tag | ||
} | ||
|
||
void ExampleClusterFactory::Process(const std::shared_ptr<const JEvent> &event) { | ||
|
||
// This example groups hits according to the quadrant in which they lie on the x-y plane. | ||
|
||
MutableExampleCluster quadrant1, quadrant2, quadrant3, quadrant4; | ||
|
||
auto hits = event->GetCollection<ExampleHit>("hits"); | ||
for (auto hit : *hits) { | ||
if (hit.x() > 0) { | ||
if (hit.y() > 0) { | ||
quadrant1.addHits(hit); | ||
quadrant1.energy(quadrant1.energy() + hit.energy()); | ||
} | ||
else { | ||
quadrant4.addHits(hit); | ||
quadrant4.energy(quadrant4.energy() + hit.energy()); | ||
} | ||
} | ||
else { | ||
if (hit.y() > 0) { | ||
quadrant2.addHits(hit); | ||
quadrant2.energy(quadrant2.energy() + hit.energy()); | ||
|
||
} | ||
else { | ||
quadrant3.addHits(hit); | ||
quadrant3.energy(quadrant3.energy() + hit.energy()); | ||
} | ||
|
||
} | ||
} | ||
auto* clusters = new ExampleClusterCollection(); | ||
if (quadrant1.Hits_size() > 0) clusters->push_back(quadrant1); | ||
if (quadrant2.Hits_size() > 0) clusters->push_back(quadrant2); | ||
if (quadrant3.Hits_size() > 0) clusters->push_back(quadrant3); | ||
if (quadrant4.Hits_size() > 0) clusters->push_back(quadrant4); | ||
|
||
// If no hits were assigned to a cluster, it will self-destruct when it goes out of scope | ||
SetCollection(clusters); | ||
} | ||
|
||
|
||
// TODO: Expose collections as refs, not ptrs? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
|
||
// Copyright 2023, Jefferson Science Associates, LLC. | ||
// Subject to the terms in the LICENSE file found in the top-level directory. | ||
|
||
|
||
#ifndef JANA2_EXAMPLECLUSTERFACTORY_H | ||
#define JANA2_EXAMPLECLUSTERFACTORY_H | ||
|
||
#include <JANA/Podio/JFactoryPodioT.h> | ||
#include "datamodel/ExampleCluster.h" | ||
#include "DatamodelGlue.h" | ||
|
||
class ExampleClusterFactory : public JFactoryPodioT<ExampleCluster> { | ||
public: | ||
ExampleClusterFactory(); | ||
void Process(const std::shared_ptr<const JEvent> &event) override; | ||
}; | ||
|
||
|
||
#endif //JANA2_EXAMPLECLUSTERFACTORY_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
|
||
// Copyright 2023, Jefferson Science Associates, LLC. | ||
// Subject to the terms in the LICENSE file found in the top-level directory. | ||
#include <iostream> | ||
#include <podio/CollectionBase.h> | ||
#include <podio/Frame.h> | ||
#include "datamodel/MutableExampleHit.h" | ||
#include "datamodel/ExampleHitCollection.h" | ||
#include <podio/ROOTFrameWriter.h> | ||
#include <podio/ROOTFrameReader.h> | ||
|
||
#include <JANA/JApplication.h> | ||
#include <JANA/JFactoryGenerator.h> | ||
#include <JANA/Podio/JEventProcessorPodio.h> | ||
|
||
#include "PodioExampleSource.h" | ||
#include "PodioExampleProcessor.h" | ||
#include "ExampleClusterFactory.h" | ||
|
||
|
||
void create_hits_file() { | ||
|
||
EventInfo eventinfo1(7, 22); | ||
EventInfoCollection eventinfos1; | ||
eventinfos1.push_back(eventinfo1); | ||
|
||
ExampleHitCollection hits1; | ||
hits1.push_back({22, -1, -1, 0, 100}); | ||
hits1.push_back({49, 1, 1, 0, 15.5}); | ||
hits1.push_back({47, 1, 2, 0, 0.5}); | ||
hits1.push_back({42, 2, 1, 0, 4.0}); | ||
|
||
podio::Frame event1; | ||
event1.put(std::move(hits1), "hits"); | ||
event1.put(std::move(eventinfos1), "eventinfos"); | ||
|
||
podio::ROOTFrameWriter writer("hits.root"); | ||
writer.writeFrame(event1, "events"); | ||
|
||
EventInfo eventinfo2(8, 22); | ||
EventInfoCollection eventinfos2; | ||
eventinfos2.push_back(eventinfo2); | ||
|
||
ExampleHitCollection hits2; | ||
hits2.push_back({42, 5, -5, 5, 7.6}); | ||
hits2.push_back({618, -3, -5, 1, 99.9}); | ||
hits2.push_back({27, -10, 10, 10, 22.2}); | ||
hits2.push_back({28, -9, 11, 10, 7.8}); | ||
|
||
podio::Frame event2; | ||
event2.put(std::move(hits2), "hits"); | ||
event2.put(std::move(eventinfos2), "eventinfos"); | ||
|
||
writer.writeFrame(event2, "events"); | ||
writer.finish(); | ||
|
||
} | ||
|
||
void verify_clusters_file() { | ||
podio::ROOTFrameReader reader; | ||
reader.openFile("podio_output.root"); | ||
auto event0 = podio::Frame(reader.readEntry("events", 0)); | ||
|
||
std::cout << "Event 0: Expected 2 clusters, got " << event0.get("clusters")->size() << std::endl; | ||
|
||
auto event1 = podio::Frame(reader.readEntry("events", 1)); | ||
std::cout << "Event 1: Expected 3 clusters, got " << event1.get("clusters")->size() << std::endl; | ||
} | ||
|
||
|
||
int main() { | ||
|
||
create_hits_file(); | ||
|
||
JApplication app; | ||
app.Add(new PodioExampleProcessor); | ||
app.Add(new JEventProcessorPodio); | ||
app.Add(new JFactoryGeneratorT<ExampleClusterFactory>()); | ||
app.Add(new PodioExampleSource("hits.root")); | ||
app.Run(); | ||
|
||
verify_clusters_file(); | ||
|
||
} | ||
|
Oops, something went wrong.