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--;
00017 int Nphi = maxphi - minphi + 1;
00018 if (Nphi <0) Nphi += 360;
00019
00020 Nchannels = Neta * Nphi;
00021
00022 Nxtals = squareMode*squareMode;
00023
00024 wsum.assign(Nchannels,0.);
00025 Ewsum.assign(Nchannels,0.);
00026 }
00027
00028
00029 MinL3Algorithm::~MinL3Algorithm()
00030 {
00031 }
00032
00033
00034 vector<float> MinL3Algorithm::iterate(const vector<vector<float> >& eventMatrix, const vector<int>& VmaxCeta, const vector<int>& VmaxCphi, const vector<float>& energyVector, const int& nIter, const bool& normalizeFlag)
00035 {
00036 int Nevents = eventMatrix.size();
00037
00038 vector<float> totalSolution(Nchannels,1.);
00039 vector<float> iterSolution;
00040 vector<vector<float> > myEventMatrix(eventMatrix);
00041 vector<float> myEnergyVector(energyVector);
00042
00043 int i, j;
00044
00045
00046 for (int iter=1;iter<=nIter;iter++)
00047 {
00048
00049
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 }
00066
00067
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
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
00084 totalSolution[i] *= iterSolution[i];
00085 }
00086
00087 }
00088
00089 return totalSolution;
00090 }
00091
00092
00093 void MinL3Algorithm::addEvent(const 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
00101 float sumXmatrix=0.;
00102
00103 for (i=0; i<Nxtals; i++) { sumXmatrix+=eventSquare[i]; }
00104
00105
00106 eventw = 1 - fabs(1 - sumXmatrix/energy);
00107 eventw = pow(eventw,kweight);
00108
00109 if (sumXmatrix != 0.)
00110 {
00111 invsumXmatrix = 1/sumXmatrix;
00112
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
00121 wsum[iFull] += w*eventw;
00122 Ewsum[iFull] += (w*eventw * energy * invsumXmatrix);
00123
00124
00125 }
00126 }
00127 }
00128
00129 }
00130
00131
00132 vector<float> MinL3Algorithm::getSolution(bool resetsolution)
00133 {
00134 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
00141
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 vector<float> MinL3Algorithm::recalibrateEvent(const vector<float>& eventSquare, const int& maxCeta, const int& maxCphi, const vector<float>& recalibrateVector)
00158 {
00159 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
00177 int curr_eta = maxCeta - squareMode/2 + sqrIndex%squareMode;
00178 if (curr_eta * maxCeta <= 0) {if (maxCeta > 0) curr_eta--; else curr_eta++; }
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 }