Skip to content

Commit

Permalink
output: use detector names as ntuple name
Browse files Browse the repository at this point in the history
  • Loading branch information
ManuelHu committed Nov 15, 2024
1 parent 70827ef commit 522145f
Show file tree
Hide file tree
Showing 15 changed files with 244 additions and 213 deletions.
35 changes: 35 additions & 0 deletions include/RMGDetectorMetadata.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (C) 2022 Luigi Pertoldi <[email protected]>
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option) any
// later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

#ifndef _RMG_DETECTOR_METADATA_HH_
#define _RMG_DETECTOR_METADATA_HH_

#include <string>

enum RMGDetectorType {
kGermanium,
kOptical,
kScintillator,
};

struct RMGDetectorMetadata {
RMGDetectorType type;
int uid;
std::string name;
};

#endif

// vim: tabstop=2 shiftwidth=2 expandtab
20 changes: 5 additions & 15 deletions include/RMGHardware.hh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "G4Region.hh"
#include "G4VUserDetectorConstruction.hh"

#include "RMGDetectorMetadata.hh"
#include "RMGHardwareMessenger.hh"
#include "RMGNavigationTools.hh"
#include "RMGVOutputScheme.hh"
Expand All @@ -46,19 +47,8 @@ class RMGHardware : public G4VUserDetectorConstruction {
G4VPhysicalVolume* Construct() override;
void ConstructSDandField() override;

enum DetectorType {
kGermanium,
kOptical,
kScintillator,
};

struct DetectorMetadata {
DetectorType type;
int uid;
};

void RegisterDetector(DetectorType type, const std::string& pv_name, int uid, int copy_nr = 0,
bool allow_uid_reuse = false);
void RegisterDetector(RMGDetectorType type, const std::string& pv_name, int uid,
int copy_nr = 0, bool allow_uid_reuse = false);
inline const auto& GetDetectorMetadataMap() { return fDetectorMetadata; }
inline const auto& GetDetectorMetadata(const std::pair<std::string, int>& det) {
return fDetectorMetadata.at(det);
Expand All @@ -84,8 +74,8 @@ class RMGHardware : public G4VUserDetectorConstruction {
std::map<std::string, double> fPhysVolStepLimits;

// one element for each sensitive detector physical volume
std::map<std::pair<std::string, int>, DetectorMetadata> fDetectorMetadata;
std::set<DetectorType> fActiveDetectors;
std::map<std::pair<std::string, int>, RMGDetectorMetadata> fDetectorMetadata;
std::set<RMGDetectorType> fActiveDetectors;
static G4ThreadLocal std::vector<std::shared_ptr<RMGVOutputScheme>> fActiveOutputSchemes;
static G4ThreadLocal bool fActiveDetectorsInitialized;

Expand Down
9 changes: 7 additions & 2 deletions include/RMGVOutputScheme.hh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "G4Track.hh"
#include "G4UserStackingAction.hh"

#include "RMGDetectorMetadata.hh"

#include "fmt/format.h"

class G4Event;
Expand Down Expand Up @@ -55,8 +57,11 @@ class RMGVOutputScheme {

protected:

[[nodiscard]] virtual inline std::string GetNtupleName(int det_uid) const {
return fNtuplePerDetector ? fmt::format("det{:03}", det_uid) : GetNtuplenameFlat();
[[nodiscard]] virtual inline std::string GetNtupleName(RMGDetectorMetadata det) const {
if (fNtuplePerDetector) {
return !det.name.empty() ? det.name : fmt::format("det{:03}", det.uid);
}
return GetNtuplenameFlat();
}
[[nodiscard]] virtual inline std::string GetNtuplenameFlat() const {
throw new std::logic_error("GetNtuplenameFlat not implemented");
Expand Down
2 changes: 1 addition & 1 deletion include/RMGVertexOutputScheme.hh
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class RMGVertexOutputScheme : public RMGVOutputScheme {

protected:

[[nodiscard]] inline std::string GetNtupleName(int) const override {
[[nodiscard]] inline std::string GetNtupleName(RMGDetectorMetadata) const override {
throw std::logic_error("vertex output scheme has no detectors");
}

Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
set(_root ${PROJECT_SOURCE_DIR})

set(PROJECT_PUBLIC_HEADERS
${_root}/include/RMGDetectorMetadata.hh
${_root}/include/RMGExceptionHandler.hh
${_root}/include/RMGEventAction.hh
${_root}/include/RMGGeneratorCosmicMuons.hh
Expand Down
2 changes: 1 addition & 1 deletion src/RMGGermaniumDetector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ bool RMGGermaniumDetector::ProcessHits(G4Step* step, G4TouchableHistory* /*histo
const auto det_cons = RMGManager::Instance()->GetDetectorConstruction();
try {
auto d_type = det_cons->GetDetectorMetadata({pv_name, pv_copynr}).type;
if (d_type != RMGHardware::kGermanium) {
if (d_type != RMGDetectorType::kGermanium) {
RMGLog::OutFormatDev(RMGLog::debug,
"Volume '{}' (copy nr. {} not registered as germanium detector", pv_name, pv_copynr);
return false;
Expand Down
4 changes: 2 additions & 2 deletions src/RMGGermaniumOutputScheme.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ void RMGGermaniumOutputScheme::AssignOutputNames(G4AnalysisManager* ana_man) {
std::set<int> registered_uids;
std::map<std::string, int> registered_ntuples;
for (auto&& det : detectors) {
if (det.second.type != RMGHardware::kGermanium) continue;
if (det.second.type != RMGDetectorType::kGermanium) continue;

// do not register the ntuple twice if two detectors share their uid.
auto had_uid = registered_uids.emplace(det.second.uid);
if (!had_uid.second) continue;

auto ntuple_name = this->GetNtupleName(det.second.uid);
auto ntuple_name = this->GetNtupleName(det.second);
auto ntuple_reg = registered_ntuples.find(ntuple_name);
if (ntuple_reg != registered_ntuples.end()) {
// ntuple already exists, but also store the ntuple id for the other uid(s).
Expand Down
14 changes: 7 additions & 7 deletions src/RMGHardware.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ void RMGHardware::ConstructSDandField() {
else sd_man->SetVerboseLevel(0);

// map holding a list of sensitive detectors to activate
std::map<DetectorType, G4VSensitiveDetector*> active_dets;
std::map<RMGDetectorType, G4VSensitiveDetector*> active_dets;

for (const auto& [k, v] : fDetectorMetadata) {

Expand All @@ -128,21 +128,21 @@ void RMGHardware::ConstructSDandField() {
G4VSensitiveDetector* obj = nullptr;
std::shared_ptr<RMGVOutputScheme> output;
switch (v.type) {
case DetectorType::kOptical:
case RMGDetectorType::kOptical:
obj = new RMGOpticalDetector();
output = std::make_shared<RMGOpticalOutputScheme>();
break;
case DetectorType::kGermanium:
case RMGDetectorType::kGermanium:
obj = new RMGGermaniumDetector();
output = std::make_shared<RMGGermaniumOutputScheme>();
break;
case DetectorType::kScintillator:
case RMGDetectorType::kScintillator:
obj = new RMGScintillatorDetector();
output = std::make_shared<RMGScintillatorOutputScheme>();
break;
default:
RMGLog::OutDev(RMGLog::fatal, "No behaviour for sensitive detector type '",
magic_enum::enum_name<DetectorType>(v.type), "' implemented (implement me)");
magic_enum::enum_name<RMGDetectorType>(v.type), "' implemented (implement me)");
}
sd_man->AddNewDetector(obj);
active_dets.emplace(v.type, obj);
Expand Down Expand Up @@ -198,7 +198,7 @@ void RMGHardware::ConstructSDandField() {
}
}

void RMGHardware::RegisterDetector(DetectorType type, const std::string& pv_name, int uid,
void RMGHardware::RegisterDetector(RMGDetectorType type, const std::string& pv_name, int uid,
int copy_nr, bool allow_uid_reuse) {
if (fActiveDetectorsInitialized) {
RMGLog::Out(RMGLog::error,
Expand All @@ -220,7 +220,7 @@ void RMGHardware::RegisterDetector(DetectorType type, const std::string& pv_name
fActiveDetectors.insert(type);

// FIXME: can this be done with emplace?
auto r_value = fDetectorMetadata.insert({{pv_name, copy_nr}, {type, uid}});
auto r_value = fDetectorMetadata.insert({{pv_name, copy_nr}, {type, uid, pv_name}});
if (!r_value.second) { // if insertion did not take place
RMGLog::OutFormat(RMGLog::warning,
"Physical volume '{}' (copy number {}) has already been registered as detector", pv_name,
Expand Down
4 changes: 2 additions & 2 deletions src/RMGHardwareMessenger.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ RMGHardwareMessenger::RMGHardwareMessenger(RMGHardware* hw) : fHardware(hw) {
fRegisterCmd->SetGuidance("register a sensitive detector");

auto p_type = new G4UIparameter("type", 's', false);
p_type->SetParameterCandidates(RMGTools::GetCandidates<RMGHardware::DetectorType>().c_str());
p_type->SetParameterCandidates(RMGTools::GetCandidates<RMGDetectorType>().c_str());
p_type->SetGuidance("Detector type");
fRegisterCmd->SetParameter(p_type);

Expand Down Expand Up @@ -62,7 +62,7 @@ void RMGHardwareMessenger::RegisterDetectorCmd(const std::string& parameters) {
G4Tokenizer next(parameters);

auto type_str = next();
auto type = RMGTools::ToEnum<RMGHardware::DetectorType>(std::string(type_str), "detector type");
auto type = RMGTools::ToEnum<RMGDetectorType>(std::string(type_str), "detector type");
auto pv_name = next();
const int uid = std::stoi(next());
int copy_nr = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/RMGOpticalDetector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ bool RMGOpticalDetector::ProcessHits(G4Step* step, G4TouchableHistory* /*history
auto det_cons = RMGManager::Instance()->GetDetectorConstruction();
try {
auto d_type = det_cons->GetDetectorMetadata({pv_name, pv_copynr}).type;
if (d_type != RMGHardware::kOptical) {
if (d_type != RMGDetectorType::kOptical) {
RMGLog::OutFormatDev(RMGLog::debug,
"Volume '{}' (copy nr. {} not registered as optical detector", pv_name, pv_copynr);
return false;
Expand Down
4 changes: 2 additions & 2 deletions src/RMGOpticalOutputScheme.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ void RMGOpticalOutputScheme::AssignOutputNames(G4AnalysisManager* ana_man) {
std::set<int> registered_uids;
std::map<std::string, int> registered_ntuples;
for (auto&& det : detectors) {
if (det.second.type != RMGHardware::kOptical) continue;
if (det.second.type != RMGDetectorType::kOptical) continue;

// do not register the ntuple twice if two detectors share their uid.
auto had_uid = registered_uids.emplace(det.second.uid);
if (!had_uid.second) continue;

auto ntuple_name = this->GetNtupleName(det.second.uid);
auto ntuple_name = this->GetNtupleName(det.second);
auto ntuple_reg = registered_ntuples.find(ntuple_name);
if (ntuple_reg != registered_ntuples.end()) {
// ntuple already exists, but also store the ntuple id for the other uid(s).
Expand Down
2 changes: 1 addition & 1 deletion src/RMGScintillatorDetector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ bool RMGScintillatorDetector::ProcessHits(G4Step* step, G4TouchableHistory* /*hi
const auto det_cons = RMGManager::Instance()->GetDetectorConstruction();
try {
auto d_type = det_cons->GetDetectorMetadata({pv_name, pv_copynr}).type;
if (d_type != RMGHardware::kScintillator) {
if (d_type != RMGDetectorType::kScintillator) {
RMGLog::OutFormatDev(RMGLog::debug,
"Volume '{}' (copy nr. {} not registered as scintillator detector", pv_name, pv_copynr);
return false;
Expand Down
4 changes: 2 additions & 2 deletions src/RMGScintillatorOutputScheme.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ void RMGScintillatorOutputScheme::AssignOutputNames(G4AnalysisManager* ana_man)
std::set<int> registered_uids;
std::map<std::string, int> registered_ntuples;
for (auto&& det : detectors) {
if (det.second.type != RMGHardware::kScintillator) continue;
if (det.second.type != RMGDetectorType::kScintillator) continue;

// do not register the ntuple twice if two detectors share their uid.
auto had_uid = registered_uids.emplace(det.second.uid);
if (!had_uid.second) continue;

auto ntuple_name = this->GetNtupleName(det.second.uid);
auto ntuple_name = this->GetNtupleName(det.second);
auto ntuple_reg = registered_ntuples.find(ntuple_name);
if (ntuple_reg != registered_ntuples.end()) {
// ntuple already exists, but also store the ntuple id for the other uid(s).
Expand Down
Loading

0 comments on commit 522145f

Please sign in to comment.