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();
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
00095 for (int iter=1;iter<=nIter;iter++)
00096 {
00097
00098
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 }
00115
00116
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
00125 for (int ievent = 0; ievent<Nevents; ievent++)
00126 {
00127 myEventMatrix[ievent] = recalibrateEvent(myEventMatrix[ievent], idMatrix[ievent], iterSolution);
00128 }
00129
00130
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
00145 }
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
00159 float sumXmatrix=0.;
00160
00161 for (unsigned i=0; i<myCluster.size(); i++) { sumXmatrix += myCluster[i]; }
00162
00163
00164 eventw = 1 - fabs(1 - sumXmatrix/energy);
00165 eventw = pow(eventw,kweight);
00166
00167 if (sumXmatrix != 0.)
00168 {
00169 invsumXmatrix = 1/sumXmatrix;
00170
00171 for (unsigned i=0; i<myCluster.size(); i++)
00172 {
00173 w = myCluster[i] * invsumXmatrix;
00174
00175
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
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