CMS 3D CMS Logo

MinL3Algorithm.cc
Go to the documentation of this file.
1 
8 #include <cmath>
9 
10 MinL3Algorithm::MinL3Algorithm(float kweight_, int squareMode_, int mineta_, int maxeta_, int minphi_, int maxphi_)
11  : kweight(kweight_),
12  squareMode(squareMode_),
13  mineta(mineta_),
14  maxeta(maxeta_),
15  minphi(minphi_),
16  maxphi(maxphi_),
17  countEvents(0) {
18  int Neta = maxeta - mineta + 1;
19  if (mineta * maxeta < 0)
20  Neta--; // there's no eta index = 0
21  int Nphi = maxphi - minphi + 1;
22  if (Nphi < 0)
23  Nphi += 360;
24 
25  Nchannels = Neta * Nphi; // no. of channels, get it from edges of the region
26 
27  Nxtals = squareMode * squareMode; // no. of xtals in one event
28 
29  wsum.assign(Nchannels, 0.);
30  Ewsum.assign(Nchannels, 0.);
31 }
32 
34 
35 std::vector<float> MinL3Algorithm::iterate(const std::vector<std::vector<float> >& eventMatrix,
36  const std::vector<int>& VmaxCeta,
37  const std::vector<int>& VmaxCphi,
38  const std::vector<float>& energyVector,
39  const int& nIter,
40  const bool& normalizeFlag) {
41  int Nevents = eventMatrix.size(); // Number of events to calibrate with
42 
43  std::vector<float> totalSolution(Nchannels, 1.);
44  std::vector<float> iterSolution;
45  std::vector<std::vector<float> > myEventMatrix(eventMatrix);
46  std::vector<float> myEnergyVector(energyVector);
47 
48  int i, j;
49 
50  // Iterate the correction
51  for (int iter = 1; iter <= nIter; iter++) {
52  // if normalization flag is set, normalize energies
53  float sumOverEnergy;
54  if (normalizeFlag) {
55  float scale = 0.;
56 
57  for (i = 0; i < Nevents; i++) {
58  sumOverEnergy = 0.;
59  for (j = 0; j < Nxtals; j++) {
60  sumOverEnergy += myEventMatrix[i][j];
61  }
62  sumOverEnergy /= myEnergyVector[i];
63  scale += sumOverEnergy;
64  }
65  scale /= Nevents;
66 
67  for (i = 0; i < Nevents; i++) {
68  myEnergyVector[i] *= scale;
69  }
70  } // end normalize energies
71 
72  // now the real work starts:
73  for (int iEvt = 0; iEvt < Nevents; iEvt++) {
74  addEvent(myEventMatrix[iEvt], VmaxCeta[iEvt], VmaxCphi[iEvt], myEnergyVector[iEvt]);
75  }
76  iterSolution = getSolution();
77  if (iterSolution.empty())
78  return iterSolution;
79 
80  // re-calibrate eventMatrix with solution
81  for (int ievent = 0; ievent < Nevents; ievent++) {
82  myEventMatrix[ievent] = recalibrateEvent(myEventMatrix[ievent], VmaxCeta[ievent], VmaxCphi[ievent], iterSolution);
83  }
84 
85  for (int i = 0; i < Nchannels; i++) {
86  // save solution into theCalibVector
87  totalSolution[i] *= iterSolution[i];
88  }
89  // resetSolution(); // reset for new iteration, now: getSolution does it automatically if not vetoed
90  } // end iterate correction
91 
92  return totalSolution;
93 }
94 
95 void MinL3Algorithm::addEvent(const std::vector<float>& eventSquare,
96  const int& maxCeta,
97  const int& maxCphi,
98  const float& energy) {
99  countEvents++;
100 
101  float w, invsumXmatrix;
102  float eventw;
103  int iFull, i;
104  // Loop over the crystal matrix to find the sum
105  float sumXmatrix = 0.;
106 
107  for (i = 0; i < Nxtals; i++) {
108  sumXmatrix += eventSquare[i];
109  }
110 
111  // event weighting
112  eventw = 1 - fabs(1 - sumXmatrix / energy);
113  eventw = pow(eventw, kweight);
114 
115  if (sumXmatrix != 0.) {
116  invsumXmatrix = 1 / sumXmatrix;
117  // Loop over the crystal matrix (3x3,5x5,7x7) again and calculate the weights for each xtal
118  for (i = 0; i < Nxtals; i++) {
119  w = eventSquare[i] * invsumXmatrix;
120 
121  iFull = indexSqr2Reg(i, maxCeta, maxCphi);
122  if (iFull >= 0) {
123  // with event weighting:
124  wsum[iFull] += w * eventw;
125  Ewsum[iFull] += (w * eventw * energy * invsumXmatrix);
126  // wsum[iFull] += w;
127  // Ewsum[iFull] += (w * energy * invsumXmatrix);
128  }
129  }
130  }
131  // else {std::cout << " Debug: dropping null event: " << countEvents << std::endl;}
132 }
133 
134 std::vector<float> MinL3Algorithm::getSolution(bool resetsolution) {
135  std::vector<float> solution(Nchannels, 1.);
136 
137  for (int i = 0; i < Nchannels; i++) {
138  if (wsum[i] != 0.) {
139  solution[i] *= Ewsum[i] / wsum[i];
140  }
141  // else
142  // { std::cout << "warning - no event data for crystal index (reduced region) " << i << std::endl; }
143  }
144 
145  if (resetsolution)
146  resetSolution();
147 
148  return solution;
149 }
150 
152  wsum.assign(Nchannels, 0.);
153  Ewsum.assign(Nchannels, 0.);
154 }
155 
156 std::vector<float> MinL3Algorithm::recalibrateEvent(const std::vector<float>& eventSquare,
157  const int& maxCeta,
158  const int& maxCphi,
159  const std::vector<float>& recalibrateVector) {
160  std::vector<float> newEventSquare(eventSquare);
161  int iFull;
162 
163  for (int i = 0; i < Nxtals; i++) {
164  iFull = indexSqr2Reg(i, maxCeta, maxCphi);
165  if (iFull >= 0)
166  newEventSquare[i] *= recalibrateVector[iFull];
167  }
168  return newEventSquare;
169 }
170 
171 int MinL3Algorithm::indexSqr2Reg(const int& sqrIndex, const int& maxCeta, const int& maxCphi) {
172  int regionIndex;
173 
174  // get the current eta, phi indices
175  int curr_eta = maxCeta - squareMode / 2 + sqrIndex % squareMode;
176  if (curr_eta * maxCeta <= 0) {
177  if (maxCeta > 0)
178  curr_eta--;
179  else
180  curr_eta++;
181  } // JUMP over 0
182 
183  int curr_phi = maxCphi - squareMode / 2 + sqrIndex / squareMode;
184  if (curr_phi < 1)
185  curr_phi += 360;
186  if (curr_phi > 360)
187  curr_phi -= 360;
188 
189  bool negPhiDirection = (maxphi < minphi);
190  int iFullphi;
191 
192  regionIndex = -1;
193 
194  if (curr_eta >= mineta && curr_eta <= maxeta)
195  if ((!negPhiDirection && (curr_phi >= minphi && curr_phi <= maxphi)) ||
196  (negPhiDirection && !(curr_phi >= minphi && curr_phi <= maxphi))) {
197  iFullphi = curr_phi - minphi;
198  if (iFullphi < 0)
199  iFullphi += 360;
200  regionIndex = (curr_eta - mineta) * (maxphi - minphi + 1 + 360 * negPhiDirection) + iFullphi;
201  }
202 
203  return regionIndex;
204 }
MinL3Algorithm(float kweight_=0., int squareMode_=5, int mineta_=1, int maxeta_=85, int minphi_=1, int maxphi_=20)
std::vector< float > getSolution(bool resetsolution=true)
get the solution at the end of the calibration
T w() const
constexpr int pow(int x)
Definition: conifer.h:24
int indexSqr2Reg(const int &sqrIndex, const int &maxCeta, const int &maxCphi)
method to translate from square indices to region indices
std::vector< float > wsum
~MinL3Algorithm()
Destructor.
void resetSolution()
reset for new iteration
void addEvent(const std::vector< float > &eventSquare, const int &maxCeta, const int &maxCphi, const float &energy)
add event to the calculation of the calibration vector
std::vector< float > Ewsum
std::vector< float > recalibrateEvent(const std::vector< float > &eventSquare, const int &maxCeta, const int &maxCphi, const std::vector< float > &recalibrateVector)
recalibrate before next iteration: give previous solution vector as argument
std::vector< float > 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=false)