CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/Calibration/Tools/interface/MinL3AlgoUniv.h

Go to the documentation of this file.
00001 #ifndef MinL3AlgoUniv_H
00002 #define MinL3AlgoUniv_H
00003 
00016 #include <vector>
00017 #include <iostream>
00018 #include <map>
00019 #include <math.h>
00020 
00021 template<class IDdet>
00022 class MinL3AlgoUniv
00023 {
00024 public:
00025   typedef std::map<IDdet,float> IDmap;
00026   typedef typename IDmap::value_type IDmapvalue;
00027   typedef typename IDmap::iterator iter_IDmap;
00028   typedef typename IDmap::const_iterator citer_IDmap;
00029 
00032   MinL3AlgoUniv(float kweight_ = 0.);
00033 
00035   ~MinL3AlgoUniv();
00036 
00042   IDmap iterate(const std::vector<std::vector<float> >& eventMatrix, const std::vector<std::vector<IDdet> >& idMatrix, const std::vector<float>& energyVector, const int& nIter, const bool& normalizeFlag = false);
00043 
00045   void addEvent(const std::vector<float>& myCluster, const std::vector<IDdet>& idCluster, const float& energy);
00046 
00048   std::vector<float> recalibrateEvent(const std::vector<float>& myCluster, const std::vector<IDdet>& idCluster, const IDmap& newCalibration); 
00049 
00052   IDmap getSolution(const bool resetsolution=true);
00053 
00055   void resetSolution(); 
00056 
00057 private:
00058 
00059   float kweight;
00060   int countEvents;
00061   IDmap wsum;
00062   IDmap Ewsum;
00063 
00064 };
00065 
00066 
00067 
00068 template<class IDdet>
00069 MinL3AlgoUniv<IDdet>::MinL3AlgoUniv(float kweight_)
00070   :kweight(kweight_), countEvents(0)
00071 {
00072   resetSolution();
00073 }
00074 
00075 
00076 template<class IDdet>
00077 MinL3AlgoUniv<IDdet>::~MinL3AlgoUniv()
00078 {
00079 }
00080 
00081 
00082 template<class IDdet>
00083 typename MinL3AlgoUniv<IDdet>::IDmap MinL3AlgoUniv<IDdet>::iterate(const std::vector<std::vector<float> >& eventMatrix, const std::vector<std::vector<IDdet> >& idMatrix, const std::vector<float>& energyVector, const int& nIter, const bool& normalizeFlag)
00084 {
00085   int Nevents = eventMatrix.size(); // Number of events to calibrate with
00086 
00087   IDmap totalSolution;
00088   IDmap iterSolution;
00089   std::vector<std::vector<float> > myEventMatrix(eventMatrix);
00090   std::vector<float> myEnergyVector(energyVector);
00091 
00092   int i;
00093 
00094   // Iterate the correction
00095   for (int iter=1;iter<=nIter;iter++) 
00096     {
00097 
00098       // if normalization flag is set, normalize energies
00099       float sumOverEnergy;
00100       if (normalizeFlag)
00101         {
00102           float scale = 0.;
00103           
00104           for (i=0; i<Nevents; i++)
00105             {
00106               sumOverEnergy = 0.;
00107               for (unsigned j=0; j<myEventMatrix[i].size(); j++) {sumOverEnergy += myEventMatrix[i][j];}
00108               sumOverEnergy /= myEnergyVector[i];
00109               scale += sumOverEnergy;
00110             }
00111           scale /= Nevents;
00112           
00113           for (i=0; i<Nevents; i++) {myEnergyVector[i] *= scale;}         
00114         } // end normalize energies
00115 
00116       // now the real work starts:
00117       for (int iEvt=0; iEvt < Nevents; iEvt++)
00118         {
00119           addEvent(myEventMatrix[iEvt], idMatrix[iEvt], myEnergyVector[iEvt]);
00120         }
00121       iterSolution = getSolution();
00122       if (iterSolution.empty()) return iterSolution;
00123 
00124       // re-calibrate eventMatrix with solution
00125       for (int ievent = 0; ievent<Nevents; ievent++)
00126         {
00127           myEventMatrix[ievent] = recalibrateEvent(myEventMatrix[ievent], idMatrix[ievent], iterSolution);
00128         }
00129 
00130       // save solution into theCalibVector
00131       for (iter_IDmap i = iterSolution.begin(); i != iterSolution.end(); i++)
00132         {
00133           iter_IDmap itotal = totalSolution.find(i->first);
00134           if (itotal == totalSolution.end())
00135             {
00136               totalSolution.insert(IDmapvalue(i->first,i->second));
00137             }
00138           else
00139             {
00140               itotal->second *= i->second;
00141             }
00142         }
00143 
00144       //      resetSolution(); // reset for new iteration, now: getSolution does it automatically if not vetoed
00145     } // end iterate correction
00146 
00147   return totalSolution;
00148 }
00149 
00150 
00151 template<class IDdet>
00152 void MinL3AlgoUniv<IDdet>::addEvent(const std::vector<float>& myCluster, const std::vector<IDdet>& idCluster, const float& energy)
00153 {
00154   countEvents++;
00155 
00156   float w, invsumXmatrix;
00157   float eventw;
00158   // Loop over the crystal matrix to find the sum
00159   float sumXmatrix=0.;
00160       
00161   for (unsigned i=0; i<myCluster.size(); i++) { sumXmatrix += myCluster[i]; }
00162       
00163   // event weighting
00164   eventw = 1 - fabs(1 - sumXmatrix/energy);
00165   eventw = pow(eventw,kweight);
00166       
00167   if (sumXmatrix != 0.)
00168     {
00169       invsumXmatrix = 1/sumXmatrix;
00170       // Loop over the crystal matrix (3x3,5x5,7x7) again and calculate the weights for each xtal
00171       for (unsigned i=0; i<myCluster.size(); i++) 
00172         {               
00173           w = myCluster[i] * invsumXmatrix;
00174 
00175           // include the weights into wsum, Ewsum
00176           iter_IDmap iwsum = wsum.find(idCluster[i]);
00177           if (iwsum == wsum.end()) wsum.insert(IDmapvalue(idCluster[i],w*eventw));
00178           else iwsum->second += w*eventw;
00179 
00180           iter_IDmap iEwsum = Ewsum.find(idCluster[i]);
00181           if (iEwsum == Ewsum.end()) Ewsum.insert(IDmapvalue(idCluster[i], (w*eventw * energy * invsumXmatrix) ));
00182           else iEwsum->second += (w*eventw * energy * invsumXmatrix);
00183         }
00184     }
00185   //  else {std::cout << " Debug: dropping null event: " << countEvents << std::endl;}
00186 }
00187 
00188 
00189 template<class IDdet>
00190 typename MinL3AlgoUniv<IDdet>::IDmap MinL3AlgoUniv<IDdet>::getSolution(const bool resetsolution)
00191 {
00192   IDmap solution;
00193 
00194   for (iter_IDmap i = wsum.begin(); i != wsum.end(); i++)
00195     {
00196       iter_IDmap iEwsum = Ewsum.find(i->first);
00197       float myValue = 1;
00198       if (i->second != 0) myValue = iEwsum->second / i->second;
00199 
00200       solution.insert(IDmapvalue(i->first,myValue));
00201     }
00202   
00203   if (resetsolution) resetSolution();
00204 
00205   return solution;
00206 }
00207 
00208 
00209 template<class IDdet>
00210 void MinL3AlgoUniv<IDdet>::resetSolution()
00211 {
00212   wsum.clear();
00213   Ewsum.clear();
00214 }
00215 
00216 
00217 template<class IDdet>
00218 std::vector<float> MinL3AlgoUniv<IDdet>::recalibrateEvent(const std::vector<float>& myCluster, const std::vector<IDdet> &idCluster, const IDmap& newCalibration)
00219 {
00220   std::vector<float> newCluster(myCluster);
00221 
00222   for (unsigned i=0; i<myCluster.size(); i++) 
00223     {
00224       citer_IDmap icalib = newCalibration.find(idCluster[i]);
00225       if (icalib != newCalibration.end())
00226         {
00227           newCluster[i] *= icalib->second;
00228         }
00229       else
00230         {
00231           std::cout << "No calibration available for this element." << std::endl;
00232         }
00233 
00234     }
00235 
00236   return newCluster;
00237 }
00238 
00239 
00240 #endif // MinL3AlgoUniv_H