File indexing completed on 2024-04-06 11:59:29
0001 #ifndef MinL3AlgoUnivErr_H
0002 #define MinL3AlgoUnivErr_H
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 #include <vector>
0070 #include <iostream>
0071 #include <map>
0072 #include <cmath>
0073
0074
0075 template <class IDdet>
0076 class MinL3AlgoUnivErr {
0077 public:
0078 typedef std::map<IDdet, float> IDmapF;
0079 typedef typename IDmapF::value_type IDmapFvalue;
0080 typedef typename IDmapF::iterator iter_IDmapF;
0081 typedef typename IDmapF::const_iterator citer_IDmapF;
0082 typedef std::map<IDdet, int> IDmapI;
0083 typedef typename IDmapI::value_type IDmapIvalue;
0084 typedef typename IDmapI::iterator iter_IDmapI;
0085 typedef typename IDmapI::const_iterator citer_IDmapI;
0086
0087
0088
0089
0090
0091 MinL3AlgoUnivErr(float kweight_ = 0.);
0092
0093
0094
0095
0096 ~MinL3AlgoUnivErr();
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 IDmapF iterate(const std::vector<std::vector<float> >& eventMatrix,
0113 const std::vector<std::vector<IDdet> >& idMatrix,
0114 const std::vector<float>& energyVector,
0115 const int& nIter,
0116 const bool& normalizeFlag = false,
0117 const int& nSubsamples = 10);
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127 float getError(IDdet id) const;
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139 IDmapF getError() const;
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 int numberOfWrongErrors() const;
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164 float getErrorQuality(IDdet id) const;
0165
0166 IDmapF getErrorQuality() const;
0167
0168
0169
0170
0171
0172
0173
0174
0175 float getMeanPartialSolution(IDdet id) const;
0176
0177
0178
0179
0180
0181
0182
0183 IDmapF getMeanPartialSolution() const;
0184
0185
0186
0187
0188 void addEvent(const std::vector<float>& myCluster, const std::vector<IDdet>& idCluster, const float& energy);
0189
0190
0191
0192
0193
0194 std::vector<float> recalibrateEvent(const std::vector<float>& myCluster,
0195 const std::vector<IDdet>& idCluster,
0196 const IDmapF& newCalibration,
0197 const int& isol = -1,
0198 const int& iter = -1);
0199
0200
0201
0202
0203
0204 IDmapF getSolution(const bool resetsolution = true);
0205
0206
0207
0208
0209 void resetSolution();
0210
0211
0212
0213 private:
0214 float kweight;
0215 int countEvents;
0216 IDmapF wsum;
0217 IDmapF Ewsum;
0218 IDmapI idToIndex;
0219
0220 std::vector<int> sumPartSolu0;
0221 std::vector<float> sumPartSolu1;
0222 std::vector<float> sumPartSolu2;
0223
0224 int nOfSubsamples;
0225
0226
0227
0228 void registerPartialSolution(const IDmapF& partialSolution);
0229
0230
0231
0232 };
0233
0234
0235
0236 template <class IDdet>
0237 MinL3AlgoUnivErr<IDdet>::MinL3AlgoUnivErr(float kweight_) : kweight(kweight_), countEvents(0) {
0238 std::cout << "MinL3AlgoUnivErr : L3 algo with a calculation"
0239 << " of stat.errors working..." << std::endl;
0240 resetSolution();
0241 }
0242
0243
0244
0245 template <class IDdet>
0246 MinL3AlgoUnivErr<IDdet>::~MinL3AlgoUnivErr() {}
0247
0248
0249
0250 template <class IDdet>
0251 typename MinL3AlgoUnivErr<IDdet>::IDmapF MinL3AlgoUnivErr<IDdet>::iterate(
0252 const std::vector<std::vector<float> >& eventMatrix,
0253 const std::vector<std::vector<IDdet> >& idMatrix,
0254 const std::vector<float>& energyVector,
0255 const int& nIter,
0256 const bool& normalizeFlag,
0257 const int& nSubsamples) {
0258
0259
0260
0261 nOfSubsamples = nSubsamples;
0262
0263
0264 idToIndex.clear();
0265 sumPartSolu0.clear();
0266 sumPartSolu1.clear();
0267 sumPartSolu2.clear();
0268
0269 IDmapF totalSolution;
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281 for (int isol = 0; isol <= nSubsamples; isol++) {
0282 IDmapF sampleSolution;
0283 IDmapF iterSolution;
0284 std::vector<std::vector<float> > myEventMatrix;
0285 std::vector<std::vector<IDdet> > myIdMatrix;
0286 std::vector<float> myEnergyVector;
0287
0288
0289
0290
0291
0292 if (isol == 0)
0293 {
0294 myEventMatrix = eventMatrix;
0295 myIdMatrix = idMatrix;
0296 myEnergyVector = energyVector;
0297 } else
0298 {
0299
0300 sampleSolution.clear();
0301 myEventMatrix.clear();
0302 myIdMatrix.clear();
0303 myEnergyVector.clear();
0304
0305 for (int i = 0; i < static_cast<int>(eventMatrix.size()); i++) {
0306
0307 if (i % nSubsamples + 1 == isol) {
0308 myEventMatrix.push_back(eventMatrix[i]);
0309 myIdMatrix.push_back(idMatrix[i]);
0310 myEnergyVector.push_back(energyVector[i]);
0311 }
0312 }
0313 }
0314
0315 int Nevents = myEventMatrix.size();
0316 countEvents = 0;
0317
0318 int i;
0319
0320
0321 for (int iter = 1; iter <= nIter; iter++) {
0322
0323 float sumOverEnergy;
0324 if (normalizeFlag) {
0325 float scale = 0.;
0326
0327 for (i = 0; i < Nevents; i++) {
0328 sumOverEnergy = 0.;
0329 for (unsigned j = 0; j < myEventMatrix[i].size(); j++) {
0330 sumOverEnergy += myEventMatrix[i][j];
0331 }
0332 sumOverEnergy /= myEnergyVector[i];
0333 scale += sumOverEnergy;
0334 }
0335 scale /= Nevents;
0336
0337 for (i = 0; i < Nevents; i++) {
0338 myEnergyVector[i] *= scale;
0339 }
0340 }
0341
0342
0343 for (int iEvt = 0; iEvt < Nevents; iEvt++) {
0344 addEvent(myEventMatrix[iEvt], myIdMatrix[iEvt], myEnergyVector[iEvt]);
0345 }
0346 iterSolution = getSolution();
0347 if (iterSolution.empty()) {
0348 sampleSolution.clear();
0349 break;
0350 }
0351
0352
0353 for (int ievent = 0; ievent < Nevents; ievent++) {
0354 myEventMatrix[ievent] = recalibrateEvent(myEventMatrix[ievent], myIdMatrix[ievent], iterSolution, isol, iter);
0355 }
0356
0357
0358 for (iter_IDmapF i = iterSolution.begin(); i != iterSolution.end(); i++) {
0359 iter_IDmapF itotal = sampleSolution.find(i->first);
0360 if (itotal == sampleSolution.end()) {
0361 sampleSolution.insert(IDmapFvalue(i->first, i->second));
0362 } else {
0363 itotal->second *= i->second;
0364 }
0365 }
0366
0367
0368
0369 }
0370
0371 if (isol == 0)
0372 {
0373 totalSolution = sampleSolution;
0374 } else
0375 {
0376 registerPartialSolution(sampleSolution);
0377 }
0378
0379 }
0380
0381 return totalSolution;
0382 }
0383
0384
0385
0386 template <class IDdet>
0387 void MinL3AlgoUnivErr<IDdet>::addEvent(const std::vector<float>& myCluster,
0388 const std::vector<IDdet>& idCluster,
0389 const float& energy) {
0390 countEvents++;
0391
0392 float w, invsumXmatrix;
0393 float eventw;
0394
0395
0396 float sumXmatrix = 0.;
0397 for (unsigned i = 0; i < myCluster.size(); i++) {
0398 sumXmatrix += myCluster[i];
0399 }
0400
0401
0402 eventw = 1 - fabs(1 - sumXmatrix / energy);
0403 eventw = pow(eventw, kweight);
0404
0405 if (sumXmatrix != 0.) {
0406 invsumXmatrix = 1 / sumXmatrix;
0407
0408
0409 for (unsigned i = 0; i < myCluster.size(); i++) {
0410 w = myCluster[i] * invsumXmatrix;
0411
0412
0413 iter_IDmapF iwsum = wsum.find(idCluster[i]);
0414 if (iwsum == wsum.end())
0415 wsum.insert(IDmapFvalue(idCluster[i], w * eventw));
0416 else
0417 iwsum->second += w * eventw;
0418
0419 iter_IDmapF iEwsum = Ewsum.find(idCluster[i]);
0420 if (iEwsum == Ewsum.end())
0421 Ewsum.insert(IDmapFvalue(idCluster[i], (w * eventw * energy * invsumXmatrix)));
0422 else
0423 iEwsum->second += (w * eventw * energy * invsumXmatrix);
0424 }
0425 }
0426
0427 }
0428
0429
0430
0431 template <class IDdet>
0432 typename MinL3AlgoUnivErr<IDdet>::IDmapF MinL3AlgoUnivErr<IDdet>::getSolution(const bool resetsolution) {
0433 IDmapF solution;
0434
0435 for (iter_IDmapF i = wsum.begin(); i != wsum.end(); i++) {
0436 iter_IDmapF iEwsum = Ewsum.find(i->first);
0437 float myValue = 1;
0438 if (i->second != 0)
0439 myValue = iEwsum->second / i->second;
0440
0441 solution.insert(IDmapFvalue(i->first, myValue));
0442 }
0443
0444 if (resetsolution)
0445 resetSolution();
0446
0447 return solution;
0448 }
0449
0450
0451
0452 template <class IDdet>
0453 void MinL3AlgoUnivErr<IDdet>::resetSolution() {
0454 wsum.clear();
0455 Ewsum.clear();
0456 }
0457
0458
0459
0460 template <class IDdet>
0461 std::vector<float> MinL3AlgoUnivErr<IDdet>::recalibrateEvent(const std::vector<float>& myCluster,
0462 const std::vector<IDdet>& idCluster,
0463 const IDmapF& newCalibration,
0464 const int& isol,
0465 const int& iter
0466 ) {
0467 std::vector<float> newCluster(myCluster);
0468
0469 for (unsigned i = 0; i < myCluster.size(); i++) {
0470 citer_IDmapF icalib = newCalibration.find(idCluster[i]);
0471 if (icalib != newCalibration.end()) {
0472 newCluster[i] *= icalib->second;
0473 } else {
0474 std::cout << "No calibration available for this element." << std::endl;
0475 std::cout << " isol = " << isol << " iter = " << iter << " idCluster[i] = " << idCluster[i] << "\n";
0476 }
0477 }
0478
0479 return newCluster;
0480 }
0481
0482
0483
0484 template <class IDdet>
0485 void MinL3AlgoUnivErr<IDdet>::registerPartialSolution(const IDmapF& partialSolution)
0486
0487 {
0488 int lastIndex = sumPartSolu0.size() - 1;
0489
0490
0491 for (citer_IDmapF cell = partialSolution.begin(); cell != partialSolution.end(); ++cell) {
0492 IDdet id = cell->first;
0493 float corr = cell->second;
0494
0495
0496 iter_IDmapI cell2 = idToIndex.find(id);
0497
0498 if (cell2 == idToIndex.end()) {
0499
0500
0501
0502 sumPartSolu0.push_back(1);
0503 sumPartSolu1.push_back(corr);
0504 sumPartSolu2.push_back(corr * corr);
0505 idToIndex.insert(IDmapIvalue(id, ++lastIndex));
0506 } else {
0507
0508
0509 int index = cell2->second;
0510 sumPartSolu0[index] += 1;
0511 sumPartSolu1[index] += corr;
0512 sumPartSolu2[index] += corr * corr;
0513 }
0514 }
0515 }
0516
0517
0518
0519 template <class IDdet>
0520 float MinL3AlgoUnivErr<IDdet>::getError(IDdet id) const
0521
0522 {
0523 float error;
0524 citer_IDmapI cell = idToIndex.find(id);
0525 if (cell == idToIndex.end())
0526 error = -2.;
0527 else {
0528 int i = cell->second;
0529 int n = sumPartSolu0[i];
0530 if (n <= 1)
0531 error = -1.;
0532 else {
0533 float meanX = sumPartSolu1[i] / n;
0534 float meanX2 = sumPartSolu2[i] / n;
0535
0536 error = sqrt(fabs(meanX2 - meanX * meanX) / (n - 1.));
0537 }
0538 }
0539 return error;
0540 }
0541
0542
0543
0544 template <class IDdet>
0545 typename MinL3AlgoUnivErr<IDdet>::IDmapF MinL3AlgoUnivErr<IDdet>::getError() const
0546
0547 {
0548 IDmapF errors;
0549 float error;
0550
0551 for (citer_IDmapI cell = idToIndex.begin(); cell != idToIndex.end(); ++cell) {
0552 int i = cell->second;
0553 int n = sumPartSolu0[i];
0554 if (n <= 1)
0555 error = -1.;
0556 else {
0557 float meanX = sumPartSolu1[i] / n;
0558 float meanX2 = sumPartSolu2[i] / n;
0559
0560 error = sqrt(fabs(meanX2 - meanX * meanX) / (n - 1));
0561 }
0562
0563 errors.insert(IDmapFvalue(cell->first, error));
0564 }
0565 return errors;
0566 }
0567
0568
0569 template <class IDdet>
0570 float MinL3AlgoUnivErr<IDdet>::getErrorQuality(IDdet id) const
0571
0572 {
0573 float fraction;
0574 citer_IDmapI cell = idToIndex.find(id);
0575 if (cell == idToIndex.end())
0576 fraction = -1.;
0577
0578 else {
0579 int i = cell->second;
0580 int n = sumPartSolu0[i];
0581 if (n < nOfSubsamples)
0582 fraction = float(n) / nOfSubsamples;
0583 else
0584 fraction = 1.;
0585 }
0586 return fraction;
0587 }
0588
0589
0590
0591 template <class IDdet>
0592 typename MinL3AlgoUnivErr<IDdet>::IDmapF MinL3AlgoUnivErr<IDdet>::getErrorQuality() const
0593
0594 {
0595 IDmapF fractions;
0596 float fraction;
0597
0598 for (citer_IDmapI cell = idToIndex.begin(); cell != idToIndex.end(); ++cell) {
0599 int i = cell->second;
0600 int n = sumPartSolu0[i];
0601
0602 if (n < nOfSubsamples)
0603 fraction = float(n) / nOfSubsamples;
0604 else
0605 fraction = 1.;
0606
0607 fractions.insert(IDmapFvalue(cell->first, fraction));
0608 }
0609
0610 return fractions;
0611 }
0612
0613
0614
0615 template <class IDdet>
0616 int MinL3AlgoUnivErr<IDdet>::numberOfWrongErrors() const
0617
0618 {
0619 int nWrong = 0;
0620
0621 for (citer_IDmapI cell = idToIndex.begin(); cell != idToIndex.end(); ++cell) {
0622 int i = cell->second;
0623 int n = sumPartSolu0[i];
0624
0625 if (n < nOfSubsamples)
0626 nWrong++;
0627 }
0628
0629 return nWrong;
0630 }
0631
0632
0633
0634 template <class IDdet>
0635 float MinL3AlgoUnivErr<IDdet>::getMeanPartialSolution(IDdet id) const
0636
0637 {
0638 float meanX;
0639 citer_IDmapI cell = idToIndex.find(id);
0640 if (cell == idToIndex.end())
0641 meanX = 999.;
0642 else {
0643 int i = cell->second;
0644 int n = sumPartSolu0[i];
0645 meanX = sumPartSolu1[i] / n;
0646 }
0647 return meanX;
0648 }
0649
0650
0651
0652 template <class IDdet>
0653 typename MinL3AlgoUnivErr<IDdet>::IDmapF MinL3AlgoUnivErr<IDdet>::getMeanPartialSolution() const
0654
0655 {
0656 IDmapF solution;
0657
0658 for (citer_IDmapI cell = idToIndex.begin(); cell != idToIndex.end(); ++cell) {
0659 int i = cell->second;
0660 int n = sumPartSolu0[i];
0661 float meanX = sumPartSolu1[i] / n;
0662 solution.insert(IDmapFvalue(cell->first, meanX));
0663 }
0664 return solution;
0665 }
0666
0667
0668
0669 #endif