CMS 3D CMS Logo

AXOL1TLCondition.cc
Go to the documentation of this file.
1 
11 // this class header
13 
14 // system include files
15 #include <iostream>
16 #include <iomanip>
17 
18 #include <string>
19 #include <vector>
20 #include <algorithm>
21 #include "ap_fixed.h"
22 #include "hls4ml/emulator.h"
23 
24 // user include files
25 // base classes
28 
37 
39 
41 
44 
45 // constructors
46 // default
48  // empty
49 }
50 
51 // from base template condition (from event setup usually)
54  m_gtAXOL1TLTemplate(static_cast<const AXOL1TLTemplate*>(axol1tlTemplate)),
55  m_gtGTB(ptrGTB) {}
56 
57 // copy constructor
59  m_gtAXOL1TLTemplate = cp.gtAXOL1TLTemplate();
60  m_gtGTB = cp.gtGTB();
61 
62  m_condMaxNumberObjects = cp.condMaxNumberObjects();
63  m_condLastResult = cp.condLastResult();
64  m_combinationsInCond = cp.getCombinationsInCond();
65 
66  m_verbosity = cp.m_verbosity;
67 }
68 
70 
71 // destructor
73  // empty
74 }
75 
76 // equal operator
78  copy(cp);
79  return *this;
80 }
81 
82 // methods
83 void l1t::AXOL1TLCondition::setGtAXOL1TLTemplate(const AXOL1TLTemplate* caloTempl) { m_gtAXOL1TLTemplate = caloTempl; }
84 
86 void l1t::AXOL1TLCondition::setuGtB(const GlobalBoard* ptrGTB) { m_gtGTB = ptrGTB; }
87 
89 void l1t::AXOL1TLCondition::setScore(const float scoreval) const { m_savedscore = scoreval; }
90 
91 const bool l1t::AXOL1TLCondition::evaluateCondition(const int bxEval) const {
92  bool condResult = false;
93  int useBx = bxEval + m_gtAXOL1TLTemplate->condRelativeBx();
94 
95  //HLS4ML stuff
96  std::string AXOL1TLmodelversion = "GTADModel_" + m_gtAXOL1TLTemplate->modelVersion(); //loading from menu/template
97 
98  //otherwise load model (if possible) and run inference
99  hls4mlEmulator::ModelLoader loader(AXOL1TLmodelversion);
100  std::shared_ptr<hls4mlEmulator::Model> model;
101 
102  try {
103  model = loader.load_model();
104  } catch (std::runtime_error& e) {
105  // for stopping with exception if model version cannot be loaded
106  throw cms::Exception("ModelError")
107  << " ERROR: failed to load AXOL1TL model version \"" << AXOL1TLmodelversion
108  << "\" that was specified in menu. Model version not found in cms-hls4ml externals.";
109  }
110 
111  // //pointers to objects
112  const BXVector<const l1t::Muon*>* candMuVec = m_gtGTB->getCandL1Mu();
113  const BXVector<const l1t::L1Candidate*>* candJetVec = m_gtGTB->getCandL1Jet();
114  const BXVector<const l1t::L1Candidate*>* candEGVec = m_gtGTB->getCandL1EG();
115  const BXVector<const l1t::EtSum*>* candEtSumVec = m_gtGTB->getCandL1EtSum();
116 
117  const int NMuons = 4;
118  const int NJets = 10;
119  const int NEgammas = 4;
120  //const int NEtSums = 1;
121 
122  //number of indices in vector is #objects * 3 for et, eta, phi
123  const int MuVecSize = 12; //NMuons * 3; //so 12
124  const int JVecSize = 30; //NJets * 3; //so 30
125  const int EGVecSize = 12; //NEgammas * 3; //so 12
126  const int EtSumVecSize = 3; //NEtSums * 3; //so 3
127 
128  //total # inputs in vector is (4+10+4+1)*3 = 57
129  const int NInputs = 57;
130 
131  //types of inputs and outputs
132  typedef ap_fixed<18, 13> inputtype;
133  typedef std::array<ap_fixed<10, 7, AP_RND_CONV, AP_SAT>, 8> resulttype; //v3
134  typedef ap_ufixed<18, 14> losstype;
135  typedef std::pair<resulttype, losstype> pairtype;
136  // typedef std::array<ap_fixed<10, 7>, 13> resulttype; //deprecated v1 type:
137 
138  //define zero
139  inputtype fillzero = 0.0;
140 
141  //AD vector declaration, will fill later
142  inputtype ADModelInput[NInputs] = {};
143 
144  //initializing vector by type for my sanity
145  inputtype MuInput[MuVecSize];
146  inputtype JetInput[JVecSize];
147  inputtype EgammaInput[EGVecSize];
148  inputtype EtSumInput[EtSumVecSize];
149 
150  //declare result vectors +score
151  resulttype result;
152  losstype loss;
153  pairtype ADModelResult; //model outputs a pair of the (result vector, loss)
154  float score = -1.0; //not sure what the best default is hm??
155 
156  //check number of input objects we actually have (muons, jets etc)
157  int NCandMu = candMuVec->size(useBx);
158  int NCandJet = candJetVec->size(useBx);
159  int NCandEG = candEGVec->size(useBx);
160  int NCandEtSum = candEtSumVec->size(useBx);
161 
162  //initialize arrays to zero (std::fill(first, last, value);)
163  std::fill(EtSumInput, EtSumInput + EtSumVecSize, fillzero);
164  std::fill(MuInput, MuInput + MuVecSize, fillzero);
165  std::fill(JetInput, JetInput + JVecSize, fillzero);
166  std::fill(EgammaInput, EgammaInput + EGVecSize, fillzero);
167  std::fill(ADModelInput, ADModelInput + NInputs, fillzero);
168 
169  //then fill the object vectors
170  //NOTE assume candidates are already sorted by pt
171  //loop over EtSums first, easy because there is max 1 of them
172  if (NCandEtSum > 0) { //check if not empty
173  for (int iEtSum = 0; iEtSum < NCandEtSum; iEtSum++) {
174  if ((candEtSumVec->at(useBx, iEtSum))->getType() == l1t::EtSum::EtSumType::kMissingEt) {
175  EtSumInput[0] =
176  ((candEtSumVec->at(useBx, iEtSum))->hwPt()) / 2; //have to do hwPt/2 in order to match original et inputs
177  // EtSumInput[1] = (candEtSumVec->at(useBx, iEtSum))->hwEta(); //this one is zero, so leave it zero
178  EtSumInput[2] = (candEtSumVec->at(useBx, iEtSum))->hwPhi();
179  }
180  }
181  }
182 
183  //next egammas
184  if (NCandEG > 0) { //check if not empty
185  for (int iEG = 0; iEG < NCandEG; iEG++) {
186  if (iEG < NEgammas) { //stop if fill the Nobjects we need
187  EgammaInput[0 + (3 * iEG)] = ((candEGVec->at(useBx, iEG))->hwPt()) /
188  2; //index 0,3,6,9 //have to do hwPt/2 in order to match original et inputs
189  EgammaInput[1 + (3 * iEG)] = (candEGVec->at(useBx, iEG))->hwEta(); //index 1,4,7,10
190  EgammaInput[2 + (3 * iEG)] = (candEGVec->at(useBx, iEG))->hwPhi(); //index 2,5,8,11
191  }
192  }
193  }
194 
195  //next muons
196  if (NCandMu > 0) { //check if not empty
197  for (int iMu = 0; iMu < NCandMu; iMu++) {
198  if (iMu < NMuons) { //stop if fill the Nobjects we need
199  MuInput[0 + (3 * iMu)] = ((candMuVec->at(useBx, iMu))->hwPt()) /
200  2; //index 0,3,6,9 //have to do hwPt/2 in order to match original et inputs
201  MuInput[1 + (3 * iMu)] = (candMuVec->at(useBx, iMu))->hwEta(); //index 1,4,7,10
202  MuInput[2 + (3 * iMu)] = (candMuVec->at(useBx, iMu))->hwPhi(); //index 2,5,8,11
203  }
204  }
205  }
206 
207  //next jets
208  if (NCandJet > 0) { //check if not empty
209  for (int iJet = 0; iJet < NCandJet; iJet++) {
210  if (iJet < NJets) { //stop if fill the Nobjects we need
211  JetInput[0 + (3 * iJet)] = ((candJetVec->at(useBx, iJet))->hwPt()) /
212  2; //index 0,3,6,9...27 //have to do hwPt/2 in order to match original et inputs
213  JetInput[1 + (3 * iJet)] = (candJetVec->at(useBx, iJet))->hwEta(); //index 1,4,7,10...28
214  JetInput[2 + (3 * iJet)] = (candJetVec->at(useBx, iJet))->hwPhi(); //index 2,5,8,11...29
215  }
216  }
217  }
218 
219  //now put it all together-> EtSum+EGamma+Muon+Jet into ADModelInput
220  int index = 0;
221  for (int idET = 0; idET < EtSumVecSize; idET++) {
222  ADModelInput[index++] = EtSumInput[idET];
223  }
224  for (int idEG = 0; idEG < EGVecSize; idEG++) {
225  ADModelInput[index++] = EgammaInput[idEG];
226  }
227  for (int idMu = 0; idMu < MuVecSize; idMu++) {
228  ADModelInput[index++] = MuInput[idMu];
229  }
230  for (int idJ = 0; idJ < JVecSize; idJ++) {
231  ADModelInput[index++] = JetInput[idJ];
232  }
233 
234  //now run the inference
235  model->prepare_input(ADModelInput); //scaling internal here
236  model->predict();
237  model->read_result(&ADModelResult); // this should be the square sum model result
238 
239  result = ADModelResult.first;
240  loss = ADModelResult.second;
241  score = ((loss).to_float()) * 16.0; //scaling to match threshold
242  //save score to class variable in case score saving needed
243  setScore(score);
244 
245  //number of objects/thrsholds to check
246  int iCondition = 0; // number of conditions: there is only one
247  int nObjInCond = m_gtAXOL1TLTemplate->nrObjects();
248 
249  if (iCondition >= nObjInCond || iCondition < 0) {
250  return false;
251  }
252 
253  const AXOL1TLTemplate::ObjectParameter objPar = (*(m_gtAXOL1TLTemplate->objectParameter()))[iCondition];
254 
255  // condGEqVal indicates the operator used for the condition (>=, =): true for >=
256  bool condGEqVal = m_gtAXOL1TLTemplate->condGEq();
257  bool passCondition = false;
258 
259  passCondition = checkCut(objPar.minAXOL1TLThreshold, score, condGEqVal);
260 
261  condResult |= passCondition; //condresult true if passCondition true else it is false
262 
263  //return result
264  return condResult;
265 }
266 
267 void l1t::AXOL1TLCondition::print(std::ostream& myCout) const {
268  myCout << "Dummy Print for AXOL1TLCondition" << std::endl;
269  m_gtAXOL1TLTemplate->print(myCout);
270 
272 }
void print(std::ostream &myCout) const override
print condition
unsigned size(int bx) const
void setScore(const float scoreval) const
get/set score value
void setGtAXOL1TLTemplate(const AXOL1TLTemplate *)
const T & at(int bx, unsigned i) const
virtual void print(std::ostream &myCout) const
print condition
void copy(const AXOL1TLCondition &cp)
copy function for copy constructor and operator=
AXOL1TLCondition & operator=(const AXOL1TLCondition &)
void setuGtB(const GlobalBoard *)
set the pointer to uGT GlobalBoard
const bool evaluateCondition(const int bxEval) const override
the core function to check if the condition matches