Skip to content

Commit

Permalink
Add hit manager output diagnostic (#1596)
Browse files Browse the repository at this point in the history
  • Loading branch information
sethrj authored Jan 26, 2025
1 parent 3245c1b commit c4bea8d
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/accel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ list(APPEND SOURCES
SimpleOffload.cc
detail/GeantSimpleCaloSD.cc
detail/HitManager.cc
detail/HitManagerOutput.cc
detail/HitProcessor.cc
detail/LevelTouchableUpdater.cc
detail/NaviTouchableUpdater.cc
Expand Down
3 changes: 3 additions & 0 deletions src/accel/SharedParams.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include "SetupOptions.hh"

#include "detail/HitManager.hh"
#include "detail/HitManagerOutput.hh"
#include "detail/OffloadWriter.hh"

namespace celeritas
Expand Down Expand Up @@ -649,6 +650,8 @@ void SharedParams::initialize_core(SetupOptions const& options)
params_->max_streams());
step_collector_
= StepCollector::make_and_insert(*params_, {hit_manager_});
output_reg_->insert(
std::make_shared<detail::HitManagerOutput>(hit_manager_));
}

// Add diagnostics
Expand Down
3 changes: 3 additions & 0 deletions src/accel/detail/HitManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ class HitManager final : public StepInterface
//! Access mapped particles if recreating G4Tracks later
VecParticle const& geant_particles() const { return particles_; }

//! Whether detailed volume information is reconstructed
bool locate_touchable() const { return locate_touchable_; }

private:
using VecLV = std::vector<G4LogicalVolume const*>;

Expand Down
96 changes: 96 additions & 0 deletions src/accel/detail/HitManagerOutput.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//------------------------------- -*- C++ -*- -------------------------------//
// Copyright Celeritas contributors: see top-level COPYRIGHT file for details
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
//---------------------------------------------------------------------------//
//! \file accel/detail/HitManagerOutput.cc
//---------------------------------------------------------------------------//
#include "HitManagerOutput.hh"

#include <G4LogicalVolume.hh>
#include <G4VSensitiveDetector.hh>
#include <nlohmann/json.hpp>

#include "corecel/cont/Range.hh"
#include "corecel/io/JsonPimpl.hh"
#include "corecel/sys/TypeDemangler.hh"

#include "HitManager.hh"

namespace celeritas
{
namespace detail
{
//---------------------------------------------------------------------------//
/*!
* Construct from hit manager.
*/
HitManagerOutput::HitManagerOutput(SPConstHitManager hits)
: hits_(std::move(hits))
{
CELER_EXPECT(hits_);
}

//---------------------------------------------------------------------------//
/*!
* Write output to the given JSON object.
*/
void HitManagerOutput::output(JsonPimpl* j) const
{
using json = nlohmann::json;

auto result = json::object();

// Save detectors
{
auto const& celer_vols = hits_->celer_vols();
auto const& geant_vols = *hits_->geant_vols();
TypeDemangler<G4VSensitiveDetector> demangle_sd;

auto vol_ids = json::array();
auto gv_names = json::array();
auto sd_names = json::array();
auto sd_types = json::array();

for (auto i : range(celer_vols.size()))
{
vol_ids.push_back(celer_vols[i].get());

auto const* lv = geant_vols[i];
G4VSensitiveDetector const* sd{nullptr};
if (lv)
{
gv_names.push_back(lv->GetName());
sd = lv->GetSensitiveDetector();
}
else
{
gv_names.push_back(nullptr);
}

if (sd)
{
sd_names.push_back(sd->GetName());
sd_types.push_back(demangle_sd(*sd));
}
else
{
sd_names.push_back(nullptr);
sd_types.push_back(nullptr);
}
}

result["vol_id"] = std::move(vol_ids);
result["lv_name"] = std::move(gv_names);
result["sd_name"] = std::move(sd_names);
result["sd_type"] = std::move(sd_types);
}

// TODO: save filter selection
result["locate_touchable"] = hits_->locate_touchable();

j->obj = std::move(result);
}

//---------------------------------------------------------------------------//
} // namespace detail
} // namespace celeritas
50 changes: 50 additions & 0 deletions src/accel/detail/HitManagerOutput.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//------------------------------- -*- C++ -*- -------------------------------//
// Copyright Celeritas contributors: see top-level COPYRIGHT file for details
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
//---------------------------------------------------------------------------//
//! \file accel/detail/HitManagerOutput.hh
//---------------------------------------------------------------------------//
#pragma once

#include <memory>

#include "corecel/io/OutputInterface.hh"

