Go to the documentation of this file.00001 #include "RecoParticleFlow/PFClusterTools/interface/LinearCalibrator.h"
00002 #include <cassert>
00003 #include <cmath>
00004 #include "TVector.h"
00005 #include "TDecompLU.h"
00006 #include "TDecompSVD.h"
00007
00008 #include "TDecompBK.h"
00009
00010 #include <iostream>
00011
00012 using namespace pftools;
00013
00014
00015
00016
00017 void printMat(std::ostream& s, const TMatrixD& input) {
00018 s << "\t[";
00019 for (int i(0); i < input.GetNrows(); i++) {
00020 for (int j(0); j < input.GetNcols(); j++) {
00021 s << input[i][j]<< ", \t";
00022 }
00023 if (i != (input.GetNrows() - 1)) {
00024 s << ";\n";
00025 s << "\t";
00026 }
00027 }
00028 s << "\t]\n";
00029 }
00030
00031 void printVec(std::ostream& s, const TVectorD& input) {
00032 s << "\t[";
00033 for (int i(0); i < input.GetNrows(); i++) {
00034 s << input[i];
00035 if (i != (input.GetNrows() - 1)) {
00036 s << ",\n\t";
00037 }
00038 }
00039 s << "\t]\n";
00040 }
00041
00042 LinearCalibrator::LinearCalibrator() {
00043
00044 }
00045
00046 LinearCalibrator::~LinearCalibrator() {
00047 }
00048 LinearCalibrator* LinearCalibrator::clone() const {
00049 return new LinearCalibrator(*this);
00050 }
00051
00052 LinearCalibrator::LinearCalibrator(const LinearCalibrator& lc) {
00053 myDetectorElements = lc.myDetectorElements;
00054 myParticleDeposits = lc.myParticleDeposits;
00055 }
00056
00057 LinearCalibrator* LinearCalibrator::create() const {
00058 return new LinearCalibrator();
00059 }
00060
00061 std::map<DetectorElementPtr, double> LinearCalibrator::getCalibrationCoefficientsCore()
00062 throw(PFToolsException&) {
00063
00064
00065 if (!hasParticles()) {
00066
00067 PFToolsException me("Calibrator has no particles for calibration!");
00068 throw me;
00069 }
00070
00071 TMatrixD eij;
00072 TVectorD truthE;
00073 initEijMatrix(eij, truthE);
00074
00075
00076
00077
00078
00079 TVectorD proj;
00080 TMatrixD hess;
00081
00082 getProjections(eij, proj, truthE);
00083
00084
00085 getHessian(eij, hess, truthE);
00086
00087 TDecompLU lu;
00088 lu.SetMatrix(hess);
00089
00090
00091
00092 lu.SetTol(1e-25);
00093 TMatrixD hessInv = lu.Invert();
00094
00095
00096 TVectorD calibsSolved(eij.GetNcols());
00097
00098 bool ok(true);
00099 calibsSolved = lu.Solve(proj, ok);
00100 if (ok) {
00101
00102 }
00103 else {
00104 std::cout << "\tWARNING: LU reports NOT ok.\n";
00105
00106
00107
00108
00109
00110
00111 std::cout
00112 << "\tDid you forget to add a dummy offset deposition to each particle?\n";
00113 std::cout << "\tThrowing an exception!"<< std::endl;
00114 PFToolsException
00115 me("TDecompLU did not converge successfully when finding calibrations. Did you forget to add a dummy offset deposition to each particle?");
00116 throw me;
00117 }
00118
00119
00120
00121
00122 std::map<DetectorElementPtr, double> answers;
00123 for (std::map<DetectorElementPtr, unsigned>::iterator it =
00124 myDetElIndex.begin(); it != myDetElIndex.end(); ++it) {
00125 DetectorElementPtr de = (*it).first;
00126 answers[de] = calibsSolved[(*it).second];
00127 }
00128 return answers;
00129 }
00130
00131 void LinearCalibrator::initEijMatrix(TMatrixD& eij, TVectorD& truthE) {
00132
00133
00134 populateDetElIndex();
00135 eij.Clear();
00136 eij.Zero();
00137
00138 truthE.ResizeTo(myParticleDeposits.size());
00139 truthE.Zero();
00140
00141
00142
00143 eij.ResizeTo(myParticleDeposits.size(), myDetElIndex.size());
00144
00145
00146 unsigned index(0);
00147 for (std::vector<ParticleDepositPtr>::const_iterator cit =
00148 myParticleDeposits.begin(); cit != myParticleDeposits.end(); ++cit) {
00149 ParticleDepositPtr p = *cit;
00150
00151
00152 for (std::vector<DetectorElementPtr>::const_iterator detElIt =
00153 myDetectorElements.begin(); detElIt != myDetectorElements.end(); ++detElIt) {
00154 DetectorElementPtr de = *detElIt;
00155 eij[index][myDetElIndex[de]] = p->getRecEnergy(de);
00156
00157 }
00158 truthE[index] = p->getTruthEnergy();
00159 ++index;
00160 }
00161
00162 }
00163
00164 TVectorD& LinearCalibrator::getProjections(const TMatrixD& eij, TVectorD& proj,
00165 const TVectorD& truthE) const {
00166
00167 proj.ResizeTo(eij.GetNcols());
00168 proj.Zero();
00169
00170 for (int j(0); j < eij.GetNcols(); ++j) {
00171 for (int i(0); i < eij.GetNrows(); ++i) {
00172 proj[j] += eij[i][j] / truthE[i];
00173 }
00174 }
00175
00176 return proj;
00177 }
00178
00179 TMatrixD& LinearCalibrator::getHessian(const TMatrixD& eij, TMatrixD& hess,
00180 const TVectorD& truthE) const {
00181
00182 unsigned nCalibs(eij.GetNcols());
00183 hess.ResizeTo(nCalibs, nCalibs);
00184 hess.Zero();
00185
00186 for (unsigned i(0); i < nCalibs; ++i) {
00187 for (unsigned j(0); j < nCalibs; ++j) {
00188 for (int n(0); n < eij.GetNrows(); ++n) {
00189 hess[i][j] += eij[n][i] * eij[n][j]/ pow(truthE[n], 2.0);
00190 }
00191 }
00192 }
00193
00194 return hess;
00195 }
00196
00197 void LinearCalibrator::populateDetElIndex() {
00198
00199 unsigned index(0);
00200
00201 myDetElIndex.clear();
00202
00203 for (std::vector<DetectorElementPtr>::const_iterator cit =
00204 myDetectorElements.begin(); cit != myDetectorElements.end(); ++cit) {
00205 DetectorElementPtr de = *cit;
00206
00207
00208 if (myDetElIndex.count(de) == 0) {
00209 myDetElIndex[de] = index;
00210 ++index;
00211 }
00212 }
00213
00214 }
00215