19 #include <Math/Vector2D.h>
20 #include <Math/Vector2Dfwd.h>
33 ATH_MSG_ERROR(
"Please make sure it exists in the ATLAS calibration area (https://atlas-groupdata.web.cern.ch/atlas-groupdata/), and provide a model file name relative to the root of the calibration area.");
35 return StatusCode::FAILURE;
39 Ort::SessionOptions session_options;
40 Ort::AllocatorWithDefaultOptions allocator;
41 session_options.SetIntraOpNumThreads(1);
42 session_options.SetGraphOptimizationLevel(ORT_ENABLE_BASIC);
44 m_session = std::make_unique<Ort::Session>(
m_svc->env(), model_file_name.c_str(), session_options);
46 ATH_MSG_INFO(
"Created ONNX runtime session with model " << model_file_name);
48 size_t num_input_nodes =
m_session->GetInputCount();
51 for (std::size_t
i = 0;
i < num_input_nodes;
i++) {
52 char* input_name =
m_session->GetInputNameAllocated(
i, allocator).release();
56 Ort::TypeInfo type_info =
m_session->GetInputTypeInfo(
i);
57 auto tensor_info = type_info.GetTensorTypeAndShapeInfo();
58 ONNXTensorElementDataType
type = tensor_info.GetElementType();
69 std::vector<int64_t> output_node_dims;
70 size_t num_output_nodes =
m_session->GetOutputCount();
74 for (std::size_t
i = 0;
i < num_output_nodes;
i++) {
75 char* output_name =
m_session->GetOutputNameAllocated(
i, allocator).release();
76 ATH_MSG_DEBUG(
"Output " <<
i <<
" : " <<
" name= " << output_name);
79 Ort::TypeInfo type_info =
m_session->GetOutputTypeInfo(
i);
80 auto tensor_info = type_info.GetTensorTypeAndShapeInfo();
81 ONNXTensorElementDataType
type = tensor_info.GetElementType();
84 output_node_dims = tensor_info.GetShape();
85 ATH_MSG_DEBUG(
"Output " <<
i <<
" : num_dims= " << output_node_dims.size());
86 for (std::size_t j = 0; j < output_node_dims.size(); j++) {
87 if (output_node_dims[j] < 0) output_node_dims[j] = 1;
88 ATH_MSG_DEBUG(
"Output" <<
i <<
" : dim " << j <<
"= " << output_node_dims[j]);
93 return StatusCode::SUCCESS;
98 ATH_MSG_DEBUG(
"Size of passingLegs = " << passingLegs.size());
100 if (passingLegs.size() == 0) {
101 return StatusCode::SUCCESS;
104 std::vector<std::vector<Combo::LegDecision>> legDecisions;
108 ATH_MSG_DEBUG(
"Have "<<passingLegs.size()<<
" passing legs in AD");
110 std::vector<const xAOD::Jet*> input_jets;
111 std::map<const xAOD::Jet*, std::vector<Combo::LegDecision>> jet_decisions;
112 std::vector<const xAOD::Electron*> input_electrons;
113 std::map<const xAOD::Electron*, std::vector<Combo::LegDecision>> ele_decisions;
114 std::vector<const xAOD::Muon*> input_muons;
115 std::map<const xAOD::Muon*, std::vector<Combo::LegDecision>> muon_decisions;
116 std::vector<const xAOD::Photon*> input_photons;
117 std::map<const xAOD::Photon*, std::vector<Combo::LegDecision>> gam_decisions;
118 std::vector<const xAOD::TauJet*> input_taus;
119 std::map<const xAOD::TauJet*, std::vector<Combo::LegDecision>> taujet_decisions;
120 std::vector<const xAOD::TrigMissingET*> input_mets;
121 std::map<const xAOD::TrigMissingET*, std::vector<Combo::LegDecision>> met_decisions;
123 for(
const auto &leg_decs : legDecisions){
124 for(
const auto &dec_pair : leg_decs){
126 std::vector<TrigCompositeUtils::LinkInfo<xAOD::JetContainer>> jet_feature_links = TrigCompositeUtils::findLinks<xAOD::JetContainer>(decision,
TrigCompositeUtils::featureString(), TrigDefs::lastFeatureOfType);
127 std::vector<TrigCompositeUtils::LinkInfo<xAOD::ElectronContainer>> ele_feature_links = TrigCompositeUtils::findLinks<xAOD::ElectronContainer>(decision,
TrigCompositeUtils::featureString(), TrigDefs::lastFeatureOfType);
128 std::vector<TrigCompositeUtils::LinkInfo<xAOD::MuonContainer>> muon_feature_links = TrigCompositeUtils::findLinks<xAOD::MuonContainer>(decision,
TrigCompositeUtils::featureString(), TrigDefs::lastFeatureOfType);
129 std::vector<TrigCompositeUtils::LinkInfo<xAOD::PhotonContainer>> gam_feature_links = TrigCompositeUtils::findLinks<xAOD::PhotonContainer>(decision,
TrigCompositeUtils::featureString(), TrigDefs::lastFeatureOfType);
130 std::vector<TrigCompositeUtils::LinkInfo<xAOD::TauJetContainer>> taujet_feature_links = TrigCompositeUtils::findLinks<xAOD::TauJetContainer>(decision,
TrigCompositeUtils::featureString(), TrigDefs::lastFeatureOfType);
131 std::vector<TrigCompositeUtils::LinkInfo<xAOD::TrigMissingETContainer>> met_feature_links = TrigCompositeUtils::findLinks<xAOD::TrigMissingETContainer>(decision,
TrigCompositeUtils::featureString(), TrigDefs::lastFeatureOfType);
132 if(jet_feature_links.size()==1){
136 jet_decisions[
jet].push_back(dec_pair);
138 if(ele_feature_links.size()==1){
142 ele_decisions[
electron].push_back(dec_pair);
144 if(muon_feature_links.size()==1){
148 muon_decisions[
muon].push_back(dec_pair);
150 if(gam_feature_links.size()==1){
154 gam_decisions[
photon].push_back(dec_pair);
156 if(taujet_feature_links.size()==1){
160 taujet_decisions[taujet].push_back(dec_pair);
162 if(met_feature_links.size()==1){
166 met_decisions[
met].push_back(dec_pair);
171 for(
const auto &pair : jet_decisions){
172 input_jets.push_back(pair.first);
174 if(input_jets.size()>1){
175 std::sort(input_jets.begin(), input_jets.end(),
176 [](
const auto a,
const auto b){
177 return a->pt() > b->pt();
181 for(
const auto &pair : ele_decisions){
182 input_electrons.push_back(pair.first);
184 if(input_electrons.size()>1){
185 std::sort(input_electrons.begin(), input_electrons.end(),
186 [](
const auto a,
const auto b){
187 return a->pt() > b->pt();
191 for(
const auto &pair : muon_decisions){
192 input_muons.push_back(pair.first);
194 if(input_muons.size()>1){
195 std::sort(input_muons.begin(), input_muons.end(),
196 [](
const auto a,
const auto b){
197 return a->pt() > b->pt();
201 for(
const auto &pair : gam_decisions){
202 input_photons.push_back(pair.first);
204 if(input_photons.size()>1){
205 std::sort(input_photons.begin(), input_photons.end(),
206 [](
const auto a,
const auto b){
207 return a->pt() > b->pt();
211 for(
const auto &pair : taujet_decisions){
212 input_taus.push_back(pair.first);
214 if(input_taus.size()>1){
215 std::sort(input_taus.begin(), input_taus.end(),
216 [](
const auto a,
const auto b){
217 return a->pt() > b->pt();
221 for(
const auto &pair : met_decisions){
222 input_mets.push_back(pair.first);
225 bool trigPass = this->
getAdDecision(input_jets, input_muons, input_electrons, input_photons, input_taus, input_mets);
231 return StatusCode::SUCCESS;
235 const std::vector<const xAOD::Jet*> &input_jets,
236 const std::vector<const xAOD::Muon*> &input_muons,
237 const std::vector<const xAOD::Electron*> &input_electrons,
238 const std::vector<const xAOD::Photon*> &input_photons,
239 const std::vector<const xAOD::TauJet*> &input_taus,
240 const std::vector<const xAOD::TrigMissingET*> &input_mets)
const{
243 <<
"Jets: " << input_jets.size() <<
", "
244 <<
"Muons: " << input_muons.size() <<
", "
245 <<
"Electrons: " << input_electrons.size() <<
", "
246 <<
"Photons: " << input_photons.size() <<
", "
247 <<
"TauJets: " << input_taus.size() <<
", "
248 <<
"METs: " << input_mets.size());
252 std::vector<float> inputTensor;
254 unsigned int jet_count = 0;
255 for(
const auto &
jet : input_jets){
257 <<
"jet[" << jet_count <<
"] = ("
258 <<
jet->pt()/1000 <<
", "
259 <<
jet->eta() <<
", "
260 <<
jet->phi() <<
", "
261 <<
jet->m()/1000 <<
")");
262 if (jet_count<
m_maxjs.value()) {
263 inputTensor.insert(inputTensor.end(), {static_cast<float>(jet->pt()/1000), static_cast<float>(jet->eta()), static_cast<float>(jet->phi())});
267 inputTensor.insert(inputTensor.end(), 3*(
m_maxjs.value()-jet_count), 0.);
269 unsigned int ele_count = 0;
270 for(
const auto &ele : input_electrons){
272 <<
"ele[" << ele_count <<
"] = ("
273 << ele->pt()/1000 <<
", "
274 << ele->eta() <<
", "
275 << ele->phi() <<
", "
276 << ele->m()/1000 <<
")");
277 if (ele_count<
m_maxes.value()) {
278 inputTensor.insert(inputTensor.end(), {static_cast<float>(ele->pt()/1000), static_cast<float>(ele->eta()), static_cast<float>(ele->phi())});
282 inputTensor.insert(inputTensor.end(), 3*(
m_maxes.value()-ele_count), 0.);
284 unsigned int muon_count = 0;
285 for(
const auto &
muon : input_muons){
287 <<
"muon[" << muon_count <<
"] = ("
288 <<
muon->pt()/1000 <<
", "
289 <<
muon->eta() <<
", "
290 <<
muon->phi() <<
", "
291 <<
muon->m()/1000 <<
")");
292 if (muon_count<
m_maxms.value()) {
293 inputTensor.insert(inputTensor.end(), {static_cast<float>(muon->pt()/1000), static_cast<float>(muon->eta()), static_cast<float>(muon->phi())});
297 inputTensor.insert(inputTensor.end(), 3*(
m_maxms.value()-muon_count), 0.);
299 unsigned int gam_count = 0;
300 for(
const auto &gam : input_photons){
302 <<
"gam[" << gam_count <<
"] = ("
303 << gam->pt()/1000 <<
", "
304 << gam->eta() <<
", "
305 << gam->phi() <<
", "
306 << gam->m()/1000 <<
")");
307 if (gam_count<
m_maxgs.value()) {
308 inputTensor.insert(inputTensor.end(), {static_cast<float>(gam->pt()/1000), static_cast<float>(gam->eta()), static_cast<float>(gam->phi())});
312 inputTensor.insert(inputTensor.end(), 3*(
m_maxgs.value()-gam_count), 0.);
314 inputTensor.insert(inputTensor.end(), {0., 0., 0.});
315 for(
const auto &
met : input_mets){
316 ROOT::Math::XYVectorF metv(
met->ex(),
met->ey());
317 float met_phi = metv.phi();
318 float met_et = metv.r();
322 << met_et/1000 <<
", "
324 inputTensor[metind] = met_et/1000;
325 inputTensor[metind+2] = met_phi;
330 for (
unsigned int i=0;
i<inputTensor.size();
i++){
347 auto memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
357 float *output_score_array = output_tensors.front().GetTensorMutableData<
float>();
358 unsigned int output_size = output_tensors.front().GetTensorTypeAndShapeInfo().GetElementCount();
360 float output_score = 0.;
362 ATH_MSG_ERROR(
"Invalid output tensor size: " << output_size);
364 output_score = output_score_array[0];