CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/Calibration/Tools/interface/MinL3AlgoUnivErr.h

Go to the documentation of this file.
00001 #ifndef MinL3AlgoUnivErr_H
00002 #define MinL3AlgoUnivErr_H
00003 
00004 //=============================================================================
00005 
00069 //=============================================================================
00070 
00071 #include <vector>
00072 #include <iostream>
00073 #include <map>
00074 #include <math.h>
00075 
00076 //=============================================================================
00077 template <class IDdet>
00078 class MinL3AlgoUnivErr
00079 {
00080 public:
00081   typedef          std::map<IDdet,float>  IDmapF;
00082   typedef typename IDmapF::value_type     IDmapFvalue;
00083   typedef typename IDmapF::iterator       iter_IDmapF;
00084   typedef typename IDmapF::const_iterator citer_IDmapF;
00085   typedef          std::map<IDdet,int>    IDmapI;
00086   typedef typename IDmapI::value_type     IDmapIvalue;
00087   typedef typename IDmapI::iterator       iter_IDmapI;
00088   typedef typename IDmapI::const_iterator citer_IDmapI;
00089 
00090   //----------------------------------------------
00093 
00094   MinL3AlgoUnivErr(float kweight_ = 0.);
00095 
00096 
00097   //----------------------------------------------
00099 
00100   ~MinL3AlgoUnivErr();
00101 
00102 
00103   //----------------------------------------------
00116 
00117   IDmapF iterate( const std::vector<std::vector<float> > & eventMatrix,
00118                   const std::vector<std::vector<IDdet> > & idMatrix,
00119                   const std::vector<float>               & energyVector,
00120                   const int                              & nIter,
00121                   const bool                             & normalizeFlag
00122                                                                        = false,
00123                   const int                              & nSubsamples = 10
00124                 );
00125   //----------------------------------------------
00133 
00134   float getError( IDdet id ) const;
00135 
00136   //----------------------------------------------
00145 
00146   IDmapF getError() const;
00147 
00148   //----------------------------------------------
00156 
00157   int numberOfWrongErrors() const;
00158 
00159   //----------------------------------------------
00170 
00171   float  getErrorQuality( IDdet id ) const;
00172 
00173   IDmapF getErrorQuality()           const;
00174 
00175   //----------------------------------------------
00181 
00182   float getMeanPartialSolution( IDdet id ) const;
00183 
00184   //----------------------------------------------
00189 
00190   IDmapF getMeanPartialSolution() const;
00191 
00192   //----------------------------------------------
00194 
00195   void addEvent( const std::vector<float> & myCluster,
00196                  const std::vector<IDdet> & idCluster,
00197                  const float              & energy
00198                );
00199 
00200   //----------------------------------------------
00203 
00204   std::vector<float>
00205   recalibrateEvent( const std::vector<float> & myCluster,
00206                     const std::vector<IDdet> & idCluster,
00207                     const IDmapF             & newCalibration,
00208                     const int                & isol = -1,
00209                     const int                & iter = -1
00210                 ); 
00211 
00212   //----------------------------------------------
00215 
00216   IDmapF getSolution( const bool resetsolution=true );
00217 
00218   //----------------------------------------------
00220 
00221   void resetSolution(); 
00222 
00223   //----------------------------------------------
00224 
00225 private:
00226 
00227   float   kweight;
00228   int     countEvents;
00229   IDmapF  wsum;
00230   IDmapF  Ewsum;
00231   IDmapI                   idToIndex;    // map: cell id -> index of cell info
00232                                          // in sumPartSolu... vectors
00233   std::vector<int>         sumPartSolu0; // number of partial solutions
00234   std::vector<float>       sumPartSolu1; // sum of partial solutions
00235   std::vector<float>       sumPartSolu2; // sum of squared partial solutions
00236 
00237   int nOfSubsamples ; //  a copy of an input argument of `iterate' function
00238 
00239   //----------------------------------------------
00240   // register a partial solution in data members
00241   void registerPartialSolution( const IDmapF & partialSolution );
00242 
00243   //----------------------------------------------
00244 
00245 };                                 //end of class MinL3AlgoUnivErr prototype
00246 
00247 
00248 //=============================================================================
00249 
00250 
00251 template<class IDdet>
00252 MinL3AlgoUnivErr<IDdet>::MinL3AlgoUnivErr(float kweight_)
00253   :kweight(kweight_), countEvents(0)
00254 {
00255   std::cout << "MinL3AlgoUnivErr : L3 algo with a calculation"
00256             << " of stat.errors working..." << std::endl;
00257   resetSolution();
00258 }
00259 
00260 //=============================================================================
00261 
00262 template<class IDdet>
00263 MinL3AlgoUnivErr<IDdet>::~MinL3AlgoUnivErr()
00264 {
00265 }
00266 
00267 //=============================================================================
00268 
00269 template<class IDdet>
00270 typename MinL3AlgoUnivErr<IDdet>::IDmapF
00271 MinL3AlgoUnivErr<IDdet>::
00272 iterate( const std::vector < std::vector<float> > & eventMatrix,
00273          const std::vector < std::vector<IDdet> > & idMatrix,
00274          const std::vector <float>                & energyVector,
00275          const int                                & nIter,
00276          const bool                               & normalizeFlag,
00277          const int                                & nSubsamples
00278        )
00279 {
00280   // clear the data members which are filled inside the function
00281   //                               (in registerPartialSolution called from here)
00282 
00283   nOfSubsamples = nSubsamples; // keep the input argument for use in other
00284                                // functions
00285 
00286   idToIndex    .clear();
00287   sumPartSolu0 .clear();
00288   sumPartSolu1 .clear();
00289   sumPartSolu2 .clear();
00290 
00291   IDmapF totalSolution;
00292 
00293   // Loop over samples/solutions:
00294   //    isol = 0                 : all events with the solution stored in
00295   //                               totalSolution
00296   //    isol = 1,...,nSubsamples : partial solutions are found for sub-samples
00297   //                               with the info on the solutions stored in the
00298   //                               data members
00299   //                                    idToIndex, sumPartSolu...
00300   //                               in order to be able to estimate the stat.
00301   //                               errors later
00302 
00303   for (int isol = 0 ; isol <= nSubsamples; isol++) {
00304 
00305     IDmapF sampleSolution ;  // solution for the sample
00306     IDmapF iterSolution   ;  // intermediate solution after an iteration
00307     std::vector < std::vector<float> > myEventMatrix  ;
00308     std::vector < std::vector<IDdet> > myIdMatrix     ;
00309     std::vector <float>                myEnergyVector ;
00310 
00311     // Select the sample.
00312     // Fill myEventMatrix, myIdMatrix and myEnergyVector 
00313     // either with all evs or with independent event subsamples
00314 
00315     if (isol == 0)  // total solution
00316       {
00317         myEventMatrix  = eventMatrix  ;
00318         myIdMatrix     = idMatrix     ;
00319         myEnergyVector = energyVector ;
00320       }
00321     else            // partial solution # isol
00322       {
00323         // clear containers filled for the previous sample
00324         sampleSolution .clear() ;
00325         myEventMatrix  .clear() ;
00326         myIdMatrix     .clear() ;
00327         myEnergyVector .clear() ;
00328 
00329         for (int i = 0; i < static_cast<int>( eventMatrix.size() ); i++)
00330           {
00331             // select every nSubsamples'th event to the subsample
00332             if ( i % nSubsamples + 1  ==  isol )
00333               {
00334                 myEventMatrix  .push_back (eventMatrix  [i]) ;
00335                 myIdMatrix     .push_back (idMatrix     [i]) ;
00336                 myEnergyVector .push_back (energyVector [i]) ;
00337               }
00338           }
00339       }
00340 
00341     int Nevents = myEventMatrix.size(); // Number of events to calibrate with
00342     countEvents = 0;
00343 
00344     int i;
00345 
00346     // Iterate the correction
00347     for (int iter=1 ; iter <= nIter ; iter++) 
00348       {
00349 
00350         // if normalization flag is set, normalize energies
00351         float sumOverEnergy;
00352         if (normalizeFlag)
00353           {
00354             float scale = 0.;
00355             
00356             for (i=0; i<Nevents; i++)
00357               {
00358                 sumOverEnergy = 0.;
00359                 for (unsigned j=0 ; j < myEventMatrix[i].size() ; j++)
00360                                        {sumOverEnergy += myEventMatrix[i][j];}
00361                 sumOverEnergy /= myEnergyVector[i];
00362                 scale += sumOverEnergy;
00363               }
00364             scale /= Nevents;
00365           
00366             for (i=0; i<Nevents; i++) {myEnergyVector[i] *= scale;}       
00367           } // end normalize energies
00368 
00369         // now the real work starts:
00370         for (int iEvt=0; iEvt < Nevents; iEvt++)
00371           {
00372             addEvent( myEventMatrix[iEvt], myIdMatrix[iEvt]
00373                                          , myEnergyVector[iEvt] );
00374           }
00375         iterSolution = getSolution();
00376         if (iterSolution.empty())
00377           { sampleSolution.clear();
00378             break;    // exit the iteration loop leaving sampleSolution empty 
00379           }
00380 
00381         // re-calibrate eventMatrix with solution
00382         for (int ievent = 0; ievent<Nevents; ievent++)
00383           {
00384             myEventMatrix[ievent] = recalibrateEvent (myEventMatrix[ievent],
00385                                                       myIdMatrix[ievent],
00386                                                       iterSolution,
00387                                                       isol,iter);
00388           }
00389 
00390         // save solution into the sampleSolution map
00391         for (iter_IDmapF i = iterSolution.begin(); i != iterSolution.end(); i++)
00392           {
00393             iter_IDmapF itotal = sampleSolution.find(i->first);
00394             if (itotal == sampleSolution.end())
00395               {
00396                 sampleSolution.insert(IDmapFvalue(i->first,i->second));
00397               }
00398             else
00399               {
00400                 itotal->second *= i->second;
00401               }
00402           }
00403 
00404         //      resetSolution(); // reset for new iteration,
00405         //               now: getSolution does it automatically if not vetoed
00406       } // end iterate correction
00407     
00408     if (isol == 0) // total solution
00409       {
00410         totalSolution = sampleSolution;
00411       }
00412     else           // partial solution => register it in sumPartSolu...
00413       {
00414         registerPartialSolution( sampleSolution );
00415       }
00416 
00417   }  // end of the loop over solutions/samples
00418 
00419   return totalSolution;
00420 }
00421 
00422 
00423 //=============================================================================
00424 
00425 template<class IDdet>
00426 void MinL3AlgoUnivErr<IDdet>::
00427 addEvent( const std::vector<float> & myCluster,
00428           const std::vector<IDdet> & idCluster,
00429           const float              & energy
00430         )
00431 {
00432   countEvents++;
00433 
00434   float w, invsumXmatrix;
00435   float eventw;
00436 
00437   // Loop over the crystal matrix to find the sum
00438   float sumXmatrix=0.;
00439   for (unsigned i=0; i<myCluster.size(); i++) { sumXmatrix += myCluster[i]; }
00440       
00441   // event weighting
00442   eventw = 1 - fabs(1 - sumXmatrix/energy);
00443   eventw = pow(eventw,kweight);
00444       
00445   if (sumXmatrix != 0.)
00446     {
00447       invsumXmatrix = 1/sumXmatrix;
00448       // Loop over the crystal matrix (3x3,5x5,7x7) again
00449       // and calculate the weights for each xtal
00450       for (unsigned i=0; i<myCluster.size(); i++) 
00451         {               
00452           w = myCluster[i] * invsumXmatrix;
00453 
00454           // include the weights into wsum, Ewsum
00455           iter_IDmapF iwsum = wsum.find(idCluster[i]);
00456           if (iwsum == wsum.end())
00457                                wsum.insert(IDmapFvalue(idCluster[i],w*eventw));
00458           else iwsum->second += w*eventw;
00459 
00460           iter_IDmapF iEwsum = Ewsum.find(idCluster[i]);
00461           if (iEwsum == Ewsum.end())
00462                 Ewsum.insert(IDmapFvalue (idCluster[i],
00463                                           (w*eventw * energy * invsumXmatrix)
00464                                          ));
00465           else iEwsum->second += (w*eventw * energy * invsumXmatrix);
00466         }
00467     }
00468   //  else {std::cout << " Debug: dropping null event: " << countEvents << std::endl;}
00469 }
00470 
00471 //=============================================================================
00472 
00473 template<class IDdet>
00474 typename MinL3AlgoUnivErr<IDdet>::IDmapF
00475 MinL3AlgoUnivErr<IDdet>::
00476 getSolution( const bool resetsolution )
00477 {
00478   IDmapF solution;
00479 
00480   for (iter_IDmapF i = wsum.begin(); i != wsum.end(); i++)
00481     {
00482       iter_IDmapF iEwsum = Ewsum.find(i->first);
00483       float myValue = 1;
00484       if (i->second != 0) myValue = iEwsum->second / i->second;
00485 
00486       solution.insert( IDmapFvalue(i->first,myValue) );
00487     }
00488   
00489   if (resetsolution) resetSolution();
00490 
00491   return solution;
00492 }
00493 
00494 //=============================================================================
00495 
00496 template<class IDdet>
00497 void MinL3AlgoUnivErr<IDdet>::resetSolution()
00498 {
00499   wsum.clear();
00500   Ewsum.clear();
00501 }
00502 
00503 //=============================================================================
00504 
00505 template<class IDdet>
00506 std::vector<float>
00507 MinL3AlgoUnivErr<IDdet>::
00508 recalibrateEvent( const std::vector <float> & myCluster,
00509                   const std::vector <IDdet> & idCluster,
00510                   const IDmapF              & newCalibration,
00511                   const int                 & isol,     // for a printout only
00512                   const int                 & iter      // for a printout only
00513                 )
00514 {
00515   std::vector<float> newCluster(myCluster);
00516 
00517   for (unsigned i=0; i<myCluster.size(); i++) 
00518     {
00519       citer_IDmapF icalib = newCalibration.find(idCluster[i]);
00520       if (icalib != newCalibration.end())
00521         {
00522           newCluster[i] *= icalib->second;
00523         }
00524       else
00525         {
00526           std::cout << "No calibration available for this element."
00527                     << std::endl;
00528           std::cout  << "   isol = " << isol
00529                      << "   iter = " << iter
00530                      << "   idCluster[i] = " << idCluster[i] << "\n";
00531         }
00532 
00533     }
00534 
00535   return newCluster;
00536 }
00537 
00538 //=============================================================================
00539 
00540 template<class IDdet>
00541 void
00542 MinL3AlgoUnivErr<IDdet>::
00543 registerPartialSolution( const IDmapF & partialSolution )
00544 
00545 {
00546   int lastIndex = sumPartSolu0.size() - 1; // index of the last element
00547                                            // of the parallel vectors
00548 
00549   for (citer_IDmapF cell  = partialSolution.begin() ;
00550                     cell != partialSolution.  end() ; ++cell)
00551     {
00552       IDdet id   = cell->first ;
00553       float corr = cell->second;
00554 
00555       // where is the cell in another map?
00556       iter_IDmapI cell2 =  idToIndex.find( id );
00557 
00558       if ( cell2 == idToIndex.end() )
00559         {
00560           // the cell is met for the first time in patial solutions
00561           // => insert the info to the end of the vectors
00562 
00563           sumPartSolu0.push_back( 1 );
00564           sumPartSolu1.push_back( corr );
00565           sumPartSolu2.push_back( corr * corr );
00566           idToIndex.insert( IDmapIvalue( id, ++lastIndex ) );
00567         }
00568       else
00569         {
00570           // add the info to the already registered cell
00571 
00572           int index = cell2 -> second;
00573           sumPartSolu0[ index ] +=           1;
00574           sumPartSolu1[ index ] +=        corr;
00575           sumPartSolu2[ index ] += corr * corr;
00576         }
00577 
00578     }
00579 
00580 }
00581 
00582 //=============================================================================
00583 
00584 template<class IDdet>
00585 float
00586 MinL3AlgoUnivErr<IDdet>::
00587 getError( IDdet id ) const
00588 
00589 {
00590   float error;
00591   citer_IDmapI cell =  idToIndex.find( id );
00592   if ( cell == idToIndex.end() ) error = -2.;     // no info for the cell
00593   else
00594     {
00595       int i = cell->second;
00596       int n = sumPartSolu0[ i ];
00597       if (n <= 1 ) error = -1.;     // 1 entry => error estimate impossible
00598       else
00599         {
00600           float meanX  = sumPartSolu1[ i ] / n;
00601           float meanX2 = sumPartSolu2[ i ] / n;
00602 
00603           error = sqrt( fabs(meanX2 - meanX * meanX) / (n - 1.)  ) ;
00604         }
00605         
00606     }
00607   return error;
00608 }
00609 
00610 //=============================================================================
00611 
00612 template<class IDdet>
00613 typename MinL3AlgoUnivErr<IDdet>::IDmapF
00614 MinL3AlgoUnivErr<IDdet>::
00615 getError() const
00616 
00617 {
00618   IDmapF errors;
00619   float  error;
00620 
00621   for (citer_IDmapI cell  = idToIndex.begin();
00622                     cell != idToIndex.  end(); ++cell )
00623     {
00624       int i = cell->second;
00625       int n = sumPartSolu0[ i ];
00626       if (n <= 1 ) error = -1.;     // 1 entry => error estimate impossible
00627       else
00628         {
00629           float meanX  = sumPartSolu1[ i ] / n;
00630           float meanX2 = sumPartSolu2[ i ] / n;
00631 
00632           error = sqrt( fabs(meanX2 - meanX * meanX) / (n - 1)  ) ;
00633         }
00634 
00635       errors.insert( IDmapFvalue( cell->first , error ) );
00636     }
00637   return errors;
00638 }
00639 //=============================================================================
00640 
00641 template<class IDdet>
00642 float
00643 MinL3AlgoUnivErr<IDdet>::
00644 getErrorQuality( IDdet id ) const
00645 
00646 {
00647   float fraction;
00648   citer_IDmapI cell =  idToIndex.find( id );
00649   if ( cell == idToIndex.end() ) fraction = -1.;   // no info for the cell
00650                                                    // => return a special value
00651   else
00652     {
00653       int i = cell->second;
00654       int n = sumPartSolu0[ i ];
00655       if (n < nOfSubsamples ) fraction = float( n ) / nOfSubsamples; 
00656       else                    fraction = 1.;
00657     }
00658   return fraction;
00659 }
00660 
00661 //=============================================================================
00662 
00663 template<class IDdet>
00664 typename MinL3AlgoUnivErr<IDdet>::IDmapF
00665 MinL3AlgoUnivErr<IDdet>::
00666 getErrorQuality()           const
00667 
00668 {
00669   IDmapF fractions;
00670   float  fraction;
00671 
00672   for (citer_IDmapI cell  = idToIndex.begin();
00673                     cell != idToIndex.  end(); ++cell )
00674     {
00675       int i = cell->second;
00676       int n = sumPartSolu0[ i ];
00677 
00678       if (n < nOfSubsamples ) fraction = float( n ) / nOfSubsamples; 
00679       else                    fraction = 1.;
00680 
00681       fractions.insert( IDmapFvalue( cell->first , fraction ) );
00682     }
00683 
00684   return fractions;
00685 }
00686 
00687 
00688 //=============================================================================
00689 
00690 template<class IDdet>
00691 int
00692 MinL3AlgoUnivErr<IDdet>::
00693 numberOfWrongErrors() const
00694 
00695 {
00696   int nWrong = 0 ;
00697 
00698   for (citer_IDmapI cell  = idToIndex.begin();
00699                     cell != idToIndex.  end(); ++cell )
00700     {
00701       int i = cell->second;
00702       int n = sumPartSolu0[ i ];
00703 
00704       if (n < nOfSubsamples ) nWrong++;
00705     }
00706 
00707   return nWrong;
00708 }
00709 
00710 //=============================================================================
00711 
00712 template<class IDdet>
00713 float
00714 MinL3AlgoUnivErr<IDdet>::
00715 getMeanPartialSolution( IDdet id ) const
00716 
00717 {
00718   float meanX;
00719   citer_IDmapI cell =  idToIndex.find( id );
00720   if ( cell == idToIndex.end() ) meanX = 999.;     // no info for the cell
00721   else
00722     {
00723       int i = cell->second;
00724       int   n      = sumPartSolu0[ i ];
00725       float meanX  = sumPartSolu1[ i ] / n;
00726     }
00727   return meanX;
00728 
00729 }
00730 
00731 //=============================================================================
00732 
00733 template<class IDdet>
00734 typename MinL3AlgoUnivErr<IDdet>::IDmapF
00735 MinL3AlgoUnivErr<IDdet>::
00736 getMeanPartialSolution () const
00737 
00738 {
00739   IDmapF solution;
00740 
00741   for (citer_IDmapI cell  = idToIndex.begin();
00742                     cell != idToIndex.  end(); ++cell )
00743     {
00744       int i = cell->second;
00745       int   n      = sumPartSolu0[ i ];
00746       float meanX  = sumPartSolu1[ i ] / n;
00747       solution.insert( IDmapFvalue( cell->first , meanX ) );
00748     }
00749   return solution;
00750 }
00751 
00752 //=============================================================================
00753 
00754 #endif // MinL3AlgoUnivErr_H