176 ATH_MSG_WARNING(
"Model not loaded or Egamma pointer is null, returning cluster energy");
179 ATH_MSG_FATAL(
"Model not loaded or Egamma pointer is null, and useClusterIf0 is false, cannot proceed");
186 bool recoverySucceeded =
false;
189 ATH_MSG_WARNING(
"Cell Recovery Tool failed. Proceeding without recovered cells.");
191 recoverySucceeded =
true;
197 std::unique_ptr<xAOD::Egamma> temp_eg;
200 auto array_layer_scales = std::array<double, 4>{1.0, 1.0, 1.0, 1.0};
203 ATH_MSG_DEBUG(
"Applying layer recalibration for GNN on data.");
209 temp_eg = std::make_unique<xAOD::Electron>();
210 temp_eg->makePrivateStore(*eg);
215 temp_eg = std::make_unique<xAOD::Photon>();
216 temp_eg->makePrivateStore(*eg);
230 clusterForTransformer = temp_eg->caloCluster();
237 ATH_MSG_DEBUG(
"Not using layer tool, Using raw layer energies as input to Transformer");
241 ATH_MSG_DEBUG(
"Applying extra layer scales for systematic studies, normally this is for MC events.");
243 ATH_MSG_WARNING(
"You are applying extra layer scales but the input is not MC! Are you sure this is intended?");
246 for (std::size_t i = 0; i < 4; ++i)
247 array_layer_scales[i] *= gei.
scaleEs[i];
259 std::vector<float> cells_E, cells_eta, cells_phi, cells_x, cells_y, cells_z;
260 std::vector<int> cells_layer;
261 std::vector<Identifier> included_cells;
264 double sum_cell_E_L0 = 0.0, sum_cell_E_L1 = 0.0, sum_cell_E_L2 = 0.0, sum_cell_E_L3 = 0.0, sum_cell_E_Gap = 0.0;
269 for (
const CaloCell* cell : *cellLinks) {
272 int sampling = cell->caloDDE()->getSampling();
273 double scale_factor = 1.0;
277 case CaloCell_ID::PreSamplerB:
case CaloCell_ID::PreSamplerE:
278 scale_factor = array_layer_scales[0]; layer_idx = 0;
break;
279 case CaloCell_ID::EMB1:
case CaloCell_ID::EME1:
280 scale_factor = array_layer_scales[1]; layer_idx = 1;
break;
281 case CaloCell_ID::EMB2:
case CaloCell_ID::EME2:
282 scale_factor = array_layer_scales[2]; layer_idx = 2;
285 included_cells.push_back(cell->ID());
288 case CaloCell_ID::EMB3:
case CaloCell_ID::EME3:
289 scale_factor = array_layer_scales[3]; layer_idx = 3;
291 included_cells.push_back(cell->ID());
294 case CaloCell_ID::TileGap3:
295 scale_factor = 1.0; layer_idx = 4;
break;
299 double final_E = cell->e() * scale_factor;
301 cells_E.push_back(final_E);
302 cells_eta.push_back(cell->eta());
303 cells_phi.push_back(cell->phi());
304 cells_x.push_back(cell->x());
305 cells_y.push_back(cell->y());
306 cells_z.push_back(cell->z());
307 cells_layer.push_back(layer_idx);
311 case 0: sum_cell_E_L0 += final_E;
break;
312 case 1: sum_cell_E_L1 += final_E;
break;
313 case 2: sum_cell_E_L2 += final_E;
break;
314 case 3: sum_cell_E_L3 += final_E;
break;
315 case 4: sum_cell_E_Gap += final_E;
break;
323 if (!cell || !cell->caloDDE())
continue;
326 if (std::find(included_cells.begin(), included_cells.end(), cell->ID()) != included_cells.end()) {
327 ATH_MSG_DEBUG(
"Recovered cell " << cell->ID() <<
" already included in cluster. Skipping to avoid double counting.");
331 ATH_MSG_DEBUG(
"Adding recovered cell " << cell->ID() <<
" to cluster inputs.");
334 int sampling = cell->caloDDE()->getSampling();
335 double scale_factor = 1.0;
338 if (sampling == CaloCell_ID::EMB2 || sampling == CaloCell_ID::EME2) {
339 scale_factor = array_layer_scales[2]; layer_idx = 2;
340 }
else if (sampling == CaloCell_ID::EMB3 || sampling == CaloCell_ID::EME3) {
341 scale_factor = array_layer_scales[3]; layer_idx = 3;
344 if (sampling == CaloCell_ID::PreSamplerB || sampling == CaloCell_ID::PreSamplerE) {
345 scale_factor = array_layer_scales[0]; layer_idx = 0;
346 }
else if (sampling == CaloCell_ID::EMB1 || sampling == CaloCell_ID::EME1) {
347 scale_factor = array_layer_scales[1]; layer_idx = 1;
353 double final_E = cell->e() * scale_factor;
355 cells_E.push_back(final_E);
356 cells_eta.push_back(cell->eta());
357 cells_phi.push_back(cell->phi());
358 cells_x.push_back(cell->x());
359 cells_y.push_back(cell->y());
360 cells_z.push_back(cell->z());
361 cells_layer.push_back(layer_idx);
364 case 0: sum_cell_E_L0 += final_E;
break;
365 case 1: sum_cell_E_L1 += final_E;
break;
366 case 2: sum_cell_E_L2 += final_E;
break;
367 case 3: sum_cell_E_L3 += final_E;
break;
368 case 4: sum_cell_E_Gap += final_E;
break;
373 const size_t nCells = cells_E.size();
374 if (nCells == 0)
return 0.0f;
376 double sum_cell_E_total = sum_cell_E_L0 + sum_cell_E_L1 + sum_cell_E_L2 + sum_cell_E_L3;
377 const double cluster_eta = clus.
eta();
378 const double cluster_phi = clus.
phi();
380 std::vector<float> cells_deta, cells_dphi, cells_eFrac;
381 cells_deta.reserve(nCells);
382 cells_dphi.reserve(nCells);
383 cells_eFrac.reserve(nCells);
385 for (
size_t i = 0; i < nCells; ++i) {
386 float deta = cells_eta[i] - cluster_eta;
387 float dphi = cells_phi[i] - cluster_phi;
388 dphi = std::fmod(dphi + 3.0f *
M_PI, 2.0f *
M_PI) -
M_PI;
390 cells_deta.push_back(deta);
391 cells_dphi.push_back(dphi);
393 float eFrac_layer = 0.0f;
394 switch (cells_layer[i]) {
395 case 0: eFrac_layer = (sum_cell_E_L0 != 0) ? (cells_E[i] / sum_cell_E_L0) : 0.0f;
break;
396 case 1: eFrac_layer = (sum_cell_E_L1 != 0) ? (cells_E[i] / sum_cell_E_L1) : 0.0f;
break;
397 case 2: eFrac_layer = (sum_cell_E_L2 != 0) ? (cells_E[i] / sum_cell_E_L2) : 0.0f;
break;
398 case 3: eFrac_layer = (sum_cell_E_L3 != 0) ? (cells_E[i] / sum_cell_E_L3) : 0.0f;
break;
399 case 4: eFrac_layer = (sum_cell_E_Gap != 0) ? (cells_E[i] / sum_cell_E_Gap) : 0.0f;
break;
401 cells_eFrac.push_back(eFrac_layer);
405 double ratio_L1_L2 = (sum_cell_E_L2 != 0) ? (sum_cell_E_L1 / sum_cell_E_L2) : 0.0;
406 double main_layers_sum = sum_cell_E_L1 + sum_cell_E_L2 + sum_cell_E_L3;
407 double ratio_L0_total = (main_layers_sum != 0) ? (sum_cell_E_L0 / main_layers_sum) : 0.0;
408 double ratio_Tile_total = (main_layers_sum != 0) ? (sum_cell_E_Gap / main_layers_sum) : 0.0;
410 std::map<std::string, FlavorTagInference::Inputs> gnn_input;
413 std::vector<float> cluster_feats = {
414 static_cast<float>(sum_cell_E_total),
415 static_cast<float>(sum_cell_E_L0),
416 static_cast<float>(sum_cell_E_L1),
417 static_cast<float>(sum_cell_E_L2),
418 static_cast<float>(sum_cell_E_L3),
419 static_cast<float>(sum_cell_E_Gap),
420 static_cast<float>(cluster_eta),
421 static_cast<float>(cluster_phi),
422 static_cast<float>(ratio_L1_L2),
423 static_cast<float>(ratio_L0_total),
424 static_cast<float>(ratio_Tile_total)
432 float convR = 799.0f;
438 float convEtOverPt = 0.0f;
442 (raw_Es1 * array_layer_scales[1] + raw_Es2 * array_layer_scales[2] + raw_Es3 * array_layer_scales[3]) :
443 (raw_Es1 + raw_Es2 + raw_Es3));
445 convEtOverPt = std::max(0.0f, eacc / (std::cosh(cl_eta) * ptconv));
447 convEtOverPt = std::min(convEtOverPt, 2.0f);
450 float convPtRatio = 1.0f;
454 if ((pt1 + pt2) > 0.0f) {
455 convPtRatio = std::max(pt1, pt2) / (pt1 + pt2);
460 float conversionType =
static_cast<float>(photon->conversionType());
462 cluster_feats.push_back(convR);
463 cluster_feats.push_back(convEtOverPt);
464 cluster_feats.push_back(convPtRatio);
465 cluster_feats.push_back(conversionType);
467 cluster_feats.push_back(0.0f);
468 cluster_feats.push_back(0.0f);
469 cluster_feats.push_back(0.0f);
470 cluster_feats.push_back(0.0f);
478 std::vector<float> cell_feats_flat;
480 for (
size_t i = 0; i < nCells; ++i) {
481 cell_feats_flat.push_back(cells_eFrac[i]);
482 cell_feats_flat.push_back(cells_deta[i]);
483 cell_feats_flat.push_back(cells_dphi[i]);
484 cell_feats_flat.push_back(cells_x[i]);
485 cell_feats_flat.push_back(cells_y[i]);
486 cell_feats_flat.push_back(cells_z[i]);
487 cell_feats_flat.push_back(
static_cast<float>(cells_layer[i]));
492 auto [out_f, out_vc, out_vf] =
m_saltModel->runInference(gnn_input);
494 float el_gnn_score = 0.0f;
495 if (out_vf.empty() || out_vf.begin()->second.empty()) {
498 el_gnn_score = out_vf.begin()->second.front();
502 if (el_gnn_score == 0.0f) {
506 return el_gnn_score *
static_cast<float>(sum_cell_E_total);