00001
00010 #include "Calibration/Tools/interface/GenericMinL3Algorithm.h"
00011
00012
00013 GenericMinL3Algorithm::GenericMinL3Algorithm(bool normalise)
00014 :normaliseFlag(normalise)
00015
00016 {
00017 }
00018
00019
00020 GenericMinL3Algorithm::~GenericMinL3Algorithm()
00021 {
00022 }
00023
00024
00025 vector<float> GenericMinL3Algorithm::iterate(const vector<vector<float> >& eventMatrix, const vector<float>& energyVector, const int nIter)
00026 {
00027 vector<float> solution;
00028 vector<vector<float> > myEventMatrix(eventMatrix);
00029 int Nevents = eventMatrix.size();
00030 int Nchannels = eventMatrix[0].size();
00031 vector<float> theCalibVector(Nchannels,1.);
00032
00033
00034 for (int iter=1;iter<=nIter;iter++)
00035 {
00036
00037 solution = iterate(myEventMatrix, energyVector);
00038
00039 if (solution.empty()) return solution;
00040
00041
00042
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
00050 theCalibVector[i] *= solution[i];
00051 }
00052
00053 }
00054
00055 return theCalibVector;
00056 }
00057
00058
00059 vector<float> GenericMinL3Algorithm::iterate(const vector<vector<float> >& eventMatrix, const vector<float>& energyVector)
00060 {
00061 vector<float> solution;
00062 vector<float> myEnergyVector(energyVector);
00063
00064 int Nevents = eventMatrix.size();
00065 int Nchannels = eventMatrix[0].size();
00066
00067
00068 if (Nevents != myEnergyVector.size())
00069 {
00070 cout << "GenericMinL3Algorithm::iterate(): Error: bad matrix dimensions. Dropping out." << endl;
00071 return solution;
00072 }
00073
00074
00075 solution.assign(Nchannels,1.);
00076
00077 int ievent, i, j;
00078
00079
00080 float sumOverEnergy;
00081 if (normaliseFlag)
00082 {
00083 float scale = 0.;
00084
00085 cout << "GenericMinL3Algorithm::iterate(): Normalising event data" << 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 cout << " Normalisation = " << scale << endl;
00096
00097 for (i=0; i<Nevents; i++) {myEnergyVector[i] *= scale;}
00098 }
00099
00100
00101
00102 float sum25, invsum25;
00103 float w;
00104 vector<float> wsum(Nchannels,0.);
00105 vector<float> Ewsum(Nchannels,0.);
00106
00107
00108 for (ievent = 0; ievent<Nevents; ievent++)
00109 {
00110
00111 sum25=0.;
00112
00113 for (i=0; i<Nchannels; i++) { sum25+=eventMatrix[ievent][i]; }
00114
00115 if (sum25 != 0.)
00116 {
00117 invsum25 = 1/sum25;
00118
00119 for (i=0; i<Nchannels; i++)
00120 {
00121 w = eventMatrix[ievent][i] * invsum25;
00122 wsum[i] += w;
00123 Ewsum[i] += (w * myEnergyVector[ievent] * invsum25);
00124 }
00125 }
00126 else {cout << " Debug: dropping null event: " << ievent << endl;}
00127
00128 }
00129
00130
00131 for (i=0; i<Nchannels; i++)
00132 {
00133 if (wsum[i] != 0.)
00134 { solution[i]*=Ewsum[i]/wsum[i]; }
00135 else
00136 { cout << "warning - no event data for crystal index " << i << endl; }
00137 }
00138
00139 return solution;
00140 }