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