ATLAS Offline Software
Loading...
Searching...
No Matches
LRAVertexPositioner.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration.
3*/
4
6
7//---
8
9#include "CLHEP/Random/RandFlat.h"
10#include "CLHEP/Vector/LorentzVector.h"
11
14
15//---
16
17namespace Simulation
18{
19 LRAVertexPositioner::LRAVertexPositioner(const std::string &t, const std::string &n, const IInterface *p)
20 : base_class(t,n,p)
21 {
22 };
23
24 //---
25
27 {
28 // Resolve the LRA file name.
29 const auto FilePath = PathResolverFindDataFile(m_FileName);
30 if(FilePath.empty())
31 {
32 ATH_MSG_ERROR("Unable to resolve LRAFile: m_FileName = " << (std::string)m_FileName);
33
34 return StatusCode::FAILURE;
35 };
36
37 // Open the file...
38 m_LRAFile = std::unique_ptr<TFile>(TFile::Open(FilePath.c_str(), "READ"));
39 if(!m_LRAFile)
40 {
41 ATH_MSG_ERROR("Unable to open LRAFile: FilePath = " << FilePath);
42
43 return StatusCode::FAILURE;
44 };
45
46 // ... and get the histogram.
47 // ToDo: We should re-evaluate holding open the TFile, compared to cloaning out the bits of interest.
48 // Requires access to a real LRA file.
49 m_LRAHist = m_LRAFile->Get<TH3F>(((std::string)m_HistName).c_str());
50 if(!m_LRAHist)
51 {
52 ATH_MSG_ERROR("Unable to get LRAHist: FilePath = " << FilePath << ", m_HistName = " << (std::string)m_HistName);
53
54 return StatusCode::FAILURE;
55 };
56
57 // ToDo: In the medium term we should look at cleaning up the Lumi groups code, adding whatever the
58 // BS group needs it to do, and getting that into Athena(_externals). The code above could then
59 // be changed to generate the TH3 dynamicaly (maybe simplyfing the configuration of all the tools),
60 // and the future vdM BSFinder could use the unbinned PDF.
61
62 //---
63
64 // Retrieve the tool handle to the RNG service...
65 ATH_CHECK(m_RNGService.retrieve());
66
67 // ... and get the RNG engine.
68 m_RNGEngine = m_RNGService->getEngine(this, m_RNGStream);
69 if (!m_RNGEngine)
70 {
71 ATH_MSG_ERROR("Unable to get RNGEngine: m_RNGStream = " << (std::string) m_RNGStream);
72
73 return StatusCode::FAILURE;
74 };
75
76 //---
77
78 // Cache the bin counts.
79 const auto nBinsX = m_LRAHist->GetNbinsX();
80 const auto nBinsY = m_LRAHist->GetNbinsY();
81 const auto nBinsZ = m_LRAHist->GetNbinsZ();
82
83 // Pre-allocate the space in the vector.
84 m_Integral.reserve(nBinsX * nBinsY * nBinsZ);
85
86 /*
87 Loop over the bins in the histogram, and store the bin numbers and the running integral into m_Integral.
88
89 Assumes the LRA histograms are "well-formed" PDFs:
90 Unit integral.
91 No probability in under/over-flow bins
92 No negative bins.
93
94 Is ugly, better would be ranges, iota * 3 -> cartesian_product -> for_each, but needs C++23 (No Stinking Loops!!!)
95 */
96 Double_t Integral = 0.0;
97 for(Int_t x = 1; x <= nBinsX; x++)
98 {
99 for(Int_t y = 1; y <= nBinsY; y++)
100 {
101 for(Int_t z = 1; z <= nBinsZ; z++)
102 {
103 Integral += m_LRAHist->GetBinContent(x, y, z);
104
105 m_Integral.emplace_back(std::forward_as_tuple(x, y, z, Integral));
106 };
107 };
108 };
109
110 // Cache the axes.
111 m_xAxis = m_LRAHist->GetXaxis();
112 m_yAxis = m_LRAHist->GetYaxis();
113 m_zAxis = m_LRAHist->GetZaxis();
114
115 //---
116
117 // Happy path...
118 return StatusCode::SUCCESS;
119 };
120
122 {
123 return StatusCode::SUCCESS;
124 };
125
126 //---
127
128 CLHEP::HepLorentzVector *LRAVertexPositioner::generate(const EventContext &ctx) const
129 {
130 // Set the RNG seed and get the engine for this event.
131 m_RNGEngine->setSeed(name(), ctx);
132 CLHEP::HepRandomEngine *LRAEngine(m_RNGEngine->getEngine(ctx));
133
134 //---
135
136 // Compare the integral of two IntegralTuples.
137 auto Comparison = [](const auto &LHS, const auto &RHS)
138 {
139 // No language place-holders... Yet...
140 auto [lx, ly, lz, i] = LHS;
141 auto [rx, ry, rz, t] = RHS;
142
143 return(i < t);
144 };
145
146 // Get the point a V'th between the bin edges.
147 auto GetCoordinate = [](const auto Axis, const auto Bin, const auto V)
148 {
149 return(Axis->GetBinLowEdge(Bin) + (V * Axis->GetBinWidth(Bin)));
150 };
151
152 // Find the x/y/z bin numbers of the interesting bin.
153 auto [xBin, yBin, zBin, Integral] = *(std::lower_bound(m_Integral.cbegin(),
154 m_Integral.cend(),
155 std::make_tuple(0, 0, 0, CLHEP::RandFlat::shoot(LRAEngine)),
156 Comparison));
157
158 // Return a point in the bin, caller deletes.
159 CLHEP::HepLorentzVector *vertexPosition = new CLHEP::HepLorentzVector(GetCoordinate(m_xAxis, xBin, CLHEP::RandFlat::shoot(LRAEngine)),
160 GetCoordinate(m_yAxis, yBin, CLHEP::RandFlat::shoot(LRAEngine)),
161 GetCoordinate(m_zAxis, zBin, CLHEP::RandFlat::shoot(LRAEngine)),
162 0.0);
163
164 // ToDo: This uses only the TH3 PDF to position the vertex, this should be expanded to include:
165 // x/y/z translations.
166 // Slant angles.
167 // Euler angle/quaternion/something for arbiraty rotations (for non-factorisable PDFs)?
168
169 //---
170
171 return(vertexPosition);
172 };
173};
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
static Double_t rz
std::string PathResolverFindDataFile(const std::string &logical_file_name)
#define y
#define x
#define z
virtual CLHEP::HepLorentzVector * generate(const EventContext &ctx) const override final
Generate a vertex position from the LRA input.
Gaudi::Property< std::string > m_RNGStream
Stream name for the RNG service.
virtual StatusCode initialize() override final
AthAlgTool initialization.
ServiceHandle< IAthRNGSvc > m_RNGService
Handle to the Athena RNG service.
const TAxis * m_zAxis
Non-owning TAxis * to the histograms z-Axis.
Gaudi::Property< std::string > m_FileName
LRA input file name.
const TH3F * m_LRAHist
Non-owning TH3F * to the LRA histogram.
virtual StatusCode finalize() override final
AthAlgTool finalization.
Gaudi::Property< std::string > m_HistName
LRA input histogram name.
const TAxis * m_yAxis
Non-owning TAxis * to the histograms y-Axis.
std::vector< IntegralTuple > m_Integral
Vector to hold the running integral over bins.
std::unique_ptr< TFile > m_LRAFile
Owning TFile * to the LRA file.
LRAVertexPositioner(const std::string &t, const std::string &n, const IInterface *p)
Constructor.
const TAxis * m_xAxis
Non-owning TAxis * to the histograms x-Axis.