ATLAS Offline Software
Loading...
Searching...
No Matches
Artemis_2A.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4/*********************************
5 * Artemis_2A.cxx
6 * Created by Paula Martinez Suarez, Ralf Gugel, Sagar Addepalli on 09/12/2025.
7 *
8 * @brief A Rapid Tagger Electing Missed Interesting Signatures:
9 * algorithm uses a variational auto-encoder based anomaly detection network
10 * Uses 6 jets, 4 muons, 4 taus, and MET to calculate the anomaly score
11 * based on the KL-divergence in a lower dimension latent space
12 *
13 * @param MinEt1 : zero any jJet TOB if its ET is below this value
14 * @param MinEt2 : zero any eTau TOB if its ET is below this value
15 * @param MinEt3 : zero any Muon TOB if its ET is below this value
16 * @param MinEt4 : zero jXE TOB if its ET is below this value
17 * @param MaxEt1 : veto event if any jJet 1 ET exceeds this value
18 * @param MaxEt2 : veto event if any jJet 2 ET exceeds this value
19 * @param MaxEt3 : veto event if any jJet 3 ET exceeds this value
20 * @param MaxEt4 : veto event if any jJet 4 ET exceeds this value
21 * @param MaxEt5 : veto event if any eTau 1 ET exceeds this value
22 * @param MaxEt6 : veto event if any muon 1 ET exceeds this value
23 * @param MaxEt7 : veto event if jXE 1 exceeds this value
24 * @param AnomalyScoreThresh
25**********************************/
26
27#include <cmath>
28
33#include <ArtemisNetwork.h>
34
35REGISTER_ALG_TCS(ARTEMIS_2A)
36
37
39{
40 defineParameter("InputWidth1", 6);
41 defineParameter("InputWidth2", 6);
42 defineParameter("InputWidth3", 6);
43 defineParameter("InputWidth4", 1);
44 defineParameter("MaxTob1", 6);
45 defineParameter("MaxTob2", 4);
46 defineParameter("MaxTob3", 4);
47 defineParameter("MaxTob4", 1);
48 defineParameter("NumResultBits", 2);
49
50 // Version parameter, used for L1TopoFW book-keeping, no practical application for now
51 defineParameter("Version", 1);
52 // minEt cuts, one per input list (TOBs failing these are set to ET = eta = phi = 0)
53 defineParameter("MinET1",0);
54 defineParameter("MinET2",0);
55 defineParameter("MinET3",0);
56 defineParameter("MinET4",0);
57 // maxEt cuts, veto event if a TOB exceeds its corresponding threshold to avoid excessive triggering at (trivial) high-ET
58 defineParameter("MaxET1",0);
59 defineParameter("MaxET2",0);
60 defineParameter("MaxET3",0);
61 defineParameter("MaxET4",0);
62 defineParameter("MaxET5",0);
63 defineParameter("MaxET6",0);
64 defineParameter("MaxET7",0);
65 // The value used is sum of squares of the NN result vector elements, bit-shifted by 8 to get all decimal bits
66 defineParameter("AnomalyScoreThresh", 1000000, 0);
67 defineParameter("AnomalyScoreThresh", 1000000, 1);
68
70}
71
73
74
77 p_NumberLeading1 = parameter("InputWidth1").value();
78 p_NumberLeading2 = parameter("InputWidth2").value();
79 p_NumberLeading3 = parameter("InputWidth3").value();
80 p_NumberLeading4 = parameter("InputWidth4").value();
81
82 if(parameter("MaxTob1").value() > 0) p_NumberLeading1 = parameter("MaxTob1").value();
83 if(parameter("MaxTob2").value() > 0) p_NumberLeading2 = parameter("MaxTob2").value();
84 if(parameter("MaxTob3").value() > 0) p_NumberLeading3 = parameter("MaxTob3").value();
85 if(parameter("MaxTob4").value() > 0) p_NumberLeading4 = parameter("MaxTob4").value();
86
87 p_minEt1 = parameter("MinET1").value();
88 p_minEt2 = parameter("MinET2").value();
89 p_minEt3 = parameter("MinET3").value();
90 p_minEt4 = parameter("MinET4").value();
91
92 p_maxEt1 = parameter("MaxET1").value();
93 p_maxEt2 = parameter("MaxET2").value();
94 p_maxEt3 = parameter("MaxET3").value();
95 p_maxEt4 = parameter("MaxET4").value();
96 p_maxEt5 = parameter("MaxET5").value();
97 p_maxEt6 = parameter("MaxET6").value();
98 p_maxEt7 = parameter("MaxET7").value();
99
100 for(unsigned int i=0; i<numberOutputBits(); ++i) {
101 p_AnomalyScoreThresh[i] = parameter("AnomalyScoreThresh", i).value();
102 }
103
104 TRG_MSG_INFO("number output : " << numberOutputBits());
105
106 // book histograms
107 for(unsigned int i=0; i<numberOutputBits(); ++i) {
108 std::string hname_accept = "hAnomalyScore_accept_bit"+std::to_string((int)i);
109 std::string hname_reject = "hAnomalyScore_reject_bit"+std::to_string((int)i);
110 // score
111 bookHist(m_histAccept, hname_accept, "AD score", 150, 0, 100000);
112 bookHist(m_histReject, hname_reject, "AD score", 150, 0, 100000);
113}
114
115 return StatusCode::SUCCESS;
116}
117
118
120TCS::ARTEMIS_2A::processBitCorrect( const std::vector<TCS::TOBArray const *> & input,
121 const std::vector<TCS::TOBArray *> & output,
122 Decision & decision )
123{
124
125
126 if( input.size() == 4) {
127
128 TCS::TOBArray const* jets = input[0];
129 TCS::TOBArray const* taus = input[1];
130 TCS::TOBArray const* mus = input[2];
131 TCS::TOBArray const* met = input[3];
132 TRG_MSG_DEBUG("Number of jets are " << (*jets).size());
133 TRG_MSG_DEBUG("Number of taus are " << (*taus).size());
134 TRG_MSG_DEBUG("Number of mus are " << (*mus).size());
135 TRG_MSG_DEBUG("Number of met are " << (*met).size());
136
137 //check for ambiguous sorting and set corresponding flag if an ambiguity is found
138 bool hasAmbiguousInputs = TSU::isAmbiguousTruncation(jets, p_NumberLeading1, p_minEt1)
146
147 std::vector<u_int> jet_pt(6,0), tau_pt(4,0), mu_pt(4,0), met_pt(1,0);
148 std::vector<int> jet_eta(6,0), tau_eta(4,0), mu_eta(4,0); //no met_eta
149 std::vector<int> jet_phi(6,0), tau_phi(4,0), mu_phi(4,0), met_phi(1,0);
150
151 bool highEtVeto = false; // high-Et veto, to be applied later
152
153 for (u_int i = 0; i<(*jets).size() && i<6; ++i) {
154 if ( parType_t( (*jets)[i].Et() ) <= p_minEt1 ) { continue; } //ET cut, leave NN inputs at default values (0)
155 jet_pt[i] = (*jets)[i].Et();
156 jet_eta[i] = (*jets)[i].eta();
157 jet_phi[i] = (*jets)[i].phi();
158 }
159 if ( ( p_maxEt1 > 0 && parType_t( jet_pt[0] ) > p_maxEt1)
160 || ( p_maxEt2 > 0 && parType_t( jet_pt[1] ) > p_maxEt2)
161 || ( p_maxEt3 > 0 && parType_t( jet_pt[2] ) > p_maxEt3)
162 || ( p_maxEt4 > 0 && parType_t( jet_pt[3] ) > p_maxEt4) ) { highEtVeto = true; }
163
164 for (u_int i = 0; i < (*taus).size() && i<4; ++i) {
165 if ( parType_t( (*taus)[i].Et() ) <= p_minEt2 ) { continue; } //ET cut, leave NN inputs at default values (0)
166 tau_pt[i] = (*taus)[i].Et();
167 tau_eta[i] = (*taus)[i].eta();
168 tau_phi[i] = (*taus)[i].phi();
169 }
170 if ( p_maxEt5 > 0 && parType_t( tau_pt[0] ) > p_maxEt5) { highEtVeto = true; }
171
172 for (u_int i = 0; i < (*mus).size() && i<4; ++i) {
173 if ( parType_t( (*mus)[i].Et() ) <= p_minEt3 ) { continue; } //ET cut, leave NN inputs at default values (0)
174 mu_pt[i] = (*mus)[i].Et();
175 mu_eta[i] = (*mus)[i].eta();
176 mu_phi[i] = (*mus)[i].phi();
177 }
178 if ( p_maxEt6 > 0 && parType_t( mu_pt[0] ) > p_maxEt6) { highEtVeto = true; }
179
180 for (u_int i = 0; i < (*met).size() && i<1; ++i) {
181 if ( parType_t( (*met)[i].Et() ) <= p_minEt4 ) { continue; } //ET cut, leave NN inputs at default values (0)
182 met_pt[i] = (*met)[i].Et();
183 met_phi[i] = (*met)[i].phi();
184 }
185 if ( p_maxEt7 > 0 && parType_t( met_pt[0] ) > p_maxEt7) { highEtVeto = true; }
186
187
188 ARTEMIS2A::ArtemisNetwork AD_Network( jet_pt[0], jet_eta[0], jet_phi[0],
189 jet_pt[1], jet_eta[1], jet_phi[1],
190 jet_pt[2], jet_eta[2], jet_phi[2],
191 jet_pt[3], jet_eta[3], jet_phi[3],
192 jet_pt[4], jet_eta[4], jet_phi[4],
193 jet_pt[5], jet_eta[5], jet_phi[5],
194 tau_pt[0], tau_eta[0], tau_phi[0],
195 tau_pt[1], tau_eta[1], tau_phi[1],
196 tau_pt[2], tau_eta[2], tau_phi[2],
197 tau_pt[3], tau_eta[3], tau_phi[3],
198 mu_pt [0], mu_eta [0], mu_phi [0],
199 mu_pt [1], mu_eta [1], mu_phi [1],
200 mu_pt [2], mu_eta [2], mu_phi [2],
201 mu_pt [3], mu_eta [3], mu_phi [3],
202 met_pt[0], met_phi[0] );
203
204 std::vector<int64_t> anomScoreInt64Vec = AD_Network.getAnomalyScoreInt64Vec();
205
206 // Calculate event score = mu^2 - log(std^2)
207 int64_t anomScoreInt64 = 0;
208 anomScoreInt64 = ((anomScoreInt64Vec.at(0) * anomScoreInt64Vec.at(0)) >> 10) // Drop extra precision
209 +((anomScoreInt64Vec.at(1) * anomScoreInt64Vec.at(1)) >> 10)
210 +((anomScoreInt64Vec.at(2) * anomScoreInt64Vec.at(2)) >> 10)
211 +((anomScoreInt64Vec.at(3) * anomScoreInt64Vec.at(3)) >> 10)
212 - anomScoreInt64Vec.at(4) - anomScoreInt64Vec.at(5) - anomScoreInt64Vec.at(6) - anomScoreInt64Vec.at(7);
213
214 for(u_int i=0; i<numberOutputBits(); ++i) {
215 bool accept = false;
216 // Retrieve threshold
217 int32_t threshold = int32_t ( p_AnomalyScoreThresh[i] );
218 // Get decision bit
219 if ( anomScoreInt64 > threshold && !highEtVeto ) {
220 accept = true;
221 decision.setBit(i, true);
222 for ( u_int j = 0; j<6 && j<(*jets).size(); ++j ) output[i]->push_back((*jets)[j]);
223 for ( u_int j = 0; j<4 && j<(*taus).size(); ++j ) output[i]->push_back((*taus)[j]);
224 for ( u_int j = 0; j<4 && j<(*mus).size() ; ++j ) output[i]->push_back((*mus) [j]);
225 output[i]->push_back((*met)[0]);
226 }
227 output[i]->setAmbiguityFlag(hasAmbiguousInputs);
228
229 if(fillHistos() and accept) {
230 fillHist1D(m_histAccept[i],anomScoreInt64);
231 } else if(fillHistos() && !accept) {
232 fillHist1D(m_histReject[i],anomScoreInt64);
233 }
234
235 TRG_MSG_DEBUG("Decision for bit" << i << ": " << (accept?"pass":"fail") << " anomaly score = " << anomScoreInt64 << std::endl);
236 }
237 } else {
238 TCS_EXCEPTION("ARTEMIS_2A alg must have 4 inputs, but got " << input.size());
239 }
240
242}
243
245TCS::ARTEMIS_2A::process( const std::vector<TCS::TOBArray const *> & input,
246 const std::vector<TCS::TOBArray *> & output,
247 Decision & decision )
248{
249 // as there is a bitwise implementation available use it
250 return this->processBitCorrect(input, output, decision);
251}
#define REGISTER_ALG_TCS(CLASS)
Definition AlgFactory.h:62
static Double_t taus
parType_t p_maxEt3
Definition Artemis_2A.h:44
parType_t p_NumberLeading3
Definition Artemis_2A.h:36
parType_t p_maxEt4
Definition Artemis_2A.h:45
parType_t p_NumberLeading2
Definition Artemis_2A.h:35
parType_t p_maxEt7
Definition Artemis_2A.h:48
parType_t p_minEt2
Definition Artemis_2A.h:39
parType_t p_maxEt5
Definition Artemis_2A.h:46
virtual StatusCode process(const std::vector< TCS::TOBArray const * > &input, const std::vector< TCS::TOBArray * > &output, Decision &decison)
virtual ~ARTEMIS_2A()
virtual StatusCode initialize()
parType_t p_NumberLeading4
Definition Artemis_2A.h:37
parType_t p_minEt4
Definition Artemis_2A.h:41
parType_t p_maxEt6
Definition Artemis_2A.h:47
parType_t p_NumberLeading1
Definition Artemis_2A.h:34
parType_t p_AnomalyScoreThresh[2]
Definition Artemis_2A.h:49
virtual StatusCode processBitCorrect(const std::vector< TCS::TOBArray const * > &input, const std::vector< TCS::TOBArray * > &output, Decision &decison)
ARTEMIS_2A(const std::string &name)
parType_t p_maxEt2
Definition Artemis_2A.h:43
parType_t p_minEt1
Definition Artemis_2A.h:38
parType_t p_minEt3
Definition Artemis_2A.h:40
parType_t p_maxEt1
Definition Artemis_2A.h:42
const Parameter & parameter(const std::string &parameterName) const
const std::string & name() const
void bookHist(std::vector< std::string > &regName, const std::string &name, const std::string &title, const int binx, const int xmin, const int xmax)
void fillHist1D(const std::string &histName, double x)
void defineParameter(const std::string &name, TCS::parType_t value)
void setNumberOutputBits(unsigned int numberOutputBits)
Definition DecisionAlg.h:40
DecisionAlg(const std::string &name)
Definition DecisionAlg.h:25
bool fillHistos() const
whether the monitoring histograms should be filled
std::vector< std::string > m_histAccept
Definition DecisionAlg.h:73
std::vector< std::string > m_histReject
Definition DecisionAlg.h:74
unsigned int numberOutputBits() const
Definition DecisionAlg.h:39
void setBit(unsigned int index, bool value)
Definition Decision.cxx:12
uint32_t parType_t
Definition Parameter.h:22
bool isAmbiguousAnywhere(TCS::TOBArray const *tobs, size_t pos, unsigned minEt=0)
bool isAmbiguousTruncation(TCS::TOBArray const *tobs, size_t pos, unsigned minEt=0)
STL namespace.