Skip to content

Commit

Permalink
add command /RMG/Geometry/RegisterDetector
Browse files Browse the repository at this point in the history
  • Loading branch information
ManuelHu committed Mar 27, 2024
1 parent b6eb6cd commit 502d335
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 1 deletion.
4 changes: 4 additions & 0 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 "RMGHardwareMessenger.hh"
#include "RMGNavigationTools.hh"

class G4VPhysicalVolume;
Expand Down Expand Up @@ -56,6 +57,7 @@ class RMGHardware : public G4VUserDetectorConstruction {
};

void RegisterDetector(DetectorType type, const std::string& pv_name, int uid, int copy_nr = 0);
void RegisterDetectorCmd(const std::string& parameters);
inline const auto& GetDetectorMetadataMap() { return fDetectorMetadata; }
inline const auto& GetDetectorMetadata(std::pair<std::string, int> det) {
return fDetectorMetadata.at(det);
Expand All @@ -80,8 +82,10 @@ class RMGHardware : public G4VUserDetectorConstruction {
// one element for each sensitive detector physical volume
std::map<std::pair<std::string, int>, DetectorMetadata> fDetectorMetadata;
std::set<DetectorType> fActiveDetectors;
bool fActiveDetectorsInitialized = false;

std::unique_ptr<G4GenericMessenger> fMessenger;
std::unique_ptr<RMGHardwareMessenger> fHwMessenger;
void DefineCommands();

/// The world volume
Expand Down
39 changes: 39 additions & 0 deletions include/RMGHardwareMessenger.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// 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_HARDWARE_MESSENGER_HH_
#define _RMG_HARDWARE_MESSENGER_HH_

#include "G4UImessenger.hh"

class RMGHardware;
class RMGHardwareMessenger : public G4UImessenger {

public:

RMGHardwareMessenger(RMGHardware* hw);
~RMGHardwareMessenger();

void SetNewValue(G4UIcommand* command, G4String newValues);

private:

RMGHardware* fHardware;
G4UIcommand* fRegisterCmd;
};

#endif

// vim: tabstop=2 shiftwidth=2 expandtab
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ set(PROJECT_PUBLIC_HEADERS

set(PROJECT_SOURCES
${_root}/src/RMGHardware.cc
${_root}/src/RMGHardwareMessenger.cc
${_root}/src/RMGEventAction.cc
${_root}/src/RMGGeneratorCosmicMuons.cc
${_root}/src/RMGGeneratorUtil.cc
Expand Down
30 changes: 29 additions & 1 deletion src/RMGHardware.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@ namespace fs = std::filesystem;
#include "G4LogicalVolume.hh"
#include "G4PhysicalVolumeStore.hh"
#include "G4SDManager.hh"
#include "G4Tokenizer.hh"
#include "G4UIparameter.hh"
#include "G4UserLimits.hh"
#include "G4VPhysicalVolume.hh"

#include "RMGGermaniumDetector.hh"
#include "RMGHardwareMessenger.hh"
#include "RMGLog.hh"
#include "RMGNavigationTools.hh"
#include "RMGOpticalDetector.hh"
Expand Down Expand Up @@ -131,6 +134,7 @@ void RMGHardware::ConstructSDandField() {
RMGLog::OutFormat(RMGLog::debug,
"Registered new sensitive detector volume of type {}: {} (uid={}, lv={})",
magic_enum::enum_name(v.type), pv->GetName().c_str(), v.uid, lv->GetName().c_str());
fActiveDetectorsInitialized = true;
}

std::string vec_repr = "";
Expand All @@ -153,6 +157,11 @@ void RMGHardware::ConstructSDandField() {

void RMGHardware::RegisterDetector(DetectorType type, const std::string& pv_name, int uid,
int copy_nr) {
if (fActiveDetectorsInitialized) {
RMGLog::Out(RMGLog::error,
"Active detectors cannot be mutated after constructing the detector.");
return;
}

// sanity check
for (const auto& [k, v] : fDetectorMetadata) {
Expand All @@ -178,6 +187,24 @@ void RMGHardware::RegisterDetector(DetectorType type, const std::string& pv_name
}
}

void RMGHardware::RegisterDetectorCmd(const std::string& parameters) {
G4Tokenizer next(parameters);

auto type_str = next();
auto type = magic_enum::enum_cast<DetectorType>(type_str);
if (!type.has_value()) {
RMGLog::OutFormat(RMGLog::error, "Invalid detector type {} in command", type_str);
return;
}
auto pv_name = next();
const int uid = std::stoi(next());
int copy_nr = 0;
auto copy_nr_str = next();
if (!copy_nr_str.empty()) copy_nr = std::stoi(copy_nr_str);

this->RegisterDetector(type.value(), pv_name, uid, copy_nr);
}

void RMGHardware::DefineCommands() {

fMessenger = std::make_unique<G4GenericMessenger>(this, "/RMG/Geometry/",
Expand All @@ -196,7 +223,8 @@ void RMGHardware::DefineCommands() {
.SetGuidance("Print list of defined physical volumes")
.SetStates(G4State_Idle);

// TODO: RegisterDetector() UI command interface
// RegisterDetector cannot be defined with the G4GenericMessenger (it has to many parameters).
fHwMessenger = std::make_unique<RMGHardwareMessenger>(this);
}

// vim: tabstop=2 shiftwidth=2 expandtab
52 changes: 52 additions & 0 deletions src/RMGHardwareMessenger.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// 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/>.

#include "RMGHardwareMessenger.hh"

#include "RMGHardware.hh"

#ifndef FMT_HEADER_ONLY
#define FMT_HEADER_ONLY
#endif
#include "fmt/core.h"
#include "magic_enum/magic_enum.hpp"

RMGHardwareMessenger::RMGHardwareMessenger(RMGHardware* hw) : fHardware(hw) {
auto detector_types = magic_enum::enum_names<RMGHardware::DetectorType>();
auto options = fmt::format("{}", fmt::join(detector_types, "|"));

fRegisterCmd = new G4UIcommand("/RMG/Geometry/RegisterDetector", this);
fRegisterCmd->SetGuidance("register a sensitive detector");
fRegisterCmd->SetGuidance("[usage] /RMG/Geometry/RegisterDetector T PV ID [C]");
fRegisterCmd->SetGuidance(fmt::format(" T:(str) {}", options).c_str());
fRegisterCmd->SetGuidance(" PV:(s) physvol");
fRegisterCmd->SetGuidance(" ID:(int) unique detector id");
fRegisterCmd->SetGuidance(" C:(int) copy nr (default 0)");

fRegisterCmd->SetParameter(new G4UIparameter("type", 's', false));
fRegisterCmd->SetParameter(new G4UIparameter("pv_name", 's', false));
fRegisterCmd->SetParameter(new G4UIparameter("uid", 'i', false));
fRegisterCmd->SetParameter(new G4UIparameter("copy_nr", 'i', true));

fRegisterCmd->AvailableForStates(G4State_PreInit);
}

RMGHardwareMessenger::~RMGHardwareMessenger() { delete fRegisterCmd; }

void RMGHardwareMessenger::SetNewValue(G4UIcommand* command, G4String newValues) {
if (command == fRegisterCmd) fHardware->RegisterDetectorCmd(newValues);
}

// vim: tabstop=2 shiftwidth=2 expandtab

0 comments on commit 502d335

Please sign in to comment.