48 std::vector<std::pair<std::string, double>> regions = {})
50 field_source_{&field_source},
52 ke_threshold_{ke_threshold},
53 regions_{std::move(regions)} {}
62 for (
auto* lv : *G4LogicalVolumeStore::GetInstance()) {
63 for (
int i = 0; i < static_cast<int>(sv_names.size()); ++i) {
64 if (G4StrUtil::contains(lv->GetName(), std::string_view{sv_names[i]})) {
65 detector_ids.emplace(lv, i);
71 G4VSensitiveDetector* sd =
nullptr;
73 sd =
new CrossingSD(
"CrossingSD", detector_ids, ke_threshold_);
75 sd =
new ScoringSD(
"ScoringSD", detector_ids);
77 G4SDManager::GetSDMpointer()->AddNewDetector(sd);
79 for (
auto [lv, _] : detector_ids) {
80 lv->SetSensitiveDetector(sd);
88 for (
auto const& fr : field_source_->regions()) {
89 auto* adapter =
new ship::G4MagFieldAdapter(fr.field);
90 auto* fmgr =
new G4FieldManager(adapter);
92 for (
auto* lv : *G4LogicalVolumeStore::GetInstance()) {
93 if (G4StrUtil::contains(lv->GetName(),
94 std::string_view{fr.volume_pattern})) {
95 lv->SetFieldManager(fmgr,
true);
100 throw std::runtime_error(
"Field region '" + fr.name +
101 "': volume_pattern '" + fr.volume_pattern +
102 "' matches no logical volumes");
106 std::call_once(regions_flag_, [
this]() {
107 for (
auto const& [pattern, cut_mm] : regions_) {
108 auto* region =
new G4Region(pattern);
109 auto* cuts =
new G4ProductionCuts();
110 cuts->SetProductionCut(cut_mm * mm);
111 region->SetProductionCuts(cuts);
112 for (
auto* lv : *G4LogicalVolumeStore::GetInstance()) {
113 if (G4StrUtil::contains(lv->GetName(), std::string_view{pattern}))
114 region->AddRootLogicalVolume(lv);