CMS 3D CMS Logo

MinL3AlgoUnivErr.h
Go to the documentation of this file.
1 #ifndef MinL3AlgoUnivErr_H
2 #define MinL3AlgoUnivErr_H
3 
4 //=============================================================================
5 
67 //=============================================================================
68 
69 #include <vector>
70 #include <iostream>
71 #include <map>
72 #include <cmath>
73 
74 //=============================================================================
75 template <class IDdet>
76 class MinL3AlgoUnivErr {
77 public:
78  typedef std::map<IDdet, float> IDmapF;
79  typedef typename IDmapF::value_type IDmapFvalue;
80  typedef typename IDmapF::iterator iter_IDmapF;
81  typedef typename IDmapF::const_iterator citer_IDmapF;
82  typedef std::map<IDdet, int> IDmapI;
83  typedef typename IDmapI::value_type IDmapIvalue;
84  typedef typename IDmapI::iterator iter_IDmapI;
85  typedef typename IDmapI::const_iterator citer_IDmapI;
86 
87  //----------------------------------------------
90 
91  MinL3AlgoUnivErr(float kweight_ = 0.);
92 
93  //----------------------------------------------
95 
96  ~MinL3AlgoUnivErr();
97 
98  //----------------------------------------------
111 
112  IDmapF iterate(const std::vector<std::vector<float> >& eventMatrix,
113  const std::vector<std::vector<IDdet> >& idMatrix,
114  const std::vector<float>& energyVector,
115  const int& nIter,
116  const bool& normalizeFlag = false,
117  const int& nSubsamples = 10);
118  //----------------------------------------------
126 
127  float getError(IDdet id) const;
128 
129  //----------------------------------------------
138 
139  IDmapF getError() const;
140 
141  //----------------------------------------------
149 
150  int numberOfWrongErrors() const;
151 
152  //----------------------------------------------
163 
164  float getErrorQuality(IDdet id) const;
165 
166  IDmapF getErrorQuality() const;
167 
168  //----------------------------------------------
174 
175  float getMeanPartialSolution(IDdet id) const;
176 
177  //----------------------------------------------
182 
183  IDmapF getMeanPartialSolution() const;
184 
185  //----------------------------------------------
187 
188  void addEvent(const std::vector<float>& myCluster, const std::vector<IDdet>& idCluster, const float& energy);
189 
190  //----------------------------------------------
193 
194  std::vector<float> recalibrateEvent(const std::vector<float>& myCluster,
195  const std::vector<IDdet>& idCluster,
196  const IDmapF& newCalibration,
197  const int& isol = -1,
198  const int& iter = -1);
199 
200  //----------------------------------------------
203 
204  IDmapF getSolution(const bool resetsolution = true);
205 
206  //----------------------------------------------
208 
209  void resetSolution();
210 
211  //----------------------------------------------
212 
213 private:
214  float kweight;
215  int countEvents;
216  IDmapF wsum;
217  IDmapF Ewsum;
218  IDmapI idToIndex; // map: cell id -> index of cell info
219  // in sumPartSolu... vectors
220  std::vector<int> sumPartSolu0; // number of partial solutions
221  std::vector<float> sumPartSolu1; // sum of partial solutions
222  std::vector<float> sumPartSolu2; // sum of squared partial solutions
223 
224  int nOfSubsamples; // a copy of an input argument of `iterate' function
225 
226  //----------------------------------------------
227  // register a partial solution in data members
228  void registerPartialSolution(const IDmapF& partialSolution);
229 
230  //----------------------------------------------
231 
232 }; //end of class MinL3AlgoUnivErr prototype
233 
234 //=============================================================================
235 
236 template <class IDdet>
237 MinL3AlgoUnivErr<IDdet>::MinL3AlgoUnivErr(float kweight_) : kweight(kweight_), countEvents(0) {
238  std::cout << "MinL3AlgoUnivErr : L3 algo with a calculation"
239  << " of stat.errors working..." << std::endl;
240  resetSolution();
241 }
242 
243 //=============================================================================
244 
245 template <class IDdet>
246 MinL3AlgoUnivErr<IDdet>::~MinL3AlgoUnivErr() {}
247 
248 //=============================================================================
249 
250 template <class IDdet>
251 typename MinL3AlgoUnivErr<IDdet>::IDmapF MinL3AlgoUnivErr<IDdet>::iterate(
252  const std::vector<std::vector<float> >& eventMatrix,
253  const std::vector<std::vector<IDdet> >& idMatrix,
254  const std::vector<float>& energyVector,
255  const int& nIter,
256  const bool& normalizeFlag,
257  const int& nSubsamples) {
258  // clear the data members which are filled inside the function
259  // (in registerPartialSolution called from here)
260 
261  nOfSubsamples = nSubsamples; // keep the input argument for use in other
262  // functions
263 
264  idToIndex.clear();
265  sumPartSolu0.clear();
266  sumPartSolu1.clear();
267  sumPartSolu2.clear();
268 
269  IDmapF totalSolution;
270 
271  // Loop over samples/solutions:
272  // isol = 0 : all events with the solution stored in
273  // totalSolution
274  // isol = 1,...,nSubsamples : partial solutions are found for sub-samples
275  // with the info on the solutions stored in the
276  // data members
277  // idToIndex, sumPartSolu...
278  // in order to be able to estimate the stat.
279  // errors later
280 
281  for (int isol = 0; isol <= nSubsamples; isol++) {
282  IDmapF sampleSolution; // solution for the sample
283  IDmapF iterSolution; // intermediate solution after an iteration
284  std::vector<std::vector<float> > myEventMatrix;
285  std::vector<std::vector<IDdet> > myIdMatrix;
286  std::vector<float> myEnergyVector;
287 
288  // Select the sample.
289  // Fill myEventMatrix, myIdMatrix and myEnergyVector
290  // either with all evs or with independent event subsamples
291 
292  if (isol == 0) // total solution
293  {
294  myEventMatrix = eventMatrix;
295  myIdMatrix = idMatrix;
296  myEnergyVector = energyVector;
297  } else // partial solution # isol
298  {
299  // clear containers filled for the previous sample
300  sampleSolution.clear();
301  myEventMatrix.clear();
302  myIdMatrix.clear();
303  myEnergyVector.clear();
304 
305  for (int i = 0; i < static_cast<int>(eventMatrix.size()); i++) {
306  // select every nSubsamples'th event to the subsample
307  if (i % nSubsamples + 1 == isol) {
308  myEventMatrix.push_back(eventMatrix[i]);
309  myIdMatrix.push_back(idMatrix[i]);
310  myEnergyVector.push_back(energyVector[i]);
311  }
312  }
313  }
314 
315  int Nevents = myEventMatrix.size(); // Number of events to calibrate with
316  countEvents = 0;
317 
318  int i;
319 
320  // Iterate the correction
321  for (int iter = 1; iter <= nIter; iter++) {
322  // if normalization flag is set, normalize energies
323  float sumOverEnergy;
324  if (normalizeFlag) {
325  float scale = 0.;
326 
327  for (i = 0; i < Nevents; i++) {
328  sumOverEnergy = 0.;
329  for (unsigned j = 0; j < myEventMatrix[i].size(); j++) {
330  sumOverEnergy += myEventMatrix[i][j];
331  }
332  sumOverEnergy /= myEnergyVector[i];
333  scale += sumOverEnergy;
334  }
335  scale /= Nevents;
336 
337  for (i = 0; i < Nevents; i++) {
338  myEnergyVector[i] *= scale;
339  }
340  } // end normalize energies
341 
342  // now the real work starts:
343  for (int iEvt = 0; iEvt < Nevents; iEvt++) {
344  addEvent(myEventMatrix[iEvt], myIdMatrix[iEvt], myEnergyVector[iEvt]);
345  }
346  iterSolution = getSolution();
347  if (iterSolution.empty()) {
348  sampleSolution.clear();
349  break; // exit the iteration loop leaving sampleSolution empty
350  }
351 
352  // re-calibrate eventMatrix with solution
353  for (int ievent = 0; ievent < Nevents; ievent++) {
354  myEventMatrix[ievent] = recalibrateEvent(myEventMatrix[ievent], myIdMatrix[ievent], iterSolution, isol, iter);
355  }
356 
357  // save solution into the sampleSolution map
358  for (iter_IDmapF i = iterSolution.begin(); i != iterSolution.end(); i++) {
359  iter_IDmapF itotal = sampleSolution.find(i->first);
360  if (itotal == sampleSolution.end()) {
361  sampleSolution.insert(IDmapFvalue(i->first, i->second));
362  } else {
363  itotal->second *= i->second;
364  }
365  }
366 
367  // resetSolution(); // reset for new iteration,
368  // now: getSolution does it automatically if not vetoed
369  } // end iterate correction
370 
371  if (isol == 0) // total solution
372  {
373  totalSolution = sampleSolution;
374  } else // partial solution => register it in sumPartSolu...
375  {
376  registerPartialSolution(sampleSolution);
377  }
378 
379  } // end of the loop over solutions/samples
380 
381  return totalSolution;
382 }
383 
384 //=============================================================================
385 
386 template <class IDdet>
387 void MinL3AlgoUnivErr<IDdet>::addEvent(const std::vector<float>& myCluster,
388  const std::vector<IDdet>& idCluster,
389  const float& energy) {
390  countEvents++;
391 
392  float w, invsumXmatrix;
393  float eventw;
394 
395  // Loop over the crystal matrix to find the sum
396  float sumXmatrix = 0.;
397  for (unsigned i = 0; i < myCluster.size(); i++) {
398  sumXmatrix += myCluster[i];
399  }
400 
401  // event weighting
402  eventw = 1 - fabs(1 - sumXmatrix / energy);
403  eventw = pow(eventw, kweight);
404 
405  if (sumXmatrix != 0.) {
406  invsumXmatrix = 1 / sumXmatrix;
407  // Loop over the crystal matrix (3x3,5x5,7x7) again
408  // and calculate the weights for each xtal
409  for (unsigned i = 0; i < myCluster.size(); i++) {
410  w = myCluster[i] * invsumXmatrix;
411 
412  // include the weights into wsum, Ewsum
413  iter_IDmapF iwsum = wsum.find(idCluster[i]);
414  if (iwsum == wsum.end())
415  wsum.insert(IDmapFvalue(idCluster[i], w * eventw));
416  else
417  iwsum->second += w * eventw;
418 
419  iter_IDmapF iEwsum = Ewsum.find(idCluster[i]);
420  if (iEwsum == Ewsum.end())
421  Ewsum.insert(IDmapFvalue(idCluster[i], (w * eventw * energy * invsumXmatrix)));
422  else
423  iEwsum->second += (w * eventw * energy * invsumXmatrix);
424  }
425  }
426  // else {std::cout << " Debug: dropping null event: " << countEvents << std::endl;}
427 }
428 
429 //=============================================================================
430 
431 template <class IDdet>
432 typename MinL3AlgoUnivErr<IDdet>::IDmapF MinL3AlgoUnivErr<IDdet>::getSolution(const bool resetsolution) {
433  IDmapF solution;
434 
435  for (iter_IDmapF i = wsum.begin(); i != wsum.end(); i++) {
436  iter_IDmapF iEwsum = Ewsum.find(i->first);
437  float myValue = 1;
438  if (i->second != 0)
439  myValue = iEwsum->second / i->second;
440 
441  solution.insert(IDmapFvalue(i->first, myValue));
442  }
443 
444  if (resetsolution)
445  resetSolution();
446 
447  return solution;
448 }
449 
450 //=============================================================================
451 
452 template <class IDdet>
453 void MinL3AlgoUnivErr<IDdet>::resetSolution() {
454  wsum.clear();
455  Ewsum.clear();
456 }
457 
458 //=============================================================================
459 
460 template <class IDdet>
461 std::vector<float> MinL3AlgoUnivErr<IDdet>::recalibrateEvent(const std::vector<float>& myCluster,
462  const std::vector<IDdet>& idCluster,
463  const IDmapF& newCalibration,
464  const int& isol, // for a printout only
465  const int& iter // for a printout only
466 ) {
467  std::vector<float> newCluster(myCluster);
468 
469  for (unsigned i = 0; i < myCluster.size(); i++) {
470  citer_IDmapF icalib = newCalibration.find(idCluster[i]);
471  if (icalib != newCalibration.end()) {
472  newCluster[i] *= icalib->second;
473  } else {
474  std::cout << "No calibration available for this element." << std::endl;
475  std::cout << " isol = " << isol << " iter = " << iter << " idCluster[i] = " << idCluster[i] << "\n";
476  }
477  }
478 
479  return newCluster;
480 }
481 
482 //=============================================================================
483 
484 template <class IDdet>
485 void MinL3AlgoUnivErr<IDdet>::registerPartialSolution(const IDmapF& partialSolution)
486 
487 {
488  int lastIndex = sumPartSolu0.size() - 1; // index of the last element
489  // of the parallel vectors
490 
491  for (citer_IDmapF cell = partialSolution.begin(); cell != partialSolution.end(); ++cell) {
492  IDdet id = cell->first;
493  float corr = cell->second;
494 
495  // where is the cell in another map?
496  iter_IDmapI cell2 = idToIndex.find(id);
497 
498  if (cell2 == idToIndex.end()) {
499  // the cell is met for the first time in patial solutions
500  // => insert the info to the end of the vectors
501 
502  sumPartSolu0.push_back(1);
503  sumPartSolu1.push_back(corr);
504  sumPartSolu2.push_back(corr * corr);
505  idToIndex.insert(IDmapIvalue(id, ++lastIndex));
506  } else {
507  // add the info to the already registered cell
508 
509  int index = cell2->second;
510  sumPartSolu0[index] += 1;
511  sumPartSolu1[index] += corr;
512  sumPartSolu2[index] += corr * corr;
513  }
514  }
515 }
516 
517 //=============================================================================
518 
519 template <class IDdet>
520 float MinL3AlgoUnivErr<IDdet>::getError(IDdet id) const
521 
522 {
523  float error;
524  citer_IDmapI cell = idToIndex.find(id);
525  if (cell == idToIndex.end())
526  error = -2.; // no info for the cell
527  else {
528  int i = cell->second;
529  int n = sumPartSolu0[i];
530  if (n <= 1)
531  error = -1.; // 1 entry => error estimate impossible
532  else {
533  float meanX = sumPartSolu1[i] / n;
534  float meanX2 = sumPartSolu2[i] / n;
535 
536  error = sqrt(fabs(meanX2 - meanX * meanX) / (n - 1.));
537  }
538  }
539  return error;
540 }
541 
542 //=============================================================================
543 
544 template <class IDdet>
545 typename MinL3AlgoUnivErr<IDdet>::IDmapF MinL3AlgoUnivErr<IDdet>::getError() const
546 
547 {
548  IDmapF errors;
549  float error;
550 
551  for (citer_IDmapI cell = idToIndex.begin(); cell != idToIndex.end(); ++cell) {
552  int i = cell->second;
553  int n = sumPartSolu0[i];
554  if (n <= 1)
555  error = -1.; // 1 entry => error estimate impossible
556  else {
557  float meanX = sumPartSolu1[i] / n;
558  float meanX2 = sumPartSolu2[i] / n;
559 
560  error = sqrt(fabs(meanX2 - meanX * meanX) / (n - 1));
561  }
562 
563  errors.insert(IDmapFvalue(cell->first, error));
564  }
565  return errors;
566 }
567 //=============================================================================
568 
569 template <class IDdet>
570 float MinL3AlgoUnivErr<IDdet>::getErrorQuality(IDdet id) const
571 
572 {
573  float fraction;
574  citer_IDmapI cell = idToIndex.find(id);
575  if (cell == idToIndex.end())
576  fraction = -1.; // no info for the cell
577  // => return a special value
578  else {
579  int i = cell->second;
580  int n = sumPartSolu0[i];
581  if (n < nOfSubsamples)
582  fraction = float(n) / nOfSubsamples;
583  else
584  fraction = 1.;
585  }
586  return fraction;
587 }
588 
589 //=============================================================================
590 
591 template <class IDdet>
592 typename MinL3AlgoUnivErr<IDdet>::IDmapF MinL3AlgoUnivErr<IDdet>::getErrorQuality() const
593 
594 {
595  IDmapF fractions;
596  float fraction;
597 
598  for (citer_IDmapI cell = idToIndex.begin(); cell != idToIndex.end(); ++cell) {
599  int i = cell->second;
600  int n = sumPartSolu0[i];
601 
602  if (n < nOfSubsamples)
603  fraction = float(n) / nOfSubsamples;
604  else
605  fraction = 1.;
606 
607  fractions.insert(IDmapFvalue(cell->first, fraction));
608  }
609 
610  return fractions;
611 }
612 
613 //=============================================================================
614 
615 template <class IDdet>
616 int MinL3AlgoUnivErr<IDdet>::numberOfWrongErrors() const
617 
618 {
619  int nWrong = 0;
620 
621  for (citer_IDmapI cell = idToIndex.begin(); cell != idToIndex.end(); ++cell) {
622  int i = cell->second;
623  int n = sumPartSolu0[i];
624 
625  if (n < nOfSubsamples)
626  nWrong++;
627  }
628 
629  return nWrong;
630 }
631 
632 //=============================================================================
633 
634 template <class IDdet>
635 float MinL3AlgoUnivErr<IDdet>::getMeanPartialSolution(IDdet id) const
636 
637 {
638  float meanX;
639  citer_IDmapI cell = idToIndex.find(id);
640  if (cell == idToIndex.end())
641  meanX = 999.; // no info for the cell
642  else {
643  int i = cell->second;
644  int n = sumPartSolu0[i];
645  meanX = sumPartSolu1[i] / n;
646  }
647  return meanX;
648 }
649 
650 //=============================================================================
651 
652 template <class IDdet>
653 typename MinL3AlgoUnivErr<IDdet>::IDmapF MinL3AlgoUnivErr<IDdet>::getMeanPartialSolution() const
654 
655 {
656  IDmapF solution;
657 
658  for (citer_IDmapI cell = idToIndex.begin(); cell != idToIndex.end(); ++cell) {
659  int i = cell->second;
660  int n = sumPartSolu0[i];
661  float meanX = sumPartSolu1[i] / n;
662  solution.insert(IDmapFvalue(cell->first, meanX));
663  }
664  return solution;
665 }
666 
667 //=============================================================================
668 
669 #endif // MinL3AlgoUnivErr_H
T w() const
constexpr int pow(int x)
Definition: conifer.h:24
dictionary corr
T sqrt(T t)
Definition: SSEVec.h:19
static std::atomic< unsigned int > lastIndex
Definition: DDValue.cc:12
void resetSolution()
reset for new iteration
Definition: errors.py:1