namespace celeritas
{
namespace detail
{
class HitManager;

//---------------------------------------------------------------------------//
/*!
* Save debugging information about sensitive detector mappings.
*/
class HitManagerOutput final : public OutputInterface
{
public:
//!@{
//! \name Type aliases
using SPConstHitManager = std::shared_ptr<HitManager const>;
//!@}

public:
// Construct from shared hit manager
explicit HitManagerOutput(SPConstHitManager hits);

//! Category of data to write
Category category() const final { return Category::internal; }

//! Name of the entry inside the category.
std::string_view label() const final { return "hit-manager"; }

// Write output to the given JSON object
void output(JsonPimpl*) const final;

private:
SPConstHitManager hits_;
};

//---------------------------------------------------------------------------//
} // namespace detail
} // namespace celeritas
4 changes: 2 additions & 2 deletions src/accel/detail/SensDetInserter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ VolumeId SensDetInserter::insert_impl(G4LogicalVolume const* lv)
{
CELER_LOG(debug)
<< "Skipping automatic SD callback for logical volume \""
<< lv->GetName() << "\" due to user option";
<< PrintableLV{lv} << "\" due to user option";
return {};
}

Expand All @@ -78,7 +78,7 @@ VolumeId SensDetInserter::insert_impl(G4LogicalVolume const* lv)
// Add Geant4 volume and corresponding volume ID to list
auto [iter, inserted] = found_->insert({id, lv});

if (CELER_UNLIKELY(!inserted)) // && iter->second != lv))
if (CELER_UNLIKELY(!inserted))
{
if (iter->second != lv)
{
Expand Down
35 changes: 35 additions & 0 deletions test/accel/detail/HitManager.test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "celeritas/geo/GeoParams.hh"
#include "accel/SDTestBase.hh"
#include "accel/SetupOptions.hh"
#include "accel/detail/HitManagerOutput.hh"

#include "celeritas_test.hh"

Expand Down Expand Up @@ -101,6 +102,13 @@ class SimpleCmsTest : public ::celeritas::test::SDTestBase,
return result;
}

std::string get_diagnostics(HitManager const& hm)
{
HitManagerOutput out(
std::shared_ptr<HitManager const>(&hm, [](HitManager const*) {}));
return to_string(out);
}

protected:
SDSetupOptions sd_setup_;
::celeritas::test::ScopedLogStorer scoped_log_{&celeritas::world_logger()};
Expand All @@ -124,6 +132,13 @@ TEST_F(SimpleCmsTest, no_change)
{
EXPECT_TRUE(scoped_log_.empty()) << scoped_log_;
}

if (CELERITAS_CORE_GEO == CELERITAS_CORE_GEO_ORANGE)
{
EXPECT_JSON_EQ(
R"json({"_category":"internal","_label":"hit-manager","locate_touchable":true,"lv_name":["em_calorimeter","had_calorimeter"],"sd_name":["em_calorimeter","had_calorimeter"],"sd_type":["celeritas::test::SimpleSensitiveDetector","celeritas::test::SimpleSensitiveDetector"],"vol_id":[3,4]})json",
this->get_diagnostics(man));
}
}

TEST_F(SimpleCmsTest, delete_one)
Expand All @@ -150,6 +165,13 @@ TEST_F(SimpleCmsTest, delete_one)
{
EXPECT_TRUE(scoped_log_.empty()) << scoped_log_;
}

if (CELERITAS_CORE_GEO == CELERITAS_CORE_GEO_ORANGE)
{
EXPECT_JSON_EQ(
R"json({"_category":"internal","_label":"hit-manager","locate_touchable":true,"lv_name":["em_calorimeter"],"sd_name":["em_calorimeter"],"sd_type":["celeritas::test::SimpleSensitiveDetector"],"vol_id":[3]})json",
this->get_diagnostics(man));
}
}

TEST_F(SimpleCmsTest, add_duplicate)
Expand Down Expand Up @@ -180,6 +202,13 @@ TEST_F(SimpleCmsTest, add_duplicate)
= {"debug", "debug", "debug"};
EXPECT_VEC_EQ(expected_log_levels, scoped_log_.levels());
}

if (CELERITAS_CORE_GEO == CELERITAS_CORE_GEO_ORANGE)
{
EXPECT_JSON_EQ(
R"json({"_category":"internal","_label":"hit-manager","locate_touchable":true,"lv_name":["em_calorimeter","had_calorimeter"],"sd_name":["em_calorimeter","had_calorimeter"],"sd_type":["celeritas::test::SimpleSensitiveDetector","celeritas::test::SimpleSensitiveDetector"],"vol_id":[3,4]})json",
this->get_diagnostics(man));
}
}

TEST_F(SimpleCmsTest, add_one)
Expand All @@ -199,6 +228,12 @@ TEST_F(SimpleCmsTest, add_one)
{
EXPECT_TRUE(scoped_log_.empty()) << scoped_log_;
}
if (CELERITAS_CORE_GEO == CELERITAS_CORE_GEO_ORANGE)
{
EXPECT_JSON_EQ(
R"json({"_category":"internal","_label":"hit-manager","locate_touchable":true,"lv_name":["si_tracker","em_calorimeter","had_calorimeter"],"sd_name":[null,"em_calorimeter","had_calorimeter"],"sd_type":[null,"celeritas::test::SimpleSensitiveDetector","celeritas::test::SimpleSensitiveDetector"],"vol_id":[2,3,4]})json",
this->get_diagnostics(man));
}
}

TEST_F(SimpleCmsTest, no_detector)
Expand Down

0 comments on commit c4bea8d

Please sign in to comment.