CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_4/src/Calibration/Tools/src/GenericMinL3Algorithm.cc

Go to the documentation of this file.
00001 
00010 #include "Calibration/Tools/interface/GenericMinL3Algorithm.h"
00011 
00012 
00013 GenericMinL3Algorithm::GenericMinL3Algorithm(bool normalise)
00014   :normaliseFlag(normalise)
00015 // if normalize=true: for all events sum the e25ovTRP. then take the mean value and rescale all TrP
00016 {
00017 }
00018 
00019 
00020 GenericMinL3Algorithm::~GenericMinL3Algorithm()
00021 {
00022 }
00023 
00024 
00025 std::vector<float> GenericMinL3Algorithm::iterate(const std::vector<std::vector<float> >& eventMatrix, const std::vector<float>& energyVector, const int nIter)
00026 {
00027   std::vector<float> solution;
00028   std::vector<std::vector<float> > myEventMatrix(eventMatrix);
00029   int Nevents = eventMatrix.size(); // Number of events to calibrate with
00030   int Nchannels = eventMatrix[0].size(); // Number of channel coefficients
00031   std::vector<float> theCalibVector(Nchannels,1.);
00032 
00033   // Iterate the correction
00034   for (int iter=1;iter<=nIter;iter++) 
00035     {
00036       // make one iteration
00037       solution = iterate(myEventMatrix, energyVector);
00038 
00039       if (solution.empty()) return solution;
00040       // R.O.: or throw an exception, what's the standard CMS way ?
00041 
00042       // re-calibrate eventMatrix with solution
00043       for (int i=0; i<Nchannels; i++) 
00044         {
00045           for (int ievent = 0; ievent<Nevents; ievent++)
00046             {
00047               myEventMatrix[ievent][i] *= solution[i];
00048             }
00049           // save solution into theCalibVector
00050           theCalibVector[i] *= solution[i];
00051         }
00052 
00053     } // end iterate the correction
00054 
00055   return theCalibVector;
00056 }
00057 
00058 
00059 std::vector<float> GenericMinL3Algorithm::iterate(const std::vector<std::vector<float> >& eventMatrix, const std::vector<float>& energyVector)
00060 {
00061   std::vector<float> solution;
00062   std::vector<float> myEnergyVector(energyVector);
00063 
00064   int Nevents = eventMatrix.size(); // Number of events to calibrate with
00065   int Nchannels = eventMatrix[0].size(); // Number of channel coefficients
00066 
00067   // Sanity check
00068   if (Nevents != int(myEnergyVector.size())) 
00069     {
00070       std::cout << "GenericMinL3Algorithm::iterate(): Error: bad matrix dimensions. Dropping out." << std::endl;
00071       return solution; // empty vector !
00072     }
00073 
00074   // initialize the solution vector with 1.
00075   solution.assign(Nchannels,1.);
00076 
00077   int ievent, i, j;
00078 
00079   // if normalization flag is set, normalize energies
00080   float sumOverEnergy;
00081   if (normaliseFlag)
00082     {
00083       float scale = 0.;
00084       
00085       std::cout << "GenericMinL3Algorithm::iterate(): Normalising event data" << std::endl;
00086 
00087       for (i=0; i<Nevents; i++)
00088         {
00089           sumOverEnergy = 0.;
00090           for (j=0; j<Nchannels; j++) {sumOverEnergy += eventMatrix[i][j];}
00091           sumOverEnergy /= myEnergyVector[i];
00092           scale += sumOverEnergy;
00093         }
00094       scale /= Nevents;
00095       std::cout << "  Normalisation = " << scale << std::endl;
00096       
00097       for (i=0; i<Nevents; i++) {myEnergyVector[i] *= scale;}     
00098     } // end normalize energies
00099 
00100 
00101   // This is where the real work goes on...
00102   float sum25, invsum25;
00103   float w; // weight for event
00104   std::vector<float> wsum(Nchannels,0.); // sum of weights for a crystal
00105   std::vector<float> Ewsum(Nchannels,0.); // sum of products of weight*Etrue/E25
00106 
00107   // Loop over events
00108   for (ievent = 0; ievent<Nevents; ievent++)
00109     {
00110       // Loop over the 5x5 to find the sum
00111       sum25=0.;
00112       
00113       for (i=0; i<Nchannels; i++) { sum25+=eventMatrix[ievent][i]; } //*calibs[i];
00114       
00115       if (sum25 != 0.)
00116         {
00117           invsum25 = 1/sum25;
00118           // Loop over the 5x5 again and calculate the weights for each xtal
00119           for (i=0; i<Nchannels; i++) 
00120             {           
00121               w = eventMatrix[ievent][i] * invsum25; // * calibs[i]
00122               wsum[i] += w;
00123               Ewsum[i] += (w * myEnergyVector[ievent] * invsum25);      
00124             }
00125         }
00126       else {std::cout << " Debug: dropping null event: " << ievent << std::endl;}
00127       
00128     } // end Loop over events
00129   
00130   // Apply correction factors to all channels not in the margin
00131   for (i=0; i<Nchannels; i++) 
00132     {
00133       if (wsum[i] != 0.) 
00134         { solution[i]*=Ewsum[i]/wsum[i]; }
00135       else 
00136         { std::cout << "warning - no event data for crystal index " << i << std::endl; }
00137     }
00138 
00139   return solution;
00140 }