File indexing completed on 2024-04-06 12:04:57
0001 #include <iomanip>
0002 #include <sstream>
0003 #include <iostream>
0004 #include <algorithm>
0005
0006 #include "FWCore/Utilities/interface/EDMException.h"
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008 #include "DataFormats/PatCandidates/interface/JetCorrFactors.h"
0009
0010 using namespace pat;
0011
0012 JetCorrFactors::JetCorrFactors(const std::string& label, const std::vector<CorrectionFactor>& jec)
0013 : label_(label), jec_(jec) {
0014 for (std::vector<CorrectionFactor>::const_iterator corrFactor = jec.begin(); corrFactor != jec.end(); ++corrFactor) {
0015 if (!isValid(*corrFactor))
0016 invalidFactor();
0017 }
0018 }
0019
0020 void JetCorrFactors::insertFactor(const unsigned int& position, const CorrectionFactor& corrFactor) {
0021 if (!isValid(corrFactor))
0022 invalidFactor();
0023 jec_.insert(jec_.begin() + position, corrFactor);
0024 }
0025
0026 std::string JetCorrFactors::jecFlavor(const Flavor& flavor) const {
0027 std::map<Flavor, std::string> flavors;
0028 flavors[UDS] = "uds";
0029 flavors[CHARM] = "charm";
0030 flavors[BOTTOM] = "bottom";
0031 flavors[GLUON] = "gluon";
0032 flavors[NONE] = "none";
0033 return flavors.find(flavor)->second;
0034 }
0035
0036 JetCorrFactors::Flavor JetCorrFactors::jecFlavor(std::string flavor) const {
0037 std::map<std::string, Flavor> flavors;
0038 std::transform(flavor.begin(), flavor.end(), flavor.begin(), [&](int c) { return std::tolower(c); });
0039 flavors["uds"] = UDS;
0040 flavors["charm"] = CHARM;
0041 flavors["bottom"] = BOTTOM;
0042 flavors["gluon"] = GLUON;
0043 flavors["none"] = NONE;
0044 if (flavors.find(flavor) == flavors.end()) {
0045 throw cms::Exception("InvalidRequest") << "You ask for a flavor, which does not exist. Available flavors are: \n"
0046 << "'uds', 'charm', 'bottom', 'gluon', 'none', (not case sensitive). \n";
0047 }
0048 return flavors.find(flavor)->second;
0049 }
0050
0051 int JetCorrFactors::jecLevel(const std::string& level) const {
0052 for (std::vector<CorrectionFactor>::const_iterator corrFactor = jec_.begin(); corrFactor != jec_.end();
0053 ++corrFactor) {
0054 if (corrFactor->first == level)
0055 return (corrFactor - jec_.begin());
0056 }
0057 return -1;
0058 }
0059
0060 float JetCorrFactors::correction(unsigned int level, Flavor flavor) const {
0061 if (!(level < jec_.size())) {
0062 throw cms::Exception("InvalidRequest") << "You try to call a jet energy correction level wich does not exist. \n"
0063 << "Available jet energy correction levels are: \n"
0064 << correctionLabelString();
0065 }
0066 if (flavorDependent(jec_.at(level)) && flavor == NONE) {
0067 throw cms::Exception("InvalidRequest") << "You try to call a flavor dependent jet energy correction level: \n"
0068 << "level : " << level << " label: " << jec_.at(level).first << " \n"
0069 << "You need to specify one of the following flavors: GLUON, UDS, \n"
0070 << "CHARM, BOTTOM. \n";
0071 }
0072 return flavorDependent(jec_.at(level)) ? jec_.at(level).second.at(flavor) : jec_.at(level).second.at(0);
0073 }
0074
0075 std::string JetCorrFactors::correctionLabelString() const {
0076 std::string labels;
0077 for (std::vector<CorrectionFactor>::const_iterator corrFactor = jec_.begin(); corrFactor != jec_.end();
0078 ++corrFactor) {
0079 std::stringstream idx;
0080 idx << (corrFactor - jec_.begin());
0081 labels.append(idx.str()).append(" ").append(corrFactor->first).append("\n");
0082 }
0083 return labels;
0084 }
0085
0086 std::vector<std::string> JetCorrFactors::correctionLabels() const {
0087 std::vector<std::string> labels;
0088 for (std::vector<CorrectionFactor>::const_iterator corrFactor = jec_.begin(); corrFactor != jec_.end();
0089 ++corrFactor) {
0090 labels.push_back(corrFactor->first);
0091 }
0092 return labels;
0093 }
0094
0095 void JetCorrFactors::print() const {
0096 edm::LogInfo message("JetCorrFactors");
0097 for (std::vector<CorrectionFactor>::const_iterator corrFactor = jec_.begin(); corrFactor != jec_.end();
0098 ++corrFactor) {
0099 unsigned int corrFactorIdx = corrFactor - jec_.begin();
0100 message << std::setw(3) << corrFactorIdx << " " << corrFactor->first;
0101 if (flavorDependent(*corrFactor)) {
0102 for (std::vector<float>::const_iterator flavor = corrFactor->second.begin(); flavor != corrFactor->second.end();
0103 ++flavor) {
0104 unsigned int flavorIdx = flavor - corrFactor->second.begin();
0105 message << std::setw(10) << correction(corrFactorIdx, (Flavor)flavorIdx);
0106 }
0107 } else {
0108 message << std::setw(10) << correction(corrFactor - jec_.begin(), NONE);
0109 }
0110 message << "\n";
0111 }
0112 }
0113
0114 void JetCorrFactors::invalidFactor() const {
0115 throw cms::Exception("InvalidRequest")
0116 << "You try to create a CorrectionFactor which is neither flavor dependent nor \n"
0117 << "flavor independent. The CorrectionFactor should obey the following rules: \n"
0118 << "\n"
0119 << " * CorrectionFactor is a std::pair<std::string, std::vector<float> >. \n"
0120 << " * The std::string holds the label of the correction level (following the \n"
0121 << " conventions of JetMET. \n"
0122 << " * The std::vector<float> holds the correction factors, these factors are \n"
0123 << " up to the given level. They include all previous correction steps. \n"
0124 << " * The vector has the length *1* for flavor independent correction factors \n"
0125 << " or *5* for flavor dependent correction factors. \n"
0126 << " * The expected order of flavor dependent correction factors is: NONE, \n"
0127 << " GLUON, UDS, CHARM, BOTTOM. If follows the JetMET conventions and is \n"
0128 << " in the Flavor enumerator of the JetCorrFactos class. \n"
0129 << " * For flavor depdendent correction factors the first entry in the vector \n"
0130 << " (corresponding to NONE) is invalid and should be set to -1. It will not \n"
0131 << " be considered by the class structure though. \n"
0132 << "\n"
0133 << "Make sure that all elements of the argument vector to this contructor are \n"
0134 << "in accordance with these rules.\n";
0135 }