Skip to content

Commit f04f230

Browse files
authored
Merge 6c75dbc into sapling-pr-archive-ktf
2 parents 9e08360 + 6c75dbc commit f04f230

27 files changed

Lines changed: 1264 additions & 57 deletions

CCDB/src/CcdbApi.cxx

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include <regex>
4747
#include <cstdio>
4848
#include <string>
49+
#include <string_view>
4950
#include <TAlienUserAgent.h>
5051
#include <unordered_set>
5152
#include "rapidjson/document.h"
@@ -62,6 +63,19 @@ unique_ptr<TJAlienCredentials> CcdbApi::mJAlienCredentials = nullptr;
6263

6364
namespace
6465
{
66+
/// Strip surrounding whitespace, CR and LF included.
67+
///
68+
/// A value that keeps its line's trailing CRLF ends the header block early when
69+
/// it is spliced back into a request, silently dropping every header after it.
70+
std::string_view trimHeaderValue(std::string_view value)
71+
{
72+
constexpr std::string_view whitespace = " \t\r\n";
73+
const auto first = value.find_first_not_of(whitespace);
74+
return first == std::string_view::npos
75+
? std::string_view{}
76+
: value.substr(first, value.find_last_not_of(whitespace) - first + 1);
77+
}
78+
6579
/// Append the gate token, if ALICEO2_CCDB_AUTH_TOKEN names one, to a header list.
6680
///
6781
/// Set when CCDB is reached through a broker that authenticates its callers.
@@ -77,7 +91,11 @@ curl_slist* appendGateToken(curl_slist* list)
7791
{
7892
static const std::string header = []() -> std::string {
7993
const char* token = getenv("ALICEO2_CCDB_AUTH_TOKEN");
80-
return (token && *token) ? std::string("Authorization: Bearer ") + token : std::string();
94+
// Trimmed, because a token carrying a newline -- one read out of a file, say
95+
// -- makes the request malformed, which a strict broker rejects with an
96+
// opaque 400 rather than an auth error.
97+
const auto value = token ? trimHeaderValue(token) : std::string_view{};
98+
return value.empty() ? std::string() : std::string("Authorization: Bearer ").append(value);
8199
}();
82100
return header.empty() ? list : curl_slist_append(list, header.c_str());
83101
}
@@ -1620,11 +1638,13 @@ void CcdbApi::parseCCDBHeaders(std::vector<std::string> const& headers, std::vec
16201638
{
16211639
static std::string etagHeader = "ETag: ";
16221640
static std::string locationHeader = "Content-Location: ";
1641+
// Trimmed: `headers` holds raw header lines, CRLF and all, and the etag goes
1642+
// straight back out as an If-None-Match request header.
16231643
for (auto h : headers) {
16241644
if (h.find(etagHeader) == 0) {
1625-
etag = std::string(h.data() + etagHeader.size());
1645+
etag = trimHeaderValue(std::string_view(h).substr(etagHeader.size()));
16261646
} else if (h.find(locationHeader) == 0) {
1627-
pfns.emplace_back(std::string(h.data() + locationHeader.size(), h.size() - locationHeader.size()));
1647+
pfns.emplace_back(trimHeaderValue(std::string_view(h).substr(locationHeader.size())));
16281648
}
16291649
}
16301650
}

Common/SimConfig/include/SimConfig/G4Params.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ struct G4Params : public o2::conf::ConfigurableParamHelper<G4Params> {
5454

5555
bool g4scoring = false;
5656
bool g4fluenceweight = false;
57+
58+
// Fast simulation. Empty fastSimModels (the default) disables the feature
59+
// entirely; see Detectors/gconfig/include/SimSetup/G4FastSimulation.h.
60+
std::string fastSimModels = ""; // comma-separated model names to activate
61+
std::string fastSimEnvelope = ""; // volume a model stands in for, e.g. AFaM; the media of its
62+
// subtree are collected automatically
63+
std::string fastSimRegions = ""; // optional explicit media, overriding the subtree walk
64+
float fastSimMinEnergy = 1.f; // GeV; below this the detailed transport runs
5765
O2ParamDef(G4Params, "G4");
5866
};
5967

Detectors/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ add_subdirectory(ForwardAlign)
5353

5454

5555
if(BUILD_SIMULATION)
56+
add_subdirectory(FastSim)
5657
add_subdirectory(gconfig)
5758
o2_data_file(COPY gconfig DESTINATION Detectors)
5859
endif()

Detectors/FastSim/CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2+
# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
# All rights not expressly granted are reserved.
4+
#
5+
# This software is distributed under the terms of the GNU General Public
6+
# License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
#
8+
# In applying this license CERN does not waive the privileges and immunities
9+
# granted to it by virtue of its status as an Intergovernmental Organization
10+
# or submit itself to any jurisdiction.
11+
12+
o2_add_library(FastSim
13+
SOURCES src/FastSimModel.cxx
14+
src/FastSimRegions.cxx
15+
src/ToyAbsorberFastSim.cxx
16+
src/G4FastSimulation.cxx
17+
PUBLIC_LINK_LIBRARIES MC::Geant4VMC MC::Geant4 O2::SimConfig
18+
)
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#ifndef O2_FASTSIM_MODEL_H_
13+
#define O2_FASTSIM_MODEL_H_
14+
15+
/// Base class for fast simulation models.
16+
///
17+
/// A fast simulation model replaces the detailed transport through a region of
18+
/// the geometry by a function from the particle that enters it to the particles
19+
/// that leave it. `DoIt()` is Geant4's own entry point
20+
/// (`G4VFastSimulationModel::DoIt`); the implementation here wraps the logic
21+
/// common to every model and delegates the physics to `sample()`. A model that
22+
/// needs a different shape can still override `DoIt()`.
23+
24+
#include "G4VFastSimulationModel.hh"
25+
26+
#include <vector>
27+
28+
class G4FastStep;
29+
class G4FastTrack;
30+
class G4ParticleDefinition;
31+
32+
namespace o2::fastsim
33+
{
34+
35+
/// The particle entering the envelope, plus the geometric context a model needs.
36+
/// Units are the O2/VMC ones: cm, GeV, ns.
37+
struct FastSimInput {
38+
int pdg = 0;
39+
double position[3] = {}; ///< global, on the envelope surface
40+
double direction[3] = {}; ///< unit vector
41+
double kineticEnergy = 0.; ///< GeV
42+
double mass = 0.; ///< GeV
43+
double time = 0.; ///< ns
44+
double exitDistance = 0.; ///< cm from `position` to the ENVELOPE surface along `direction`
45+
};
46+
47+
/// One particle leaving the envelope.
48+
struct FastSimOutput {
49+
int pdg = 0;
50+
double position[3] = {}; ///< global; put it outside the envelope surface
51+
double momentum[3] = {}; ///< GeV/c
52+
double time = 0.; ///< ns
53+
};
54+
55+
/// A secondary created exactly on the envelope surface is located by the
56+
/// navigator in whichever daughter owns that point, which costs two extra
57+
/// zero-length steps before it gets out. Models should emit just beyond it.
58+
constexpr double kSurfaceEpsilonCm = 1e-5;
59+
60+
/// Base class for fast simulation models.
61+
///
62+
/// The model is attached to regions (see G4FastSimulation.h) purely so that
63+
/// Geant4 consults it; what it encloses is the ENVELOPE VOLUME named below,
64+
/// which is normally the mother volume of a whole module. The two are
65+
/// deliberately separate, because a Geant4 region in O2 can only ever be "every
66+
/// volume of a given material" -- the VMC special cuts make every logical volume
67+
/// a root of its own material's region, and Geant4 stops propagating a region at
68+
/// any such daughter. So `G4FastTrack::GetEnvelopeSolid()` would hand back one
69+
/// absorber piece rather than the absorber, and this class does not use it.
70+
///
71+
/// Containment and the exit distance are taken from the track's own touchable,
72+
/// which already carries the full ancestry and the transform of every level.
73+
class FastSimModel : public G4VFastSimulationModel
74+
{
75+
public:
76+
FastSimModel(const G4String& name, const G4String& envelopeVolume, double minEnergyGeV);
77+
78+
G4bool IsApplicable(const G4ParticleDefinition& particle) override;
79+
G4bool ModelTrigger(const G4FastTrack& fastTrack) override;
80+
81+
/// Wraps the common logic of a fast simulation action and delegates the
82+
/// physics to `sample()`: it measures the distance to the envelope surface,
83+
/// kills the incident particle, stacks what `sample()` returned and books the
84+
/// energy difference as a deposit. Override it for a model that does not fit
85+
/// that shape.
86+
void DoIt(const G4FastTrack& fastTrack, G4FastStep& fastStep) override;
87+
88+
protected:
89+
/// Given the particle that entered, return everything that leaves. This is
90+
/// the function a trained model implements.
91+
virtual std::vector<FastSimOutput> sample(const FastSimInput& input) const = 0;
92+
93+
private:
94+
/// The track's ancestry level at which the envelope volume sits, or -1 when
95+
/// the track is not inside it at all.
96+
int envelopeDepth(const G4Track* track) const;
97+
98+
G4String mEnvelope; ///< logical volume the model encloses
99+
double mMinEnergy = 0.; ///< internal Geant4 units; below this the detailed transport runs
100+
mutable bool mWarned = false;
101+
};
102+
103+
} // namespace o2::fastsim
104+
105+
#endif // O2_FASTSIM_MODEL_H_
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#ifndef O2_FASTSIM_REGIONS_H_
13+
#define O2_FASTSIM_REGIONS_H_
14+
15+
/// Deriving a model's regions from its envelope volume.
16+
///
17+
/// Geant4-VMC attaches a fast simulation model to regions, and in O2 a region
18+
/// can only be "every volume of a given material" (see FastSimModel.h). To have
19+
/// the model consulted everywhere inside a module, it must therefore be attached
20+
/// to every material that module is built from -- which is a list nobody should
21+
/// maintain by hand, because it changes whenever the geometry does.
22+
///
23+
/// So walk the envelope's subtree and collect the media as they actually are.
24+
25+
#include "TG4VUserPostDetConstruction.h"
26+
27+
#include <set>
28+
#include <string>
29+
#include <vector>
30+
31+
class TGeoVolume;
32+
33+
namespace o2::fastsim
34+
{
35+
36+
/// Every tracking medium used by `volume` or anything below it.
37+
/// Takes a non-const pointer because TGeo's accessors are not const.
38+
std::set<std::string> mediaInSubtree(TGeoVolume* volume);
39+
40+
/// Same, looked up by volume name in the current TGeo geometry. Empty if there
41+
/// is no such volume.
42+
std::set<std::string> mediaInSubtree(const std::string& volumeName);
43+
44+
/// Sets each model's regions from its envelope, in the one window where that is
45+
/// possible: after the geometry is built and before Geant4-VMC turns the media
46+
/// into regions.
47+
class FastSimRegionConstruction : public TG4VUserPostDetConstruction
48+
{
49+
public:
50+
struct ModelRegions {
51+
std::string model;
52+
std::string envelope; ///< volume whose subtree supplies the media
53+
std::string regions; ///< explicit media, used instead of the walk if given
54+
};
55+
56+
explicit FastSimRegionConstruction(std::vector<ModelRegions> models);
57+
void Construct() override;
58+
59+
private:
60+
std::vector<ModelRegions> mModels;
61+
};
62+
63+
} // namespace o2::fastsim
64+
65+
#endif // O2_FASTSIM_REGIONS_H_
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#ifndef O2_FASTSIM_G4_FAST_SIMULATION_H_
13+
#define O2_FASTSIM_G4_FAST_SIMULATION_H_
14+
15+
/// Wiring of the fast simulation models into the Geant4 engine.
16+
///
17+
/// The feature is OFF unless `G4.fastSimModels` names a model.
18+
///
19+
/// o2-sim -n 10 -g pythia8pp -e TGeant4 -m PIPE ABSO
20+
/// --configKeyValues "G4.fastSimModels=toyAbsorber;
21+
/// G4.fastSimEnvelope=AFaM"
22+
///
23+
/// `G4.fastSimEnvelope` names the VOLUME the model stands in for. The regions
24+
/// Geant4 needs in order to consult the model are derived from it by walking its
25+
/// subtree and collecting the media (FastSimRegions.h) -- a region in O2 can only
26+
/// be "every volume of a given material", so covering a module means naming all
27+
/// of its materials, and that list should not be maintained by hand.
28+
///
29+
/// `G4.fastSimRegions` overrides the walk with an explicit space-separated list
30+
/// of media, for when a model should see less than a whole subtree.
31+
32+
#include "TG4RunConfiguration.h"
33+
#include "TG4VUserFastSimulation.h"
34+
#include "TG4VUserPostDetConstruction.h"
35+
36+
#include <string>
37+
#include <vector>
38+
39+
namespace o2::fastsim
40+
{
41+
42+
/// Creates and registers the models named in `G4.fastSimModels`.
43+
class G4FastSimulation : public TG4VUserFastSimulation
44+
{
45+
public:
46+
G4FastSimulation(std::vector<std::string> models, const std::string& envelope,
47+
double minEnergyGeV);
48+
void Construct() override;
49+
50+
private:
51+
std::vector<std::string> mModels;
52+
std::string mEnvelope;
53+
double mMinEnergy = 1.;
54+
};
55+
56+
/// Supplies Geant4-VMC with the fast simulation models and their regions.
57+
/// Returns nullptr when no model is configured, so nothing is set up.
58+
class G4RunConfiguration : public TG4RunConfiguration
59+
{
60+
public:
61+
using TG4RunConfiguration::TG4RunConfiguration;
62+
TG4VUserFastSimulation* CreateUserFastSimulation() override;
63+
TG4VUserPostDetConstruction* CreateUserPostDetConstruction() override;
64+
};
65+
66+
} // namespace o2::fastsim
67+
68+
#endif // O2_FASTSIM_G4_FAST_SIMULATION_H_
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2019-2026 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
#ifndef O2_FASTSIM_TOY_ABSORBER_H_
13+
#define O2_FASTSIM_TOY_ABSORBER_H_
14+
15+
#include "FastSim/FastSimModel.h"
16+
17+
namespace o2::fastsim
18+
{
19+
20+
/// A toy fast simulation model for the absorber: one particle out, continuing
21+
/// along the incident direction with the energy exponentially attenuated over
22+
/// the path through the envelope.
23+
class ToyAbsorberFastSim : public FastSimModel
24+
{
25+
public:
26+
using FastSimModel::FastSimModel;
27+
28+
protected:
29+
std::vector<FastSimOutput> sample(const FastSimInput& input) const override;
30+
};
31+
32+
} // namespace o2::fastsim
33+
34+
#endif // O2_FASTSIM_TOY_ABSORBER_H_

0 commit comments

Comments
 (0)