CMS 3D CMS Logo

PtAssignmentNNRegression.cc
Go to the documentation of this file.
1 /*
2  * PtAssignmentNN.cc
3  *
4  * Created on: May 8, 2020
5  * Author: kbunkow
6  */
7 
11 
13 
15 
16 #include <boost/archive/text_oarchive.hpp>
17 #include <boost/archive/text_iarchive.hpp>
18 #include <boost/algorithm/string/replace.hpp>
19 
20 #include <sstream>
21 #include <fstream>
22 
23 namespace lutNN {
24  static constexpr int input_I = 10;
25  static constexpr int input_F = 4;
26  static constexpr std::size_t networkInputSize = 18;
27 
28  static constexpr int layer1_neurons = 16;
29  static constexpr int layer1_lut_I = 3;
30  static constexpr int layer1_lut_F = 13;
31 
32  static constexpr int layer1_output_I = 4;
33  //4 bits are for the count of the noHit layers which goes to the input of the layer2
34  static constexpr int layer2_input_I = 8;
35 
36  static constexpr int layer2_neurons = 9;
37  static constexpr int layer2_lut_I = 5;
38  static constexpr int layer2_lut_F = 11;
39 
40  static constexpr int layer3_input_I = 5;
41 
42  static constexpr int layer3_0_inputCnt = 8;
43  static constexpr int layer3_0_lut_I = 5;
44  static constexpr int layer3_0_lut_F = 11;
45  static constexpr int output0_I = 8;
46  static constexpr int output0_F = 2;
47 
48  static constexpr int layer3_1_inputCnt = 1;
49  static constexpr int layer3_1_lut_I = 4;
50  static constexpr int layer3_1_lut_F = 11;
51  static constexpr int output1_I = 8;
52  static constexpr int output1_F = 0; //Does not matter in principle - it is not used
53 
55  input_F,
59  layer1_neurons, //layer1_lutSize = 2 ^ input_I
69  output0_I,
70  output0_F,
74  output1_I,
75  output1_F>
77 } // namespace lutNN
78 
80  const OMTFConfiguration* omtfConfig,
81  std::string networkFile)
82  : PtAssignmentBase(omtfConfig), lutNetworkFP(make_unique<lutNN::LutNetworkFP>()) {
83  std::ifstream ifs(networkFile);
84 
85  edm::LogImportant("OMTFReconstruction")
86  << " " << __FUNCTION__ << ":" << __LINE__ << " networkFile " << networkFile << std::endl;
87 
88  lutNetworkFP->load(networkFile);
89 
90  edm::LogImportant("OMTFReconstruction") << " " << __FUNCTION__ << ":" << __LINE__ << std::endl;
91 }
92 
93 struct OmtfHit {
94  union {
95  unsigned long rawData = 0;
96 
97  struct {
98  char layer;
99  char quality;
100  char z;
101  char valid;
102  short eta;
103  short phiDist;
104  };
105  };
106 
107  OmtfHit(unsigned long rawData) : rawData(rawData) {}
108 };
109 
110 bool omtfHitToEventInput(OmtfHit& hit, std::vector<float>& inputs, unsigned int omtfRefLayer, bool print) {
111  float offset = (omtfRefLayer << 7) + 64;
112 
113  if (hit.valid) {
114  if ((hit.layer == 1 || hit.layer == 3 || hit.layer == 5) && hit.quality < 4)
115  return false;
116 
117  int rangeFactor = 2; //rangeFactor scales the hit.phiDist such that the event->inputs is smaller then 63
118  if (hit.layer == 1) {
119  rangeFactor = 8;
120  }
121  /*else if(hit.layer == 8 || hit.layer == 17) {
122  rangeFactor = 4;
123  }*/
124  else if (hit.layer == 3) {
125  rangeFactor = 4;
126  } else if (hit.layer == 9) {
127  rangeFactor = 1;
128  }
129  /*else {
130  rangeFactor = 2;
131  }
132  */
133 
134  rangeFactor *= 2; //TODO !!!!!!!!!!!!!!!!!!!
135 
136  if (std::abs(hit.phiDist) >= (63 * rangeFactor)) {
137  edm::LogImportant("OMTFReconstruction") //<<" muonPt "<<omtfEvent.muonPt<<" omtfPt "<<omtfEvent.omtfPt
138  << " RefLayer " << omtfRefLayer << " layer " << int(hit.layer) << " hit.phiDist " << hit.phiDist << " valid "
139  << ((short)hit.valid) << " !!!!!!!!!!!!!!!!!!!!!!!!" << endl;
140  hit.phiDist = copysign(63 * rangeFactor, hit.phiDist);
141  }
142 
143  inputs.at(hit.layer) = (float)hit.phiDist / (float)rangeFactor + offset;
144 
145  if (inputs.at(hit.layer) >=
146  1022) //the last address i.e. 1023 is reserved for the no-hit value, so interpolation between the 1022 and 1023 has no sense
147  inputs.at(hit.layer) = 1022;
148 
149  if (print || inputs.at(hit.layer) < 0) {
150  edm::LogImportant("OMTFReconstruction") //<<"rawData "<<hex<<setw(16)<<hit.rawData
151  << " layer " << dec << int(hit.layer);
152  edm::LogImportant("OMTFReconstruction")
153  << " phiDist " << hit.phiDist << " inputVal " << inputs.at(hit.layer) << " hit.z " << int(hit.z) << " valid "
154  << ((short)hit.valid) << " quality " << (short)hit.quality << " omtfRefLayer " << omtfRefLayer;
155  if (inputs.at(hit.layer) < 0)
156  edm::LogImportant("OMTFReconstruction") << " event->inputs.at(hit.layer) < 0 !!!!!!!!!!!!!!!!!" << endl;
157  edm::LogImportant("OMTFReconstruction") << endl;
158  }
159 
160  if (inputs[hit.layer] >= 1024) { //TODO should be the size of the LUT of the first layer
161  edm::LogImportant("OMTFReconstruction") << " event->inputs[hit.layer] >= 1024 !!!!!!!!!!!!!!!!!" << endl;
162  }
163  return true;
164  }
165 
166  return false;
167 }
168 
170  std::vector<std::unique_ptr<IOMTFEmulationObserver>>& observers) {
171  LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << std::endl;
172  auto& gpResult = algoMuon->getGpResultConstr();
173  //int pdfMiddle = 1<<(omtfConfig->nPdfAddrBits()-1);
174 
175  LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << std::endl;
176  /*
177  edm::LogVerbatim("l1tOmtfEventPrint")<<"DataROOTDumper2:;observeEventEnd muonPt "<<event.muonPt<<" muonCharge "<<event.muonCharge
178  <<" omtfPt "<<event.omtfPt<<" RefLayer "<<event.omtfRefLayer<<" omtfPtCont "<<event.omtfPtCont
179  <<std::endl;
180 */
181 
182  unsigned int inputCnt = 18; //TDOO!!!!!
183  unsigned int outputCnt = 2;
184  const float noHitVal = 1023.;
185 
186  //edm::LogImportant("OMTFReconstruction") <<"\n----------------------"<<endl;
187  //edm::LogImportant("OMTFReconstruction") <<(*algoMuon)<<std::endl;
188 
189  std::vector<float> inputs(inputCnt, noHitVal);
190 
191  for (unsigned int iLogicLayer = 0; iLogicLayer < gpResult.getStubResults().size(); ++iLogicLayer) {
192  auto& stubResult = gpResult.getStubResults()[iLogicLayer];
193  if (stubResult.getMuonStub()) { //&& stubResult.getValid() //TODO!!!!!!!!!!!!!!!!1
194  int hitPhi = stubResult.getMuonStub()->phiHw;
195  unsigned int refLayerLogicNum = omtfConfig->getRefToLogicNumber()[algoMuon->getRefLayer()];
196  int phiRefHit = gpResult.getStubResults()[refLayerLogicNum].getMuonStub()->phiHw;
197 
198  if (omtfConfig->isBendingLayer(iLogicLayer)) {
199  hitPhi = stubResult.getMuonStub()->phiBHw;
200  phiRefHit = 0; //phi ref hit for the banding layer set to 0, since it should not be included in the phiDist
201  }
202 
203  OmtfHit hit(0);
204 
205  hit.layer = iLogicLayer;
206  hit.quality = stubResult.getMuonStub()->qualityHw;
207  hit.eta = stubResult.getMuonStub()->etaHw; //in which scale?
208  hit.valid = stubResult.getValid();
209 
210  //phiDist = hitPhi - phiRefHit;
211  hit.phiDist = hitPhi - phiRefHit;
212 
213  /*
214  LogTrace("l1tOmtfEventPrint") <<" muonPt "<<event.muonPt<<" omtfPt "<<event.omtfPt<<" RefLayer "<<event.omtfRefLayer
215  <<" layer "<<int(hit.layer)<<" PdfBin "<<stubResult.getPdfBin()<<" hit.phiDist "<<hit.phiDist<<" valid "<<stubResult.getValid()<<" " //<<" phiDist "<<phiDist
216  <<" getDistPhiBitShift "<<omtfCand->getGoldenPatern()->getDistPhiBitShift(iLogicLayer, omtfCand->getRefLayer())
217  <<" meanDistPhiValue "<<omtfCand->getGoldenPatern()->meanDistPhiValue(iLogicLayer, omtfCand->getRefLayer())//<<(phiDist != hit.phiDist? "!!!!!!!<<<<<" : "")
218  <<endl;*/
219 
220  if (hit.phiDist > 504 || hit.phiDist < -512) {
221  edm::LogVerbatim("l1tOmtfEventPrint")
222  //<<" muonPt "<<event.muonPt<<" omtfPt "<<event.omtfPt<<" RefLayer "<<event.omtfRefLayer
223  << " layer " << int(hit.layer) << " hit.phiDist " << hit.phiDist << " valid " << stubResult.getValid()
224  << " !!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
225  }
226 
227  DetId detId(stubResult.getMuonStub()->detId);
228  if (detId.subdetId() == MuonSubdetId::CSC) {
229  CSCDetId cscId(detId);
230  hit.z = cscId.chamber() % 2;
231  }
232 
233  LogTrace("l1tOmtfEventPrint") << "hit: layer " << (int)hit.layer << " quality " << (int)hit.quality << " eta "
234  << (int)hit.eta << " valid " << (int)hit.valid << " phiDist " << (int)hit.phiDist
235  << " z " << (int)hit.z << std::endl;
236 
237  omtfHitToEventInput(hit, inputs, algoMuon->getRefLayer(), false);
238  }
239  }
240 
241  LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << std::endl;
242 
243  std::vector<double> nnResult(outputCnt);
244  lutNetworkFP->run(inputs, noHitVal, nnResult);
245 
246  LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << std::endl;
247 
248  double pt = std::copysign(nnResult.at(0), nnResult.at(1));
249 
250  LogTrace("l1tOmtfEventPrint") << " " << __FUNCTION__ << ":" << __LINE__ << " nnResult.at(0) " << nnResult.at(0)
251  << " nnResult.at(1) " << nnResult.at(1) << " pt " << pt << std::endl;
252 
253  std::vector<float> pts;
254  pts.emplace_back(pt);
255 
256  //algoMuon->setPtNN(omtfConfig->ptGevToHw(nnResult.at(0)));
257  auto calibratedHwPt = lutNetworkFP->getCalibratedHwPt();
258  algoMuon->setPtNNConstr(calibratedHwPt);
259 
260  algoMuon->setChargeNNConstr(nnResult[1] >= 0 ? 1 : -1);
261 
262  //TODO add some if here, such that the property_tree is filled only when needed
263  boost::property_tree::ptree procDataTree;
264  for (unsigned int i = 0; i < inputs.size(); i++) {
265  auto& inputTree = procDataTree.add("input", "");
266  inputTree.add("<xmlattr>.num", i);
267  inputTree.add("<xmlattr>.val", inputs[i]);
268  }
269 
270  std::ostringstream ostr;
271  ostr << std::fixed << std::setprecision(19) << nnResult.at(0);
272  procDataTree.add("output0.<xmlattr>.val", ostr.str());
273 
274  ostr.str("");
275  ostr << std::fixed << std::setprecision(19) << nnResult.at(1);
276  procDataTree.add("output1.<xmlattr>.val", ostr.str());
277 
278  procDataTree.add("calibratedHwPt.<xmlattr>.val", calibratedHwPt);
279 
280  procDataTree.add("hwSign.<xmlattr>.val", algoMuon->getChargeNNConstr() < 0 ? 1 : 0);
281 
282  for (auto& obs : observers)
283  obs->addProcesorData("regressionNN", procDataTree);
284 
285  return pts;
286 
287  //event.print();
288  /*
289  std::vector<float> pts(classifierToRegressions.size(), 0);
290 
291  unsigned int i =0;
292  for(auto& classifierToRegression : classifierToRegressions) {
293  auto orgValue = classifierToRegression->getValue(&event);
294  auto absOrgValue = std::abs(orgValue);
295  pts.at(i) = classifierToRegression->getCalibratedValue(absOrgValue);
296  pts.at(i) = std::copysign(pts.at(i), orgValue);
297 
298  LogTrace("OMTFReconstruction") <<" "<<__FUNCTION__<<":"<<__LINE__<<" orgValue "<<orgValue<<" pts["<<i<<"] "<<pts[i]<<std::endl;
299  //std::cout<<"nn pts["<<i<<"] "<<pts[i]<< std::endl;
300  i++;
301  }
302 
303  return pts;*/
304 }
Log< level::Info, true > LogVerbatim
static constexpr int output1_F
const OMTFConfiguration * omtfConfig
std::vector< float > getPts(AlgoMuons::value_type &algoMuon, std::vector< std::unique_ptr< IOMTFEmulationObserver > > &observers) override
static constexpr int layer3_1_inputCnt
unique_ptr< lutNN::LutNetworkFixedPointRegressionBase > lutNetworkFP
static constexpr int layer1_neurons
static constexpr int output1_I
static constexpr int layer2_lut_I
bool omtfHitToEventInput(OmtfHit &hit, std::vector< float > &inputs, unsigned int omtfRefLayer, bool print)
static constexpr int layer1_lut_F
#define LogTrace(id)
static const double pts[33]
Definition: Constants.h:30
static constexpr int layer3_0_lut_I
static constexpr int layer3_1_lut_I
OmtfHit(unsigned long rawData)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Log< level::Error, true > LogImportant
int chamber() const
Definition: CSCDetId.h:62
const std::vector< int > & getRefToLogicNumber() const
static constexpr int input_I
static constexpr int layer3_0_lut_F
static constexpr int layer1_output_I
PtAssignmentNNRegression(const edm::ParameterSet &edmCfg, const OMTFConfiguration *omtfConfig, std::string networkFile)
LutNetworkFixedPointRegression2Outputs< input_I, input_F, networkInputSize, layer1_lut_I, layer1_lut_F, layer1_neurons, layer1_output_I, layer2_input_I, layer2_lut_I, layer2_lut_F, layer2_neurons, layer3_input_I, layer3_0_inputCnt, layer3_0_lut_I, layer3_0_lut_F, output0_I, output0_F, layer3_1_inputCnt, layer3_1_lut_I, layer3_1_lut_F, output1_I, output1_F > LutNetworkFP
static constexpr int layer2_input_I
Definition: DetId.h:17
static constexpr int layer2_neurons
static constexpr int layer1_lut_I
static constexpr int input_F
static constexpr int layer3_input_I
static constexpr int layer3_0_inputCnt
static constexpr int output0_I
static constexpr int layer2_lut_F
static constexpr int output0_F
static constexpr int layer3_1_lut_F
static constexpr int CSC
Definition: MuonSubdetId.h:12
if(threadIdxLocalY==0 &&threadIdxLocalX==0)
static constexpr std::size_t networkInputSize
unsigned long rawData
bool isBendingLayer(unsigned int iLayer) const override