Skip to content

Commit d808ad3

Browse files
committed
added also_reject_true_info to make sure true and digitized data are both rejected if so requested
1 parent d5f524c commit d808ad3

8 files changed

Lines changed: 73 additions & 58 deletions

File tree

.github/workflows/trigger_c12s_tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Trigger clas12-systems tests
1+
name: Triggers clas12-systems test
22

33
# Fires a workflow_dispatch on gemc/clas12-systems' Test workflow whenever the
44
# gemc/src Deploy workflow succeeds on a push to main, i.e. after fresh

gemc/actions/event/gEventAction.cc

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
#include "event/gEventDataCollection.h"
1010
#include "../generator/gPrimaryGeneratorAction.h"
1111

12+
// c++
13+
#include <algorithm>
14+
#include <cctype>
15+
1216
namespace {
1317
GGeneratedParticleBank make_generated_particle_bank(const GParticleRecordEvent& particles) {
1418
GGeneratedParticleBank bank;
@@ -31,6 +35,13 @@ GGeneratedParticleBank make_generated_particle_bank(const GParticleRecordEvent&
3135

3236
return bank;
3337
}
38+
39+
bool scalar_bool_option_enabled(const std::shared_ptr<GOptions>& goptions, const std::string& name) {
40+
std::string value = goptions->getScalarString(name);
41+
std::transform(value.begin(), value.end(), value.begin(),
42+
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
43+
return value == "true" || value == "1" || value == "yes" || value == "on";
44+
}
3445
}
3546

3647

@@ -92,6 +103,7 @@ void GEventAction::EndOfEventAction([[maybe_unused]] const G4Event* event) {
92103

93104
bool has_event_mode_payload = false;
94105
bool has_run_mode_payload = false;
106+
const bool also_reject_true_info = scalar_bool_option_enabled(goptions, "also_reject_true_info");
95107

96108
// Loop over every hit collection produced during this event and dispatch each
97109
// collection to the digitization routine registered under its collection name.
@@ -126,6 +138,7 @@ void GEventAction::EndOfEventAction([[maybe_unused]] const G4Event* event) {
126138
}
127139

128140
const auto collection_mode = digitization_routine->collection_mode();
141+
size_t accepted_hit_index = 0;
129142

130143
// Process all hits in the collection. Event-mode digitizers append to the
131144
// event container, while run-mode digitizers append to the run container.
@@ -136,18 +149,24 @@ void GEventAction::EndOfEventAction([[maybe_unused]] const G4Event* event) {
136149
continue;
137150
}
138151

139-
auto true_data = digitization_routine->collectTrueInformation(this_hit, hitIndex);
140152
auto digi_data = digitization_routine->digitizeHit(this_hit, hitIndex);
153+
const bool hit_accepted = digi_data != nullptr;
141154

142155
if (collection_mode == CollectionMode::event) {
143-
if (digi_data != nullptr) {
156+
if (hit_accepted) {
157+
++accepted_hit_index;
158+
digi_data->includeVariable("hitn", static_cast<int>(accepted_hit_index));
144159
eventDataCollection->addDetectorDigitizedData(hcSDName, std::move(digi_data));
145160
}
146-
eventDataCollection->addDetectorTrueInfoData(hcSDName, std::move(true_data));
147-
has_event_mode_payload = true;
161+
if (hit_accepted || !also_reject_true_info) {
162+
const size_t output_hit_index = hit_accepted ? accepted_hit_index : hitIndex + 1;
163+
auto true_data = digitization_routine->collectTrueInformation(this_hit, output_hit_index);
164+
eventDataCollection->addDetectorTrueInfoData(hcSDName, std::move(true_data));
165+
has_event_mode_payload = true;
166+
}
148167
}
149168
else if (collection_mode == CollectionMode::run) {
150-
if (digi_data != nullptr) {
169+
if (hit_accepted) {
151170
run_action->collect_event_data_collections(
152171
hcSDName,
153172
std::move(digi_data));

gemc/actions/generator/gPrimaryGeneratorAction.cc

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,6 @@ thread_local GParticleRecordEvent GPrimaryGeneratorAction::current_generated_par
1212
thread_local GParticleRecordEvent GPrimaryGeneratorAction::current_generated_tracked_particle_records;
1313

1414
namespace {
15-
GParticleRecord make_particle_record(const GparticlePtr& particle) {
16-
if (particle == nullptr) { return {}; }
17-
const auto& vertex = particle->getVertex();
18-
return {
19-
particle->getName(),
20-
particle->getPid(),
21-
particle->getGeneratorType(),
22-
particle->getMultiplicity(),
23-
particle->getMomentum(),
24-
particle->getTheta(),
25-
particle->getPhi(),
26-
vertex.x(),
27-
vertex.y(),
28-
vertex.z()
29-
};
30-
}
31-
3215
GParticleRecord make_particle_record(const GparticleRuntimeRecord& particle) {
3316
return {
3417
particle.name,
@@ -50,6 +33,14 @@ void append_runtime_records(GParticleRecordEvent& records, const GparticlePtr& p
5033
records.emplace_back(make_particle_record(runtime_record));
5134
}
5235
}
36+
37+
void append_untracked_file_records(GParticleRecordEvent& records, const GParticleRecordEvent& source_records) {
38+
for (const auto& record : source_records) {
39+
if (record.type != 1) {
40+
records.emplace_back(record);
41+
}
42+
}
43+
}
5344
}
5445

5546
// Build the primary-generator action, load the configured particle definitions,
@@ -94,18 +85,14 @@ void GPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent) {
9485
current_generated_tracked_particle_records.clear();
9586

9687
current_generated_particles.insert(current_generated_particles.end(), gparticles->begin(), gparticles->end());
97-
current_generated_tracked_particles.insert(current_generated_tracked_particles.end(), gparticles->begin(), gparticles->end());
98-
current_generated_particle_records.reserve(gparticles->size());
99-
for (const auto& gparticle : *gparticles) {
100-
current_generated_particle_records.emplace_back(make_particle_record(gparticle));
101-
}
88+
current_generated_tracked_particles.insert(current_generated_tracked_particles.end(),
89+
gparticles->begin(),
90+
gparticles->end());
10291

10392
const auto event_id = anEvent->GetEventID();
10493
if (event_id >= 0 && static_cast<size_t>(event_id) < allGparticleFileRecordEvents.size()) {
10594
const auto& event_particles = allGparticleFileRecordEvents[static_cast<size_t>(event_id)];
106-
current_generated_particle_records.insert(current_generated_particle_records.end(),
107-
event_particles.begin(),
108-
event_particles.end());
95+
append_untracked_file_records(current_generated_particle_records, event_particles);
10996
}
11097
if (event_id >= 0 && static_cast<size_t>(event_id) < gparticleFileEvents.size()) {
11198
const auto& event_particles = gparticleFileEvents[static_cast<size_t>(event_id)];
@@ -117,6 +104,7 @@ void GPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent) {
117104
for (const auto& gparticle : *gparticles) {
118105
if (gparticle != nullptr) {
119106
gparticle->shootParticle(gparticleGun.get(), anEvent);
107+
append_runtime_records(current_generated_particle_records, gparticle);
120108
append_runtime_records(current_generated_tracked_particle_records, gparticle);
121109
}
122110
}
@@ -129,6 +117,7 @@ void GPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent) {
129117
for (const auto& gparticle : gparticleFileEvents[static_cast<size_t>(event_id)]) {
130118
if (gparticle != nullptr) {
131119
gparticle->shootParticle(gparticleGun.get(), anEvent);
120+
append_runtime_records(current_generated_particle_records, gparticle);
132121
append_runtime_records(current_generated_tracked_particle_records, gparticle);
133122
}
134123
}

gemc/actions/generator/gPrimaryGeneratorAction.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ inline GOptions defineOptions() {
6464
* a default particle so the simulation still has a valid primary source.
6565
*
6666
* The class also exposes thread-local generated-particle snapshots for event
67-
* output. The \c generated snapshot includes inline particles and all parsed
68-
* file rows. The \c generated_tracked snapshot includes inline particles and
69-
* only the file rows propagated in Geant4.
67+
* output. The \c generated snapshot contains runtime records for particles
68+
* propagated in Geant4 plus source-only file rows that are not propagated. The
69+
* \c generated_tracked snapshot contains only the runtime records propagated
70+
* in Geant4.
7071
*
7172
* @ingroup gactions_module
7273
*/
@@ -130,8 +131,9 @@ class GPrimaryGeneratorAction : public GBase<GPrimaryGeneratorAction>, public G4
130131
/**
131132
* \brief Returns the current event's full generated-particle records.
132133
*
133-
* This is the source for the \c generated output bank. It includes inline
134-
* particles and every parsed file-backed particle row.
134+
* This is the source for the \c generated output bank. It includes runtime
135+
* records for propagated particles and source-only records for file-backed
136+
* rows not propagated in Geant4.
135137
*
136138
* \return Thread-local generated-particle records for the active event.
137139
*/
@@ -141,7 +143,7 @@ class GPrimaryGeneratorAction : public GBase<GPrimaryGeneratorAction>, public G4
141143
* \brief Returns the current event's Geant4-tracked generated-particle records.
142144
*
143145
* This is the source for the \c generated_tracked output bank. It includes
144-
* inline particles and only file-backed particles propagated in Geant4.
146+
* only runtime records for particles propagated in Geant4.
145147
*
146148
* \return Thread-local tracked generated-particle records for the active event.
147149
*/

gemc/gdata/event/gEventDataCollection.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ constexpr const char* GEVENTDATA_LOGGER = "gevent_data";
4747
* the gparticle module from gdata. It is used by event streamers to publish
4848
* generated-particle metadata alongside detector hit banks.
4949
*
50-
* The \c generated bank contains inline \c -gparticle definitions and every
51-
* parsed \c -gparticlefile row. The \c generated_tracked bank contains inline
52-
* \c -gparticle definitions and only the file rows propagated in Geant4,
53-
* normally rows with \c type == 1.
50+
* The \c generated bank contains runtime records for particles propagated in
51+
* Geant4 plus source-only file rows that are not propagated. The
52+
* \c generated_tracked bank contains only runtime records for particles
53+
* propagated in Geant4, normally rows with \c type == 1 for Lund input.
5454
*/
5555
struct GGeneratedParticleData
5656
{
@@ -197,16 +197,16 @@ class GEventDataCollection : public GBase<GEventDataCollection>
197197
*
198198
* \return Const reference to the detector map.
199199
*/
200-
[[nodiscard]] auto getDataCollectionMap() const -> const std::map<std::string, std::unique_ptr<GDataCollection>>& {
200+
[[nodiscard]] auto getDataCollectionMap() const
201+
-> const std::map<std::string, std::unique_ptr<GDataCollection>>& {
201202
return gdataCollectionMap;
202203
}
203204

204205
/**
205206
* \brief Stores the full generated-particle bank for this event.
206207
*
207-
* The bank named \c generated contains inline \c -gparticle definitions
208-
* plus all parsed \c -gparticlefile rows, including file particles that
209-
* are not propagated in Geant4.
208+
* The bank named \c generated contains runtime records for particles
209+
* propagated in Geant4 plus source-only file rows that are not propagated.
210210
*
211211
* \param particles Generated-particle rows to store.
212212
*/
@@ -217,9 +217,8 @@ class GEventDataCollection : public GBase<GEventDataCollection>
217217
/**
218218
* \brief Stores the Geant4-tracked generated-particle bank for this event.
219219
*
220-
* The bank named \c generated_tracked contains inline \c -gparticle
221-
* definitions plus only the file particles propagated in Geant4, normally
222-
* those with source \c type == 1.
220+
* The bank named \c generated_tracked contains only runtime records for
221+
* particles propagated in Geant4, normally those with source \c type == 1.
223222
*
224223
* \param particles Generated-particle rows to store.
225224
*/
@@ -239,7 +238,9 @@ class GEventDataCollection : public GBase<GEventDataCollection>
239238
*
240239
* \return Rows published as the \c generated_tracked output bank.
241240
*/
242-
[[nodiscard]] const GGeneratedParticleBank& getGeneratedTrackedParticles() const { return generated_tracked_particles; }
241+
[[nodiscard]] const GGeneratedParticleBank& getGeneratedTrackedParticles() const {
242+
return generated_tracked_particles;
243+
}
243244

244245
/**
245246
* \brief Returns the event number stored in the owned header.

gemc/gstreamer/gstreamer.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -616,10 +616,11 @@ namespace gstreamer {
616616
for (const auto& gstreamer_def : gstreamer::getGStreamerDefinition(gopts)) {
617617
auto gstreamer_def_thread = GStreamerDefinition(gstreamer_def, thread_id);
618618
std::string gstreamer_plugin = gstreamer_def_thread.gstreamerPluginName();
619-
// Key the map by the unique per-output rootname so that multiple same-format
620-
// outputs (e.g. two csv files) do not collide; the plugin library is still
621-
// loaded by the format-derived plugin name.
622-
const std::string& output_key = gstreamer_def_thread.rootname;
619+
// Key the map by the format-derived plugin name combined with the per-output
620+
// rootname so that neither multiple same-format outputs (e.g. two csv files)
621+
// nor multiple same-rootname outputs of different formats (e.g. dc.csv and
622+
// dc.hipo) collide; the plugin library is still loaded by the plugin name.
623+
const std::string output_key = gstreamer_plugin + ":" + gstreamer_def_thread.rootname;
623624

624625
// Load the plugin object for this configured output. Each call returns a
625626
// fresh GStreamer instance, so same-format outputs stay independent.

gemc/gstreamer/gstreamerDoxy.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,10 @@
135135
* \subsection gstreamer_arch_generated Generated-particle banks
136136
* Event output includes two generated-particle banks when generator metadata is
137137
* available:
138-
* - \c generated : inline \c -gparticle definitions plus every parsed
139-
* \c -gparticlefile particle, including rows that are not propagated in Geant4.
140-
* - \c generated_tracked : inline \c -gparticle definitions plus only the
141-
* \c -gparticlefile particles that are propagated in Geant4. For Lund input,
142-
* this corresponds to rows with \c type == 1.
138+
* - \c generated : runtime records for particles propagated in Geant4 plus
139+
* source-only file rows that are not propagated.
140+
* - \c generated_tracked : runtime records for particles propagated in Geant4.
141+
* For Lund input, this corresponds to rows with \c type == 1.
143142
*
144143
* Both banks publish the same columns: particle name, pid, source type,
145144
* multiplicity, momentum, theta, phi, and vertex components. The concrete

gemc_options.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ namespace gemc {
3838

3939
// switches
4040
goptions.defineOption(GVariable("nthreads", 0, "sets number of threads."), "Default: 0 (use one thread for each available cores)");
41+
goptions.defineOption(
42+
GVariable("also_reject_true_info", true, "also reject true information for rejected hits"),
43+
"Drops true information for hits rejected by detector digitization. Default: true.\n"
44+
"Set to false to keep true information for all Geant4 hits even when no digitized hit is written.");
4145
// goptions.defineOption(GVariable("event_module_log", 0, "Event Modulo log"), "Logs every <value> events. Default: 0 (log all events)");
4246
//
4347
// goptions.defineOption(GVariable("eventTimeSize", "0*ns", "event duration with unit"), "Default: 0*ns");

0 commit comments

Comments
 (0)