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