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