14#include "GaudiKernel/SystemOfUnits.h"
26 declareInterface<ICaloMuonScoreTool>(
this);
43 "Please make sure it exists in the ATLAS calibration area (https://atlas-groupdata.web.cern.ch/atlas-groupdata/), and provide "
44 "a model file name relative to the root of the calibration area.");
46 return StatusCode::FAILURE;
50 Ort::SessionOptions session_options;
51 Ort::AllocatorWithDefaultOptions allocator;
52 session_options.SetIntraOpNumThreads(1);
53 session_options.SetGraphOptimizationLevel(ORT_ENABLE_BASIC);
55 m_session = std::make_unique<Ort::Session>(
m_svc->env(), model_file_name.c_str(), session_options);
57 ATH_MSG_INFO(
"Created ONNX runtime session with model " << model_file_name);
59 size_t num_input_nodes =
m_session->GetInputCount();
62 for (std::size_t i = 0; i < num_input_nodes; i++) {
64 char* input_name =
m_session->GetInputNameAllocated(i, allocator).release();
66 <<
" name= " << input_name);
69 Ort::TypeInfo type_info =
m_session->GetInputTypeInfo(i);
70 auto tensor_info = type_info.GetTensorTypeAndShapeInfo();
71 ONNXTensorElementDataType
type = tensor_info.GetElementType();
73 <<
" type= " <<
type);
85 std::vector<int64_t> output_node_dims;
86 size_t num_output_nodes =
m_session->GetOutputCount();
90 for (std::size_t i = 0; i < num_output_nodes; i++) {
92 char* output_name =
m_session->GetOutputNameAllocated(i, allocator).release();
94 <<
" name= " << output_name);
97 Ort::TypeInfo type_info =
m_session->GetOutputTypeInfo(i);
98 auto tensor_info = type_info.GetTensorTypeAndShapeInfo();
99 ONNXTensorElementDataType
type = tensor_info.GetElementType();
101 <<
" type= " <<
type);
104 output_node_dims = tensor_info.GetShape();
105 ATH_MSG_INFO(
"Output " << i <<
" : num_dims= " << output_node_dims.size());
106 for (std::size_t j = 0; j < output_node_dims.size(); j++) {
107 if (output_node_dims[j] < 0) output_node_dims[j] = 1;
108 ATH_MSG_INFO(
"Output" << i <<
" : dim " << j <<
"= " << output_node_dims[j]);
112 return StatusCode::SUCCESS;
119 std::vector<float> out(in.size());
123 for (
unsigned int i = 1; i < out.size(); i++) {
125 out[i] = out[i - 1] + d;
135 std::vector<float> &
phi, std::vector<float> &energy, std::vector<int> &samplingId)
const {
138 for (
auto cluster : association->data()) {
139 eta.push_back(cluster->eta());
140 phi.push_back(cluster->phi());
141 samplingId.push_back(cluster->caloDDE()->getSampling());
142 energy.push_back(cluster->energy());
147 ATH_MSG_DEBUG(
"Iterated over " << cell_count <<
" calo cells");
159 double track_eta = trk->
eta();
164 <<
" (eta=" << track_eta <<
")");
168 ATH_MSG_DEBUG(
"Calculating muon score for track particle with eta=" << track_eta);
173 std::unique_ptr<const Rec::ParticleCellAssociation> association =
179 ATH_MSG_VERBOSE(
" particleCellAssociation done " << association.get());
182 std::vector<float>
eta,
phi, energy;
183 std::vector<int> sampling;
211 auto memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
213 Ort::Value input_tensor =
227 float *output_score_array = output_tensors.front().GetTensorMutableData<
float>();
230 float output_score = output_score_array[0];
240 switch (samplingId) {
256 if (v.empty())
return 0.0;
258 int n = v.size() / 2;
259 std::nth_element(v.begin(), v.begin() + n, v.end());
262 if (v.size() % 2 == 1)
return med;
264 auto max_it = std::max_element(v.begin(), v.begin() + n);
266 return (*max_it + med) / 2.0;
270 if (val < low_edge || val >= up_edge)
272 const float bin_width = (up_edge - low_edge) / (n_bins - 1);
273 float interval = val - low_edge;
274 return std::ceil(interval / bin_width);
283 std::vector<int> &sampling)
const {
284 int n_cells =
eta.size();
291 float median_phi =
getMedian(unwrappedPhi);
296 int skipped_cells = 0;
298 for (
int i = 0; i < n_cells; i++) {
300 float shifted_eta =
eta[i] - median_eta;
301 float shifted_phi = unwrappedPhi[i] - median_phi;
306 if (eta_bin == -1 || phi_bin == -1) {
308 ATH_MSG_DEBUG(
"Skipping cell because eta or phi bin lies outside of range. Eta bin: " << eta_bin <<
" phi bin: " << phi_bin);
317 ATH_MSG_DEBUG(
"Skipping cell because sampling ID does not correspond to low-eta layers. Sampling ID: " << sampling[i]);
324 tensor[tensor_idx] += energy[i];
327 ATH_MSG_DEBUG(
"Skipped " << skipped_cells <<
" out of " << n_cells <<
" cells");
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
DataVector< Trk::CaloExtension > CaloExtensionCollection
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
#define ATLAS_THREAD_SAFE
Container class for CaloCell.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
TrackParticle_v1 TrackParticle
Reference the current persistent version: