00001 #include "TopQuarkAnalysis/TopKinFitter/interface/CovarianceMatrix.h"
00002
00003 #include "CommonTools/Utils/interface/StringObjectFunction.h"
00004 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
00005
00006 CovarianceMatrix::CovarianceMatrix(const std::vector<edm::ParameterSet> udscResolutions, const std::vector<edm::ParameterSet> bResolutions,
00007 const std::vector<double> jetEnergyResolutionScaleFactors, const std::vector<double> jetEnergyResolutionEtaBinning):
00008 jetEnergyResolutionScaleFactors_(jetEnergyResolutionScaleFactors), jetEnergyResolutionEtaBinning_(jetEnergyResolutionEtaBinning)
00009 {
00010 for(std::vector<edm::ParameterSet>::const_iterator iSet = udscResolutions.begin(); iSet != udscResolutions.end(); ++iSet){
00011 if(iSet->exists("bin")) binsUdsc_.push_back(iSet->getParameter<std::string>("bin"));
00012 else if(udscResolutions.size()==1) binsUdsc_.push_back("");
00013 else throw cms::Exception("Configuration") << "Parameter 'bin' is needed if more than one PSet is specified!\n";
00014
00015 funcEtUdsc_.push_back(iSet->getParameter<std::string>("et"));
00016 funcEtaUdsc_.push_back(iSet->getParameter<std::string>("eta"));
00017 funcPhiUdsc_.push_back(iSet->getParameter<std::string>("phi"));
00018 }
00019 for(std::vector<edm::ParameterSet>::const_iterator iSet = bResolutions.begin(); iSet != bResolutions.end(); ++iSet){
00020 if(iSet->exists("bin")) binsB_.push_back(iSet->getParameter<std::string>("bin"));
00021 else if(bResolutions.size()==1) binsB_.push_back("");
00022 else throw cms::Exception("Configuration") << "Parameter 'bin' is needed if more than one PSet is specified!\n";
00023
00024 funcEtB_.push_back(iSet->getParameter<std::string>("et"));
00025 funcEtaB_.push_back(iSet->getParameter<std::string>("eta"));
00026 funcPhiB_.push_back(iSet->getParameter<std::string>("phi"));
00027 }
00028 }
00029
00030 CovarianceMatrix::CovarianceMatrix(const std::vector<edm::ParameterSet> udscResolutions, const std::vector<edm::ParameterSet> bResolutions,
00031 const std::vector<edm::ParameterSet> lepResolutions, const std::vector<edm::ParameterSet> metResolutions,
00032 const std::vector<double> jetEnergyResolutionScaleFactors, const std::vector<double> jetEnergyResolutionEtaBinning):
00033 jetEnergyResolutionScaleFactors_(jetEnergyResolutionScaleFactors), jetEnergyResolutionEtaBinning_(jetEnergyResolutionEtaBinning)
00034 {
00035 if(jetEnergyResolutionScaleFactors_.size()+1!=jetEnergyResolutionEtaBinning_.size())
00036 throw cms::Exception("Configuration") << "The number of scale factors does not fit to the number of eta bins!\n";
00037 for(unsigned int i=0; i<jetEnergyResolutionEtaBinning_.size(); i++)
00038 if(jetEnergyResolutionEtaBinning_[i]<0. && i<jetEnergyResolutionEtaBinning_.size()-1)
00039 throw cms::Exception("Configuration") << "eta binning in absolut values required!\n";
00040
00041 for(std::vector<edm::ParameterSet>::const_iterator iSet = udscResolutions.begin(); iSet != udscResolutions.end(); ++iSet){
00042 if(iSet->exists("bin")) binsUdsc_.push_back(iSet->getParameter<std::string>("bin"));
00043 else if(udscResolutions.size()==1) binsUdsc_.push_back("");
00044 else throw cms::Exception("Configuration") << "Parameter 'bin' is needed if more than one PSet is specified!\n";
00045
00046 funcEtUdsc_.push_back(iSet->getParameter<std::string>("et"));
00047 funcEtaUdsc_.push_back(iSet->getParameter<std::string>("eta"));
00048 funcPhiUdsc_.push_back(iSet->getParameter<std::string>("phi"));
00049 }
00050 for(std::vector<edm::ParameterSet>::const_iterator iSet = bResolutions.begin(); iSet != bResolutions.end(); ++iSet){
00051 if(iSet->exists("bin")) binsB_.push_back(iSet->getParameter<std::string>("bin"));
00052 else if(bResolutions.size()==1) binsB_.push_back("");
00053 else throw cms::Exception("Configuration") << "Parameter 'bin' is needed if more than one PSet is specified!\n";
00054
00055 funcEtB_.push_back(iSet->getParameter<std::string>("et"));
00056 funcEtaB_.push_back(iSet->getParameter<std::string>("eta"));
00057 funcPhiB_.push_back(iSet->getParameter<std::string>("phi"));
00058 }
00059 for(std::vector<edm::ParameterSet>::const_iterator iSet = lepResolutions.begin(); iSet != lepResolutions.end(); ++iSet){
00060 if(iSet->exists("bin")) binsLep_.push_back(iSet->getParameter<std::string>("bin"));
00061 else if(lepResolutions.size()==1) binsLep_.push_back("");
00062 else throw cms::Exception("Configuration") << "Parameter 'bin' is needed if more than one PSet is specified!\n";
00063
00064 funcEtLep_.push_back(iSet->getParameter<std::string>("et"));
00065 funcEtaLep_.push_back(iSet->getParameter<std::string>("eta"));
00066 funcPhiLep_.push_back(iSet->getParameter<std::string>("phi"));
00067 }
00068 for(std::vector<edm::ParameterSet>::const_iterator iSet = metResolutions.begin(); iSet != metResolutions.end(); ++iSet){
00069 if(iSet->exists("bin")) binsMet_.push_back(iSet->getParameter<std::string>("bin"));
00070 else if(metResolutions.size()==1) binsMet_.push_back("");
00071 else throw cms::Exception("Configuration") << "Parameter 'bin' is needed if more than one PSet is specified!\n";
00072
00073 funcEtMet_.push_back(iSet->getParameter<std::string>("et"));
00074 funcEtaMet_.push_back(iSet->getParameter<std::string>("eta"));
00075 funcPhiMet_.push_back(iSet->getParameter<std::string>("phi"));
00076 }
00077 }
00078
00079 double CovarianceMatrix::getResolution(const TLorentzVector& object, const ObjectType objType, const std::string& whichResolution)
00080 {
00081 std::vector<std::string> * bins_, * funcEt_, * funcEta_, * funcPhi_;
00082
00083 switch(objType) {
00084 case kUdscJet:
00085 bins_ = &binsUdsc_;
00086 funcEt_ = &funcEtUdsc_;
00087 funcEta_ = &funcEtaUdsc_;
00088 funcPhi_ = &funcPhiUdsc_;
00089 break;
00090 case kBJet:
00091 bins_ = &binsB_;
00092 funcEt_ = &funcEtB_;
00093 funcEta_ = &funcEtaB_;
00094 funcPhi_ = &funcPhiB_;
00095 break;
00096 case kMuon:
00097 bins_ = &binsLep_;
00098 funcEt_ = &funcEtLep_;
00099 funcEta_ = &funcEtaLep_;
00100 funcPhi_ = &funcPhiLep_;
00101 break;
00102 case kElectron:
00103 bins_ = &binsLep_;
00104 funcEt_ = &funcEtLep_;
00105 funcEta_ = &funcEtaLep_;
00106 funcPhi_ = &funcPhiLep_;
00107 break;
00108 case kMet:
00109 bins_ = &binsMet_;
00110 funcEt_ = &funcEtMet_;
00111 funcEta_ = &funcEtaMet_;
00112 funcPhi_ = &funcPhiMet_;
00113 break;
00114 default:
00115 throw cms::Exception("UnsupportedObject") << "The object given is not supported!\n";
00116 }
00117
00118 int selectedBin=-1;
00119 reco::LeafCandidate candidate;
00120 for(unsigned int i=0; i<bins_->size(); ++i){
00121 StringCutObjectSelector<reco::LeafCandidate> select_(bins_->at(i));
00122 candidate = reco::LeafCandidate( 0, reco::LeafCandidate::LorentzVector(object.Px(), object.Py(), object.Pz(), object.Energy()) );
00123 if(select_(candidate)){
00124 selectedBin = i;
00125 break;
00126 }
00127 }
00128 double res = 0;
00129 if(selectedBin>=0){
00130 if(whichResolution == "et") res = StringObjectFunction<reco::LeafCandidate>(funcEt_ ->at(selectedBin)).operator()(candidate);
00131 else if(whichResolution == "eta") res = StringObjectFunction<reco::LeafCandidate>(funcEta_->at(selectedBin)).operator()(candidate);
00132 else if(whichResolution == "phi") res = StringObjectFunction<reco::LeafCandidate>(funcPhi_->at(selectedBin)).operator()(candidate);
00133 else throw cms::Exception("ProgrammingError") << "Only 'et', 'eta' and 'phi' resolutions supported!\n";
00134 }
00135 return res;
00136 }
00137
00138 TMatrixD CovarianceMatrix::setupMatrix(const TLorentzVector& object, const ObjectType objType, const TopKinFitter::Param param)
00139 {
00140 TMatrixD CovM3 (3,3); CovM3.Zero();
00141 TMatrixD CovM4 (4,4); CovM4.Zero();
00142 const double pt = object.Pt();
00143 const double eta = object.Eta();
00144 switch(objType) {
00145 case kUdscJet:
00146
00147 {
00148 res::HelperJet jetRes;
00149 switch(param) {
00150 case TopKinFitter::kEMom :
00151 CovM4(0,0) = pow(jetRes.a (pt, eta, res::HelperJet::kUds), 2);
00152 CovM4(1,1) = pow(jetRes.b (pt, eta, res::HelperJet::kUds), 2);
00153 CovM4(2,2) = pow(jetRes.c (pt, eta, res::HelperJet::kUds), 2);
00154 CovM4(3,3) = pow(jetRes.d (pt, eta, res::HelperJet::kUds), 2);
00155 return CovM4;
00156 case TopKinFitter::kEtEtaPhi :
00157 if(!binsUdsc_.size()){
00158 CovM3(0,0) = pow(jetRes.et (pt, eta, res::HelperJet::kUds), 2);
00159 CovM3(0,0)*= pow(getEtaDependentScaleFactor(object) , 2);
00160 CovM3(1,1) = pow(jetRes.eta(pt, eta, res::HelperJet::kUds), 2);
00161 CovM3(2,2) = pow(jetRes.phi(pt, eta, res::HelperJet::kUds), 2);
00162 }
00163 else{
00164 CovM3(0,0) = pow(getResolution(object, objType, "et") , 2);
00165 CovM3(0,0)*= pow(getEtaDependentScaleFactor(object) , 2);
00166 CovM3(1,1) = pow(getResolution(object, objType, "eta"), 2);
00167 CovM3(2,2) = pow(getResolution(object, objType, "phi"), 2);
00168 }
00169 return CovM3;
00170 case TopKinFitter::kEtThetaPhi :
00171 CovM3(0,0) = pow(jetRes.et (pt, eta, res::HelperJet::kUds), 2);
00172 CovM3(0,0)*= pow(getEtaDependentScaleFactor(object) , 2);
00173 CovM3(1,1) = pow(jetRes.theta(pt, eta, res::HelperJet::kUds), 2);
00174 CovM3(2,2) = pow(jetRes.phi (pt, eta, res::HelperJet::kUds), 2);
00175 return CovM3;
00176 }
00177 }
00178 break;
00179 case kBJet:
00180
00181 {
00182 res::HelperJet jetRes;
00183 switch(param) {
00184 case TopKinFitter::kEMom :
00185 CovM4(0,0) = pow(jetRes.a (pt, eta, res::HelperJet::kB), 2);
00186 CovM4(1,1) = pow(jetRes.b (pt, eta, res::HelperJet::kB), 2);
00187 CovM4(2,2) = pow(jetRes.c (pt, eta, res::HelperJet::kB), 2);
00188 CovM4(3,3) = pow(jetRes.d (pt, eta, res::HelperJet::kB), 2);
00189 return CovM4;
00190 case TopKinFitter::kEtEtaPhi :
00191 if(!binsUdsc_.size()){
00192 CovM3(0,0) = pow(jetRes.et (pt, eta, res::HelperJet::kB), 2);
00193 CovM3(0,0)*= pow(getEtaDependentScaleFactor(object) , 2);
00194 CovM3(1,1) = pow(jetRes.eta(pt, eta, res::HelperJet::kB), 2);
00195 CovM3(2,2) = pow(jetRes.phi(pt, eta, res::HelperJet::kB), 2);
00196 }
00197 else{
00198 CovM3(0,0) = pow(getResolution(object, objType, "et") , 2);
00199 CovM3(0,0)*= pow(getEtaDependentScaleFactor(object) , 2);
00200 CovM3(1,1) = pow(getResolution(object, objType, "eta"), 2);
00201 CovM3(2,2) = pow(getResolution(object, objType, "phi"), 2);
00202 }
00203 return CovM3;
00204 case TopKinFitter::kEtThetaPhi :
00205 CovM3(0,0) = pow(jetRes.et (pt, eta, res::HelperJet::kB), 2);
00206 CovM3(0,0)*= pow(getEtaDependentScaleFactor(object) , 2);
00207 CovM3(1,1) = pow(jetRes.theta(pt, eta, res::HelperJet::kB), 2);
00208 CovM3(2,2) = pow(jetRes.phi (pt, eta, res::HelperJet::kB), 2);
00209 return CovM3;
00210 }
00211 }
00212 break;
00213 case kMuon:
00214
00215 {
00216 res::HelperMuon muonRes;
00217 switch(param){
00218 case TopKinFitter::kEMom :
00219 CovM3(0,0) = pow(muonRes.a (pt, eta), 2);
00220 CovM3(1,1) = pow(muonRes.b (pt, eta), 2);
00221 CovM3(2,2) = pow(muonRes.c (pt, eta), 2);
00222 return CovM3;
00223 case TopKinFitter::kEtEtaPhi :
00224 if(!binsLep_.size()){
00225 CovM3(0,0) = pow(muonRes.et (pt, eta), 2);
00226 CovM3(1,1) = pow(muonRes.eta(pt, eta), 2);
00227 CovM3(2,2) = pow(muonRes.phi(pt, eta), 2);
00228 }
00229 else{
00230 CovM3(0,0) = pow(getResolution(object, objType, "et") , 2);
00231 CovM3(1,1) = pow(getResolution(object, objType, "eta"), 2);
00232 CovM3(2,2) = pow(getResolution(object, objType, "phi"), 2);
00233 }
00234 return CovM3;
00235 case TopKinFitter::kEtThetaPhi :
00236 CovM3(0,0) = pow(muonRes.et (pt, eta), 2);
00237 CovM3(1,1) = pow(muonRes.theta(pt, eta), 2);
00238 CovM3(2,2) = pow(muonRes.phi (pt, eta), 2);
00239 return CovM3;
00240 }
00241 }
00242 break;
00243 case kElectron:
00244 {
00245
00246 res::HelperElectron elecRes;
00247 switch(param){
00248 case TopKinFitter::kEMom :
00249 CovM3(0,0) = pow(elecRes.a (pt, eta), 2);
00250 CovM3(1,1) = pow(elecRes.b (pt, eta), 2);
00251 CovM3(2,2) = pow(elecRes.c (pt, eta), 2);
00252 return CovM3;
00253 case TopKinFitter::kEtEtaPhi :
00254 if(!binsLep_.size()){
00255 CovM3(0,0) = pow(elecRes.et (pt, eta), 2);
00256 CovM3(1,1) = pow(elecRes.eta(pt, eta), 2);
00257 CovM3(2,2) = pow(elecRes.phi(pt, eta), 2);
00258 }
00259 else{
00260 CovM3(0,0) = pow(getResolution(object, objType, "et") , 2);
00261 CovM3(1,1) = pow(getResolution(object, objType, "eta"), 2);
00262 CovM3(2,2) = pow(getResolution(object, objType, "phi"), 2);
00263 }
00264 return CovM3;
00265 case TopKinFitter::kEtThetaPhi :
00266 CovM3(0,0) = pow(elecRes.et (pt, eta), 2);
00267 CovM3(1,1) = pow(elecRes.theta(pt, eta), 2);
00268 CovM3(2,2) = pow(elecRes.phi (pt, eta), 2);
00269 return CovM3;
00270 }
00271 }
00272 break;
00273 case kMet:
00274
00275 {
00276 res::HelperMET metRes;
00277 switch(param){
00278 case TopKinFitter::kEMom :
00279 CovM3(0,0) = pow(metRes.a(pt), 2);
00280 CovM3(1,1) = pow(metRes.b(pt), 2);
00281 CovM3(2,2) = pow(metRes.c(pt), 2);
00282 return CovM3;
00283 case TopKinFitter::kEtEtaPhi :
00284 if(!binsMet_.size()){
00285 CovM3(0,0) = pow(metRes.et(pt) , 2);
00286 CovM3(1,1) = pow( 9999. , 2);
00287 CovM3(2,2) = pow(metRes.phi(pt), 2);
00288 }
00289 else{
00290 CovM3(0,0) = pow(getResolution(object, objType, "et") , 2);
00291 CovM3(1,1) = pow(getResolution(object, objType, "eta"), 2);
00292 CovM3(2,2) = pow(getResolution(object, objType, "phi"), 2);
00293 }
00294 return CovM3;
00295 case TopKinFitter::kEtThetaPhi :
00296 CovM3(0,0) = pow(metRes.et(pt) , 2);
00297 CovM3(1,1) = pow( 9999. , 2);
00298 CovM3(2,2) = pow(metRes.phi(pt), 2);
00299 return CovM3;
00300 }
00301 }
00302 break;
00303 }
00304 cms::Exception("Logic") << "Something went wrong while trying to setup a covariance matrix!\n";
00305 return CovM4;
00306 }
00307
00308 double CovarianceMatrix::getEtaDependentScaleFactor(const TLorentzVector& object)
00309 {
00310 double etaDependentScaleFactor = 1.;
00311 for(unsigned int i=0; i<jetEnergyResolutionEtaBinning_.size(); i++){
00312 if(std::abs(object.Eta())>=jetEnergyResolutionEtaBinning_[i] && jetEnergyResolutionEtaBinning_[i]>=0.){
00313 if(i==jetEnergyResolutionEtaBinning_.size()-1) {
00314 edm::LogWarning("CovarianceMatrix") << "object eta ("<<std::abs(object.Eta())<<") beyond last eta bin ("<<jetEnergyResolutionEtaBinning_[i]<<") using scale factor 1.0!";
00315 etaDependentScaleFactor=1.;
00316 break;
00317 }
00318 etaDependentScaleFactor=jetEnergyResolutionScaleFactors_[i];
00319 }
00320 else
00321 break;
00322 }
00323 return etaDependentScaleFactor;
00324 }