11 #ifdef XAOD_STANDALONE
23 std::unique_ptr< Ort::Session > CreateORTSession(
const std::string& modelFile){
24 Ort::SessionOptions sessionOptions;
25 sessionOptions.SetIntraOpNumThreads( 1 );
26 sessionOptions.SetGraphOptimizationLevel( ORT_ENABLE_BASIC );
29 std::string serviceName;
30 #ifdef XAOD_STANDALONE
31 using namespace asg::msgUserCode;
32 ANA_MSG_WARNING(
"If running DNN calibration in AnalysisBase: necessary to instantiate the ONNX service AthONNX::ONNXRuntimeSvc with name AthONNXSvc");
33 ATH_MSG_WARNING(
"Either in C++ config (see exemple in JetCalibTools_Example.cxx)");
35 ATH_MSG_WARNING(
" from AnaAlgorithm.DualUseConfig import createService");
36 ATH_MSG_WARNING(
" onnxSvc = createService('AthOnnx::OnnxRuntimeSvc', 'AthONNXSvc', myAlgSequence)");
37 serviceName =
"AthONNXSvc";
39 serviceName =
"AthOnnx::OnnxRuntimeSvc";
44 return std::make_unique<Ort::Session>(
svc->env(),
50 std::tuple<std::vector<int64_t>, std::vector<const char*> > GetInputNodeInfo(
const std::unique_ptr< Ort::Session >& session){
51 std::vector<int64_t> input_node_dims;
52 size_t num_input_nodes = session->GetInputCount();
53 std::vector<const char*> input_node_names(num_input_nodes);
54 Ort::AllocatorWithDefaultOptions allocator;
55 for( std::size_t
i = 0;
i < num_input_nodes;
i++ ) {
57 char* input_name = session->GetInputNameAllocated(
i, allocator).release();
58 input_node_names[
i] = input_name;
59 Ort::TypeInfo type_info = session->GetInputTypeInfo(
i);
60 auto tensor_info = type_info.GetTensorTypeAndShapeInfo();
62 input_node_dims = tensor_info.GetShape();
64 return std::make_tuple(input_node_dims, input_node_names);
68 std::tuple<std::vector<int64_t>, std::vector<const char*> > GetOutputNodeInfo(
const std::unique_ptr< Ort::Session >& session){
69 std::vector<int64_t> output_node_dims;
70 size_t num_output_nodes = session->GetOutputCount();
71 std::vector<const char*> output_node_names(num_output_nodes);
72 Ort::AllocatorWithDefaultOptions allocator;
74 for( std::size_t
i = 0;
i < num_output_nodes;
i++ ) {
75 char* output_name = session->GetOutputNameAllocated(
i, allocator).release();
76 output_node_names[
i] = output_name;
78 Ort::TypeInfo type_info = session->GetOutputTypeInfo(
i);
79 auto tensor_info = type_info.GetTensorTypeAndShapeInfo();
81 output_node_dims = tensor_info.GetShape();
83 return std::make_tuple(output_node_dims, output_node_names);
101 VarAccessorRetriever(
const std::string &
n): m_acc(
n) {}
104 return m_acc(
jet) * eScale;
113 RatioAccessorRetriever(): m_accTau1(
"Tau1_wta"),
114 m_accTau2(
"Tau2_wta"),
115 m_accTau3(
"Tau3_wta"),
131 #define DEF_RETRIEVER0(cname, expr ) struct Var_##cname : public GlobalLargeRDNNCalibration::VarRetriever { float value(const xAOD::Jet& jet, JetEventInfo& , double eScale ) { return expr ; } }
132 #define DEF_RETRIEVER1(cname, expr ) struct Var_##cname : public GlobalLargeRDNNCalibration::VarRetriever { float value(const xAOD::Jet& , JetEventInfo& jetInfo, double eScale ) { return expr ; } }
133 #define DEF_RATIO_RETRIEVER(cname, expr ) struct Ratio_##cname : public RatioAccessorRetriever { float value(const xAOD::Jet& jet, JetEventInfo& , double eScale ) { return expr ; } }
158 {
"eta", [](){
return new Var_eta();} },
159 {
"log_e", [](){
return new Var_log_e();} },
160 {
"log_m", [](){
return new Var_log_m();} },
161 {
"Tau21_wta", [](){
return new Ratio_Tau21_wta();} },
162 {
"Tau32_wta", [](){
return new Ratio_Tau32_wta();} },
163 {
"C2", [](){
return new Ratio_C2();} },
164 {
"D2", [](){
return new Ratio_D2();} },
165 {
"mu", [](){
return new Var_mu();} },
166 {
"NPV", [](){
return new Var_NPV();} },
182 m_config(nullptr), m_calibArea(
"")
188 m_config(nullptr), m_calibArea(
"")
194 m_config(
config), m_calibArea(calibArea)
206 if ( !
m_config ) {
ATH_MSG_FATAL(
"Config file not specified. Aborting.");
return StatusCode::FAILURE; }
224 ATH_MSG_FATAL(
"Misconfiguration of config file : not same number of offset/scale parameters and number of features. Will exit");
225 return StatusCode::FAILURE;
249 m_session = CreateORTSession(fullModelPath);
255 std::tuple<std::vector<int64_t>, std::vector<const char*> > inputInfo = GetInputNodeInfo(
m_session);
274 std::tuple<std::vector<int64_t>, std::vector<const char*> > outputInfo = GetOutputNodeInfo(
m_session);
299 ATH_MSG_FATAL(
"DNN input features not the same size as in config, will exit");
300 return StatusCode::FAILURE;
306 return StatusCode::SUCCESS;
316 jetStartP4 =
jet.jetP4();
319 if(
jet.m()<=0 ||
jet.numConstituents()==1){
321 return StatusCode::SUCCESS;
328 for (
long unsigned int i=0;
i<input_tensor_values.size();
i++)
ATH_MSG_DEBUG(
" " << input_tensor_values[
i]);
332 int nNan = std::count_if(input_tensor_values.begin(), input_tensor_values.end(), [](
float f){return std::isnan(f) || std::isinf(f);});
334 ATH_MSG_WARNING(
"Encountered Nan or inf value in input features, will not apply calibration");
336 return StatusCode::SUCCESS;
340 Ort::MemoryInfo memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeCPU);
341 Ort::Value input_tensor = Ort::Value::CreateTensor<float>( memory_info,
342 input_tensor_values.data(),
343 input_tensor_values.size(),
348 std::vector<float>
vec(input_tensor.GetTensorMutableData<
float>(), input_tensor.GetTensorMutableData<
float>() +
m_input_node_dims[1]);
349 if (
vec!=input_tensor_values) {
350 ATH_MSG_WARNING(
"Input tensor after convertion to Ort tensor is not the same as the input vector, will not apply calibration");
352 return StatusCode::SUCCESS;
357 auto output_tensor = session.Run( Ort::RunOptions{
nullptr},
364 ATH_MSG_WARNING(
"Output tensor does not have the same size as output layer, will not apply calibration");
366 return StatusCode::SUCCESS;
370 float* outputE = output_tensor.at(0).GetTensorMutableData<
float>();
371 float* outputM = output_tensor.at(1).GetTensorMutableData<
float>();
374 float predRespE = outputE[0];
375 float predRespM = outputM[0];
381 if (predRespE==0 || predRespM==0) {
382 ATH_MSG_WARNING(
"Predictions give 0 values, will not apply calibration");
384 return StatusCode::SUCCESS;
388 float calibE = jetStartP4.e() / predRespE;
391 float calibM = jetStartP4.mass();
392 if ( calibM > 40000 ) {
397 float calibpT = std::sqrt( calibE*calibE - calibM*calibM )/std::cosh( jetStartP4.eta() );
400 TLorentzVector TLVjet;
401 TLVjet.SetPtEtaPhiM( calibpT, jetStartP4.eta(), jetStartP4.phi(), calibM );
403 calibP4.SetPxPyPzE( TLVjet.Px(), TLVjet.Py(), TLVjet.Pz(), TLVjet.E() );
407 jet.setJetP4( calibP4 );
409 return StatusCode::SUCCESS;
417 std::vector<float> input_tensor_values(
m_NNInputs.size());
420 for(
size_t i=0;
i<input_tensor_values.size();
i++){
426 return input_tensor_values;