dbselect
Loading...
Searching...
No Matches
test_reload_sequence.cc
Go to the documentation of this file.
1
17// dbselect
18#include "dbselect_options.h"
19
20// gdetector
22
23// gsd (for GHitsCollection typedef)
24#include "gsd.h"
25
26// gemc
27#include "gsystemConventions.h"
28
29// geant4
30#include "G4RunManagerFactory.hh"
31#include "G4VUserPrimaryGeneratorAction.hh"
32#include "G4VUserActionInitialization.hh"
33#include "G4UserEventAction.hh"
34#include "G4ParticleGun.hh"
35#include "G4ParticleTable.hh"
36#include "G4HCofThisEvent.hh"
37#include "G4Event.hh"
38#include "G4SystemOfUnits.hh"
39#include "QBBC.hh"
40
41// c++
42#include <atomic>
43#include <iostream>
44#include <memory>
45#include <string>
46
47// Per-phase hit counters — incremented once per event that contains ≥1 hit.
48static std::atomic<int> g_hitsFlux{0};
49static std::atomic<int> g_hitsDosimeter{0};
50
51// ---------------------------------------------------------------------------
52// Particle gun: proton along +Z from z=-100 mm at 1 GeV.
53// Intercepts the simple_flux plane (z=50 mm, 240×240 mm; world half=150 mm).
54// ---------------------------------------------------------------------------
55class PrimaryGenerator : public G4VUserPrimaryGeneratorAction {
56 G4ParticleGun gun;
57public:
58 PrimaryGenerator() : gun(1) {
59 auto* proton = G4ParticleTable::GetParticleTable()->FindParticle("proton");
60 gun.SetParticleDefinition(proton);
61 gun.SetParticlePosition(G4ThreeVector(0, 0, -100 * mm));
62 gun.SetParticleMomentumDirection(G4ThreeVector(0, 0, 1));
63 gun.SetParticleEnergy(1 * GeV);
64 }
65 void GeneratePrimaries(G4Event* ev) override { gun.GeneratePrimaryVertex(ev); }
66};
67
68// ---------------------------------------------------------------------------
69// Event action: count events that have hits in each SD.
70// ---------------------------------------------------------------------------
71class EventAction : public G4UserEventAction {
72public:
73 void EndOfEventAction(const G4Event* event) override {
74 // G4HCofThisEvent::GetHC / GetNumberOfCollections are not marked const in G4 11.4.
75 auto* hc = const_cast<G4HCofThisEvent*>(event->GetHCofThisEvent());
76 if (!hc) return;
77 for (G4int i = 0; i < hc->GetNumberOfCollections(); ++i) {
78 auto* col = static_cast<GHitsCollection*>(hc->GetHC(i));
79 if (!col || col->GetSize() == 0) continue;
80 const std::string sdName = col->GetSDname();
81 if (sdName == "flux")
82 g_hitsFlux.fetch_add(1, std::memory_order_relaxed);
83 else if (sdName == "dosimeter")
84 g_hitsDosimeter.fetch_add(1, std::memory_order_relaxed);
85 }
86 }
87};
88
89// ---------------------------------------------------------------------------
90// Action initialisation — called by Geant4 per worker thread on Initialize().
91// ---------------------------------------------------------------------------
92class ActionInit : public G4VUserActionInitialization {
93public:
94 void Build() const override {
95 SetUserAction(new PrimaryGenerator);
96 SetUserAction(new EventAction);
97 }
98};
99
100// ---------------------------------------------------------------------------
101// Helpers to build a fresh descriptor for each system.
102// ---------------------------------------------------------------------------
103static auto makeSystem(const std::shared_ptr<GOptions>& gopts, const std::string& dbhost,
104 const std::string& name) {
105 return std::make_shared<GSystem>(gopts, dbhost, name,
106 GSYSTEMSQLITETFACTORYLABEL, "examples", 1, "default");
107}
108
109// ---------------------------------------------------------------------------
110// Run one phase: reload geometry, prepare for run, BeamOn, return hit counts.
111// ---------------------------------------------------------------------------
112static void runPhase(const char* label,
114 G4RunManager* rm,
115 SystemList systems,
116 int& outFlux, int& outDosi) {
117 g_hitsFlux = 0;
118 g_hitsDosimeter = 0;
119
120 gdetector->reload_geometry(std::move(systems));
121 gdetector->prepare_geometry_for_run();
122 rm->BeamOn(10);
123
124 outFlux = g_hitsFlux.load();
125 outDosi = g_hitsDosimeter.load();
126 std::cout << label << ": flux=" << outFlux << " dosimeter=" << outDosi << "\n";
127}
128
129// ---------------------------------------------------------------------------
130int main(int argc, char* argv[]) {
131 auto gopts = std::make_shared<GOptions>(argc, argv, dbselect::defineOptions());
132
133 const std::string dbhost = gopts->getScalarString("sql");
134
135 auto* runManager = G4RunManagerFactory::CreateRunManager(G4RunManagerType::Default);
136 runManager->SetNumberOfThreads(2);
137 runManager->SetUserInitialization(new QBBC);
138
139 auto* gdetector = new GDetectorConstruction(gopts);
140 runManager->SetUserInitialization(gdetector);
141 runManager->SetUserInitialization(new ActionInit);
142
143 std::cout << "\n=== Reload Sequence Test ===\n";
144
145 int flux1 = 0, dosi1 = 0;
146 runPhase("Phase 1 (simple_flux)", gdetector, runManager,
147 {makeSystem(gopts, dbhost, "simple_flux")}, flux1, dosi1);
148
149 int flux2 = 0, dosi2 = 0;
150 runPhase("Phase 2 (b1)", gdetector, runManager,
151 {makeSystem(gopts, dbhost, "b1")}, flux2, dosi2);
152
153 int flux3 = 0, dosi3 = 0;
154 runPhase("Phase 3 (simple_flux)", gdetector, runManager,
155 {makeSystem(gopts, dbhost, "simple_flux")}, flux3, dosi3);
156
157 std::cout << "\n=== Results ===\n";
158
159 // Stale-SD check: the flux SD must not fire during the b1-only phase.
160 bool stale_flux_in_b1 = (flux2 > 0);
161 bool stale_dosi_in_flux = (dosi1 > 0 || dosi3 > 0);
162
163 if (stale_flux_in_b1)
164 std::cout << "WARNING: unexpected flux hits in Phase 2 (stale SD).\n";
165 if (stale_dosi_in_flux)
166 std::cout << "WARNING: unexpected dosimeter hits in flux-only phases (stale SD).\n";
167
168 bool passed = (flux1 > 0) && (flux3 > 0) && !stale_flux_in_b1 && !stale_dosi_in_flux;
169
170 delete runManager;
171
172 if (passed) {
173 std::cout << "PASSED\n";
174 return EXIT_SUCCESS;
175 }
176 std::cout << "FAILED"
177 << (flux1 == 0 ? " (no flux hits in Phase 1)" : "")
178 << (flux3 == 0 ? " (no flux hits in Phase 3)" : "")
179 << (stale_flux_in_b1 ? " (stale flux SD in Phase 2)" : "")
180 << (stale_dosi_in_flux ? " (stale dosimeter SD in flux phases)" : "")
181 << "\n";
182 return EXIT_FAILURE;
183}
void Build() const override
void EndOfEventAction(const G4Event *event) override
void GeneratePrimaries(G4Event *ev) override
G4THitsCollection< GHit > GHitsCollection
std::vector< SystemPtr > SystemList
GOptions defineOptions()
Define and return the option set used by the dbselect module.
int main(int argc, char *argv[])