-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ROOT-based event exporter #900
Changes from 10 commits
3eff886
a591721
6a919c6
c7039fa
389d5cb
9fdd0c5
b514630
58a32be
5365993
bc4d486
d822921
c14d2fb
b0e9f43
8db8f19
2ba1132
2b68f96
473b5c8
95d6885
e0bd0ab
5b5340e
0bfede8
3ac3ced
9f99cff
798b407
47c7618
ea48c6a
b5fa3d9
1ec6e33
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -112,6 +112,8 @@ struct SetupOptions | |
std::string physics_output_file; | ||
//! Filename to dump a HepMC3 copy of offloaded tracks as events | ||
std::string offload_output_file; | ||
//! Filename to dump a ROOT copy of offloaded tracks as events | ||
std::string offload_root_output_file; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this; we'll reuse There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also this one? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ahh crap. Thanks for noticing this. I checked out back a few files from a previous commit just to test a |
||
//!@} | ||
|
||
//!@{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ namespace detail | |
{ | ||
class HitManager; | ||
class OffloadWriter; | ||
class RootOffloadWriter; | ||
} // namespace detail | ||
class CoreParams; | ||
struct Primary; | ||
|
@@ -87,13 +88,20 @@ class SharedParams | |
|
||
using SPHitManager = std::shared_ptr<detail::HitManager>; | ||
using SPOffloadWriter = std::shared_ptr<detail::OffloadWriter>; | ||
using SPRootOffloadWriter = std::shared_ptr<detail::RootOffloadWriter>; | ||
|
||
//! Hit manager, to be used only by LocalTransporter | ||
SPHitManager const& hit_manager() const { return hit_manager_; } | ||
|
||
//! Optional offload writer, only for use by LocalTransporter | ||
SPOffloadWriter const& offload_writer() const { return offload_writer_; } | ||
|
||
//! Optional ROOT offload writer, only for use by LocalTransporter | ||
SPRootOffloadWriter const& root_offload_writer() const | ||
{ | ||
return root_offload_writer_; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Delete all this code; we should be using the same offload writer interface: either HepMC3 or ROOT, we don't need separate copies of both. I just wanted you to add the |
||
//!@} | ||
|
||
private: | ||
|
@@ -105,6 +113,7 @@ class SharedParams | |
VecG4ParticleDef particles_; | ||
std::string output_filename_; | ||
SPOffloadWriter offload_writer_; | ||
SPRootOffloadWriter root_offload_writer_; | ||
|
||
//// HELPER FUNCTIONS //// | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
//----------------------------------*-C++-*----------------------------------// | ||
// Copyright 2023 UT-Battelle, LLC, and other Celeritas developers. | ||
// See the top-level COPYRIGHT file for details. | ||
// SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
//---------------------------------------------------------------------------// | ||
//! \file accel/detail/RootOffloadReader.cc | ||
//---------------------------------------------------------------------------// | ||
#include "RootOffloadReader.hh" | ||
|
||
#include <TFile.h> | ||
#include <TLeaf.h> | ||
#include <TTree.h> | ||
|
||
#include "corecel/io/Logger.hh" | ||
#include "celeritas/phys/ParticleParams.hh" | ||
|
||
namespace celeritas | ||
{ | ||
namespace detail | ||
{ | ||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Construct with ROOT input filename. | ||
*/ | ||
RootOffloadReader::RootOffloadReader(std::string const& filename, | ||
SPConstParticles params) | ||
: params_(std::move(params)) | ||
{ | ||
CELER_EXPECT(!filename.empty()); | ||
tfile_.reset(TFile::Open(filename.c_str(), "read")); | ||
CELER_ASSERT(tfile_->IsOpen()); | ||
ttree_.reset(tfile_->Get<TTree>(tree_name())); | ||
CELER_ASSERT(ttree_); | ||
|
||
num_entries_ = ttree_->GetEntries(); | ||
CELER_ASSERT(num_entries_ > 0); | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Read single event from the primaries tree. | ||
*/ | ||
auto RootOffloadReader::operator()() -> result_type | ||
{ | ||
std::lock_guard scoped_lock{read_mutex_}; | ||
|
||
CELER_EXPECT(entry_count_ <= num_entries_); | ||
ttree_->GetEntry(entry_count_); | ||
auto const this_evt_id = ttree_->GetLeaf("event_id")->GetValue(); | ||
|
||
result_type primaries; | ||
for (; entry_count_ < num_entries_; entry_count_++) | ||
{ | ||
ttree_->GetEntry(entry_count_); | ||
if (ttree_->GetLeaf("event_id")->GetValue() != this_evt_id) | ||
{ | ||
break; | ||
} | ||
|
||
Primary primary; | ||
primary.event_id = EventId{this->from_leaf<std::size_t>("event_id")}; | ||
primary.track_id = TrackId{this->from_leaf<std::size_t>("track_id")}; | ||
primary.particle_id | ||
= params_->find(PDGNumber{this->from_leaf<int>("particle")}); | ||
primary.energy = units::MevEnergy{this->from_leaf<double>("energy")}; | ||
primary.time = this->from_leaf<double>("time"); | ||
primary.position = this->from_array_leaf("pos"); | ||
primary.direction = this->from_array_leaf("dir"); | ||
primaries.push_back(std::move(primary)); | ||
} | ||
|
||
CELER_LOG_LOCAL(info) << "Read event " << this_evt_id << " with " | ||
<< primaries.size() << " primaries"; | ||
return primaries; | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Helper function to fetch leaves. | ||
*/ | ||
template<class T> | ||
auto RootOffloadReader::from_leaf(char const* leaf_name) -> T | ||
{ | ||
CELER_EXPECT(ttree_); | ||
auto const leaf = ttree_->GetLeaf(leaf_name); | ||
CELER_ASSERT(leaf); | ||
return static_cast<T>(leaf->GetValue()); | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Helper function to fetch leaves containing `std::array<double, 3>`. | ||
*/ | ||
Real3 RootOffloadReader::from_array_leaf(char const* leaf_name) | ||
{ | ||
CELER_EXPECT(ttree_); | ||
auto const leaf = ttree_->GetLeaf(leaf_name); | ||
CELER_ASSERT(leaf); | ||
CELER_ASSERT(leaf->GetLen() == 3); | ||
return {leaf->GetValue(0), leaf->GetValue(1), leaf->GetValue(2)}; | ||
} | ||
|
||
//---------------------------------------------------------------------------// | ||
} // namespace detail | ||
} // namespace celeritas |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
//----------------------------------*-C++-*----------------------------------// | ||
// Copyright 2023 UT-Battelle, LLC, and other Celeritas developers. | ||
// See the top-level COPYRIGHT file for details. | ||
// SPDX-License-Identifier: (Apache-2.0 OR MIT) | ||
//---------------------------------------------------------------------------// | ||
//! \file accel/detail/RootOffloadReader.hh | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be |
||
//---------------------------------------------------------------------------// | ||
#pragma once | ||
|
||
#include <string> | ||
|
||
#include "corecel/Macros.hh" | ||
#include "celeritas/ext/RootUniquePtr.hh" | ||
#include "celeritas/phys/Primary.hh" | ||
|
||
// ROOT forward declaration | ||
class TFile; | ||
class TTree; | ||
|
||
namespace celeritas | ||
{ | ||
class ParticleParams; | ||
|
||
namespace detail | ||
{ | ||
//---------------------------------------------------------------------------// | ||
/*! | ||
* Read ROOT file generated by \c RootOffloadWriter . | ||
* | ||
* Use \c operator() to read new primaries: | ||
* \code | ||
RootOffloadReader read("primaries.root", particle_params); | ||
auto event = read(); | ||
while (!event.empty()) | ||
{ | ||
event.read(); | ||
} | ||
* \endcode | ||
*/ | ||
class RootOffloadReader | ||
{ | ||
public: | ||
//!@{ | ||
//! \name Type aliases | ||
using SPConstParticles = std::shared_ptr<ParticleParams const>; | ||
using result_type = std::vector<Primary>; | ||
//!@} | ||
|
||
// Construct with ROOT filename | ||
explicit RootOffloadReader(std::string const& filename, | ||
SPConstParticles params); | ||
|
||
// Read a single event from the ROOT file | ||
result_type operator()(); | ||
|
||
private: | ||
//// DATA //// | ||
|
||
SPConstParticles params_; | ||
std::size_t entry_count_{0}; // Current TTree entry | ||
std::size_t num_entries_; // Total number of entries in the TTree | ||
UPExtern<TFile> tfile_; | ||
UPExtern<TTree> ttree_; | ||
std::mutex read_mutex_; | ||
|
||
//// HELPER FUNCTIONS //// | ||
|
||
// Hardcoded ROOT TTree name defined by RootOffloadWriter | ||
char const* tree_name() { return "primaries"; } | ||
|
||
// Fetch basic data types from leaves | ||
template<class T> | ||
auto from_leaf(char const* leaf_name) -> T; | ||
|
||
// Fetch arrays from leaves | ||
Real3 from_array_leaf(char const* leaf_name); | ||
}; | ||
|
||
//---------------------------------------------------------------------------// | ||
#if !CELERITAS_USE_ROOT | ||
inline RootOffloadReader::RootOffloadReader(std::string const&) | ||
{ | ||
(void)sizeof(num_entries_); | ||
(void)sizeof(entry_count_); | ||
(void)sizeof(tfile_); | ||
(void)sizeof(ttree_); | ||
(void)sizeof(read_mutex_); | ||
(void)sizeof(event_); | ||
CELER_NOT_CONFIGURED("ROOT"); | ||
} | ||
|
||
inline RootOffloadReader::result_type RootOffloadReader::operator()() | ||
{ | ||
CELER_ASSERT_UNREACHABLE(); | ||
} | ||
|
||
inline template<class T> | ||
auto RootOffloadReader::from_leaf(char const*) -> T | ||
{ | ||
CELER_ASSERT_UNREACHABLE(); | ||
} | ||
|
||
Real3 RootOffloadReader::from_leaf(char const*) | ||
{ | ||
CELER_ASSERT_UNREACHABLE(); | ||
} | ||
#endif | ||
|
||
//---------------------------------------------------------------------------// | ||
} // namespace detail | ||
} // namespace celeritas |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be reverted since the ROOT code is no longer in
accel
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stognini You might have missed this comment earlier?