1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
#include <iomanip>
#include <sstream>
#include <iostream>
#include <algorithm>
#include "FWCore/Utilities/interface/EDMException.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "DataFormats/PatCandidates/interface/JetCorrFactors.h"
using namespace pat;
JetCorrFactors::JetCorrFactors(const std::string& label, const std::vector<CorrectionFactor>& jec)
: label_(label), jec_(jec) {
for (std::vector<CorrectionFactor>::const_iterator corrFactor = jec.begin(); corrFactor != jec.end(); ++corrFactor) {
if (!isValid(*corrFactor))
invalidFactor();
}
}
void JetCorrFactors::insertFactor(const unsigned int& position, const CorrectionFactor& corrFactor) {
if (!isValid(corrFactor))
invalidFactor();
jec_.insert(jec_.begin() + position, corrFactor);
}
std::string JetCorrFactors::jecFlavor(const Flavor& flavor) const {
std::map<Flavor, std::string> flavors;
flavors[UDS] = "uds";
flavors[CHARM] = "charm";
flavors[BOTTOM] = "bottom";
flavors[GLUON] = "gluon";
flavors[NONE] = "none";
return flavors.find(flavor)->second;
}
JetCorrFactors::Flavor JetCorrFactors::jecFlavor(std::string flavor) const {
std::map<std::string, Flavor> flavors;
std::transform(flavor.begin(), flavor.end(), flavor.begin(), [&](int c) { return std::tolower(c); });
flavors["uds"] = UDS;
flavors["charm"] = CHARM;
flavors["bottom"] = BOTTOM;
flavors["gluon"] = GLUON;
flavors["none"] = NONE;
if (flavors.find(flavor) == flavors.end()) {
throw cms::Exception("InvalidRequest") << "You ask for a flavor, which does not exist. Available flavors are: \n"
<< "'uds', 'charm', 'bottom', 'gluon', 'none', (not case sensitive). \n";
}
return flavors.find(flavor)->second;
}
int JetCorrFactors::jecLevel(const std::string& level) const {
for (std::vector<CorrectionFactor>::const_iterator corrFactor = jec_.begin(); corrFactor != jec_.end();
++corrFactor) {
if (corrFactor->first == level)
return (corrFactor - jec_.begin());
}
return -1;
}
float JetCorrFactors::correction(unsigned int level, Flavor flavor) const {
if (!(level < jec_.size())) {
throw cms::Exception("InvalidRequest") << "You try to call a jet energy correction level wich does not exist. \n"
<< "Available jet energy correction levels are: \n"
<< correctionLabelString();
}
if (flavorDependent(jec_.at(level)) && flavor == NONE) {
throw cms::Exception("InvalidRequest") << "You try to call a flavor dependent jet energy correction level: \n"
<< "level : " << level << " label: " << jec_.at(level).first << " \n"
<< "You need to specify one of the following flavors: GLUON, UDS, \n"
<< "CHARM, BOTTOM. \n";
}
return flavorDependent(jec_.at(level)) ? jec_.at(level).second.at(flavor) : jec_.at(level).second.at(0);
}
std::string JetCorrFactors::correctionLabelString() const {
std::string labels;
for (std::vector<CorrectionFactor>::const_iterator corrFactor = jec_.begin(); corrFactor != jec_.end();
++corrFactor) {
std::stringstream idx;
idx << (corrFactor - jec_.begin());
labels.append(idx.str()).append(" ").append(corrFactor->first).append("\n");
}
return labels;
}
std::vector<std::string> JetCorrFactors::correctionLabels() const {
std::vector<std::string> labels;
for (std::vector<CorrectionFactor>::const_iterator corrFactor = jec_.begin(); corrFactor != jec_.end();
++corrFactor) {
labels.push_back(corrFactor->first);
}
return labels;
}
void JetCorrFactors::print() const {
edm::LogInfo message("JetCorrFactors");
for (std::vector<CorrectionFactor>::const_iterator corrFactor = jec_.begin(); corrFactor != jec_.end();
++corrFactor) {
unsigned int corrFactorIdx = corrFactor - jec_.begin();
message << std::setw(3) << corrFactorIdx << " " << corrFactor->first;
if (flavorDependent(*corrFactor)) {
for (std::vector<float>::const_iterator flavor = corrFactor->second.begin(); flavor != corrFactor->second.end();
++flavor) {
unsigned int flavorIdx = flavor - corrFactor->second.begin();
message << std::setw(10) << correction(corrFactorIdx, (Flavor)flavorIdx);
}
} else {
message << std::setw(10) << correction(corrFactor - jec_.begin(), NONE);
}
message << "\n";
}
}
void JetCorrFactors::invalidFactor() const {
throw cms::Exception("InvalidRequest")
<< "You try to create a CorrectionFactor which is neither flavor dependent nor \n"
<< "flavor independent. The CorrectionFactor should obey the following rules: \n"
<< "\n"
<< " * CorrectionFactor is a std::pair<std::string, std::vector<float> >. \n"
<< " * The std::string holds the label of the correction level (following the \n"
<< " conventions of JetMET. \n"
<< " * The std::vector<float> holds the correction factors, these factors are \n"
<< " up to the given level. They include all previous correction steps. \n"
<< " * The vector has the length *1* for flavor independent correction factors \n"
<< " or *5* for flavor dependent correction factors. \n"
<< " * The expected order of flavor dependent correction factors is: NONE, \n"
<< " GLUON, UDS, CHARM, BOTTOM. If follows the JetMET conventions and is \n"
<< " in the Flavor enumerator of the JetCorrFactos class. \n"
<< " * For flavor depdendent correction factors the first entry in the vector \n"
<< " (corresponding to NONE) is invalid and should be set to -1. It will not \n"
<< " be considered by the class structure though. \n"
<< "\n"
<< "Make sure that all elements of the argument vector to this contructor are \n"
<< "in accordance with these rules.\n";
}
|