CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/Calibration/Tools/src/MinL3Algorithm.cc

Go to the documentation of this file.
00001 
00009 #include "Calibration/Tools/interface/MinL3Algorithm.h"
00010 #include <math.h>
00011 
00012 MinL3Algorithm::MinL3Algorithm(float kweight_, int squareMode_, int mineta_, int maxeta_, int minphi_, int maxphi_)
00013   :kweight(kweight_), squareMode(squareMode_), mineta(mineta_), maxeta(maxeta_), minphi(minphi_), maxphi(maxphi_), countEvents(0)
00014 {
00015   int Neta = maxeta - mineta + 1;
00016   if (mineta * maxeta < 0) Neta--; // there's no eta index = 0
00017   int Nphi = maxphi - minphi + 1;
00018   if (Nphi <0) Nphi += 360;
00019   
00020   Nchannels = Neta * Nphi; // no. of channels, get it from edges of the region
00021 
00022   Nxtals = squareMode*squareMode; // no. of xtals in one event
00023 
00024   wsum.assign(Nchannels,0.);
00025   Ewsum.assign(Nchannels,0.);
00026 }
00027 
00028 
00029 MinL3Algorithm::~MinL3Algorithm()
00030 {
00031 }
00032 
00033 
00034 std::vector<float> MinL3Algorithm::iterate(const std::vector<std::vector<float> >& eventMatrix, const std::vector<int>& VmaxCeta, const std::vector<int>& VmaxCphi, const std::vector<float>& energyVector, const int& nIter, const bool& normalizeFlag)
00035 {
00036   int Nevents = eventMatrix.size(); // Number of events to calibrate with
00037 
00038   std::vector<float> totalSolution(Nchannels,1.);
00039   std::vector<float> iterSolution;
00040   std::vector<std::vector<float> > myEventMatrix(eventMatrix);
00041   std::vector<float> myEnergyVector(energyVector);
00042 
00043   int i, j;
00044 
00045   // Iterate the correction
00046   for (int iter=1;iter<=nIter;iter++) 
00047     {
00048 
00049       // if normalization flag is set, normalize energies
00050       float sumOverEnergy;
00051       if (normalizeFlag)
00052         {
00053           float scale = 0.;
00054           
00055           for (i=0; i<Nevents; i++)
00056             {
00057               sumOverEnergy = 0.;
00058               for (j=0; j<Nxtals; j++) {sumOverEnergy += myEventMatrix[i][j];}
00059               sumOverEnergy /= myEnergyVector[i];
00060               scale += sumOverEnergy;
00061             }
00062           scale /= Nevents;
00063           
00064           for (i=0; i<Nevents; i++) {myEnergyVector[i] *= scale;}         
00065         } // end normalize energies
00066 
00067       // now the real work starts:
00068       for (int iEvt=0; iEvt < Nevents; iEvt++)
00069         {
00070           addEvent(myEventMatrix[iEvt], VmaxCeta[iEvt], VmaxCphi[iEvt], myEnergyVector[iEvt]);
00071         }
00072       iterSolution = getSolution();
00073       if (iterSolution.empty()) return iterSolution;
00074 
00075       // re-calibrate eventMatrix with solution
00076       for (int ievent = 0; ievent<Nevents; ievent++)
00077         {
00078           myEventMatrix[ievent] = recalibrateEvent(myEventMatrix[ievent], VmaxCeta[ievent], VmaxCphi[ievent], iterSolution);
00079         }
00080 
00081       for (int i=0; i<Nchannels; i++) 
00082         {
00083           // save solution into theCalibVector
00084           totalSolution[i] *= iterSolution[i];
00085         }
00086       //      resetSolution(); // reset for new iteration, now: getSolution does it automatically if not vetoed
00087     } // end iterate correction
00088 
00089   return totalSolution;
00090 }
00091 
00092 
00093 void MinL3Algorithm::addEvent(const std::vector<float>& eventSquare, const int& maxCeta, const int& maxCphi, const float& energy)
00094 {
00095   countEvents++;
00096 
00097   float w, invsumXmatrix;
00098   float eventw;
00099   int iFull, i;
00100   // Loop over the crystal matrix to find the sum
00101   float sumXmatrix=0.;
00102       
00103   for (i=0; i<Nxtals; i++) { sumXmatrix+=eventSquare[i]; }
00104       
00105   // event weighting
00106   eventw = 1 - fabs(1 - sumXmatrix/energy);
00107   eventw = pow(eventw,kweight);
00108       
00109   if (sumXmatrix != 0.)
00110     {
00111       invsumXmatrix = 1/sumXmatrix;
00112       // Loop over the crystal matrix (3x3,5x5,7x7) again and calculate the weights for each xtal
00113       for (i=0; i<Nxtals; i++) 
00114         {               
00115           w = eventSquare[i] * invsumXmatrix;
00116 
00117           iFull = indexSqr2Reg(i, maxCeta, maxCphi);
00118           if (iFull >= 0)
00119             {
00120               // with event weighting:
00121               wsum[iFull] += w*eventw;
00122               Ewsum[iFull] += (w*eventw * energy * invsumXmatrix);
00123               //              wsum[iFull] += w;
00124               //              Ewsum[iFull] += (w * energy * invsumXmatrix);
00125             }
00126         }
00127     }
00128   //  else {std::cout << " Debug: dropping null event: " << countEvents << std::endl;}
00129 }
00130 
00131 
00132 std::vector<float> MinL3Algorithm::getSolution(bool resetsolution)
00133 {
00134   std::vector<float> solution(Nchannels,1.);
00135 
00136   for (int i=0; i<Nchannels; i++) 
00137     {
00138       if (wsum[i] != 0.) 
00139         { solution[i]*=Ewsum[i]/wsum[i];}
00140       //      else 
00141       //        { std::cout << "warning - no event data for crystal index (reduced region) " << i << std::endl; }
00142     }
00143   
00144   if (resetsolution) resetSolution();
00145 
00146   return solution;
00147 }
00148 
00149 
00150 void MinL3Algorithm::resetSolution()
00151 {
00152   wsum.assign(Nchannels,0.);
00153   Ewsum.assign(Nchannels,0.);
00154 }
00155 
00156 
00157 std::vector<float> MinL3Algorithm::recalibrateEvent(const std::vector<float>& eventSquare, const int& maxCeta, const int& maxCphi, const std::vector<float>& recalibrateVector)
00158 {
00159   std::vector<float> newEventSquare(eventSquare);
00160   int iFull;
00161 
00162   for (int i=0; i<Nxtals; i++) 
00163     {
00164       iFull = indexSqr2Reg(i, maxCeta, maxCphi);
00165       if (iFull >=0)
00166         newEventSquare[i] *= recalibrateVector[iFull];
00167     }
00168   return newEventSquare;
00169 }
00170 
00171 
00172 int MinL3Algorithm::indexSqr2Reg(const int& sqrIndex, const int& maxCeta, const int& maxCphi)
00173 {
00174   int regionIndex;
00175 
00176   // get the current eta, phi indices
00177   int curr_eta = maxCeta - squareMode/2 + sqrIndex%squareMode;
00178   if (curr_eta * maxCeta <= 0) {if (maxCeta > 0) curr_eta--; else curr_eta++; }  // JUMP over 0
00179 
00180   int curr_phi = maxCphi - squareMode/2 + sqrIndex/squareMode;
00181   if (curr_phi < 1) curr_phi += 360;
00182   if (curr_phi > 360) curr_phi -= 360;
00183 
00184   bool negPhiDirection = (maxphi < minphi);
00185   int iFullphi;
00186 
00187   regionIndex = -1;
00188 
00189   if (curr_eta >= mineta && curr_eta <= maxeta)
00190     if ( (!negPhiDirection && (curr_phi >= minphi && curr_phi <= maxphi)) ||
00191          (negPhiDirection && !(curr_phi >= minphi && curr_phi <= maxphi))      ) 
00192       {
00193         iFullphi = curr_phi - minphi;
00194         if (iFullphi < 0) iFullphi += 360;
00195         regionIndex = (curr_eta - mineta) * (maxphi - minphi + 1 + 360*negPhiDirection) + iFullphi;
00196       }
00197 
00198   return regionIndex;
00199 }