00001
00002
00003
00004
00005 #include "DataFormats/PatCandidates/interface/Jet.h"
00006 #include "DataFormats/RecoCandidate/interface/RecoCaloTowerCandidate.h"
00007 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00008
00009 using namespace pat;
00010
00011
00013 Jet::Jet() :
00014 PATObject<JetType>(JetType()),
00015 embeddedCaloTowers_(false),
00016 partonFlavour_(0),
00017 jetCharge_(0.)
00018 {
00019 }
00020
00022 Jet::Jet(const JetType & aJet) :
00023 PATObject<JetType>(aJet),
00024 embeddedCaloTowers_(false),
00025 partonFlavour_(0),
00026 jetCharge_(0.0)
00027 {
00028 tryImportSpecific(aJet);
00029 }
00030
00032 Jet::Jet(const edm::Ptr<JetType> & aJetRef) :
00033 PATObject<JetType>(aJetRef),
00034 embeddedCaloTowers_(false),
00035 partonFlavour_(0),
00036 jetCharge_(0.0)
00037 {
00038 tryImportSpecific(*aJetRef);
00039 }
00040
00042 Jet::Jet(const edm::RefToBase<JetType> & aJetRef) :
00043 PATObject<JetType>(aJetRef),
00044 embeddedCaloTowers_(false),
00045 partonFlavour_(0),
00046 jetCharge_(0.0)
00047 {
00048 tryImportSpecific(*aJetRef);
00049 }
00050
00052 void Jet::tryImportSpecific(const JetType &source) {
00053 const std::type_info & type = typeid(source);
00054 if (type == typeid(reco::CaloJet)) {
00055 specificCalo_.push_back( (static_cast<const reco::CaloJet &>(source)).getSpecific() );
00056 } else if (type == typeid(reco::PFJet)) {
00057 specificPF_.push_back( (static_cast<const reco::PFJet &>(source)).getSpecific() );
00058 }
00059 }
00060
00062 Jet::~Jet() {
00063 }
00064
00066
00067 CaloTowerPtr Jet::getCaloConstituent (unsigned fIndex) const {
00068 if (embeddedCaloTowers_) {
00069 return (fIndex < caloTowers_.size() ? CaloTowerPtr(&caloTowers_, fIndex) : CaloTowerPtr());
00070 } else {
00071 Constituent dau = daughterPtr (fIndex);
00072 const CaloTower* towerCandidate = dynamic_cast <const CaloTower*> (dau.get());
00073 if (towerCandidate) {
00074 return edm::Ptr<CaloTower> (dau.id(), towerCandidate, dau.key() );
00075 }
00076 else {
00077 throw cms::Exception("Invalid Constituent") << "CaloJet constituent is not of CaloTowere type";
00078 }
00079
00080 }
00081
00082 return CaloTowerPtr ();
00083 }
00084
00085 std::vector<CaloTowerPtr> Jet::getCaloConstituents () const {
00086 std::vector<CaloTowerPtr> result;
00087 for (unsigned i = 0; i < numberOfDaughters (); i++) result.push_back (getCaloConstituent (i));
00088 return result;
00089 }
00090
00092
00093 const reco::PFCandidate* Jet::getPFCandidate (const reco::Candidate* fConstituent) {
00094 if (!fConstituent) return 0;
00095 const reco::Candidate* base = fConstituent;
00096 if (fConstituent->hasMasterClone ())
00097 base = fConstituent->masterClone().get();
00098 if (!base) return 0;
00099 const reco::PFCandidate* candidate = dynamic_cast <const reco::PFCandidate*> (base);
00100 if (!candidate) {
00101 throw cms::Exception("Invalid Constituent") << "Jet constituent is not of PFCandidate type."
00102 << "Actual type is " << typeid (*base).name();
00103 }
00104 return candidate;
00105 }
00106
00107 const reco::PFCandidate* Jet::getPFConstituent (unsigned fIndex) const {
00108 return getPFCandidate (daughter (fIndex));
00109 }
00110
00111 std::vector <const reco::PFCandidate*> Jet::getPFConstituents () const {
00112 std::vector <const reco::PFCandidate*> result;
00113 for (unsigned i = 0; i < numberOfDaughters (); i++) result.push_back (getPFConstituent (i));
00114 return result;
00115 }
00116
00118 const reco::GenJet * Jet::genJet() const {
00119 return (genJet_.size() > 0 ? &genJet_.front() : 0);
00120 }
00121
00123 int Jet::partonFlavour() const {
00124 return partonFlavour_;
00125 }
00126
00127 const std::vector<std::pair<std::string, float> > & Jet::getPairDiscri() const {
00128 return pairDiscriVector_;
00129 }
00130
00132 float Jet::bDiscriminator(const std::string & aLabel) const {
00133 float discriminator = -1000.;
00134 const std::string & theLabel = ((aLabel == "" || aLabel == "default")) ? "trackCountingHighEffBJetTags" : aLabel;
00135 for(unsigned int i=0; i!=pairDiscriVector_.size(); i++){
00136 if(pairDiscriVector_[i].first == theLabel){
00137 discriminator = pairDiscriVector_[i].second;
00138 }
00139 }
00140 return discriminator;
00141 }
00142
00143 const reco::BaseTagInfo * Jet::tagInfo(const std::string &label) const {
00144 std::vector<std::string>::const_iterator it = std::find(tagInfoLabels_.begin(), tagInfoLabels_.end(), label);
00145 if (it != tagInfoLabels_.end()) {
00146 return & tagInfos_[it - tagInfoLabels_.begin()];
00147 }
00148 return 0;
00149 }
00150 template<typename T>
00151 const T * Jet::tagInfoByType() const {
00152 for (size_t i = 0, n = tagInfos_.size(); i < n; ++i) {
00153 if ( typeid(tagInfos_[i]) == typeid(T) )
00154 return static_cast<const T *>(&tagInfos_[i]);
00155 }
00156 return 0;
00157 }
00158
00159 const reco::TrackIPTagInfo *
00160 Jet::tagInfoTrackIP(const std::string &label) const {
00161 return (label.empty() ? tagInfoByType<reco::TrackIPTagInfo>()
00162 : dynamic_cast<const reco::TrackIPTagInfo *>(tagInfo(label)) );
00163 }
00164
00165 const reco::SoftLeptonTagInfo *
00166 Jet::tagInfoSoftLepton(const std::string &label) const {
00167 return (label.empty() ? tagInfoByType<reco::SoftLeptonTagInfo>()
00168 : dynamic_cast<const reco::SoftLeptonTagInfo *>(tagInfo(label)) );
00169 }
00170
00171 const reco::SecondaryVertexTagInfo *
00172 Jet::tagInfoSecondaryVertex(const std::string &label) const {
00173 return (label.empty() ? tagInfoByType<reco::SecondaryVertexTagInfo>()
00174 : dynamic_cast<const reco::SecondaryVertexTagInfo *>(tagInfo(label)) );
00175 }
00176
00177 void
00178 Jet::addTagInfo(const std::string &label, const edm::Ptr<reco::BaseTagInfo> &info) {
00179 addTagInfo(label, *info);
00180 }
00181
00182 void
00183 Jet::addTagInfo(const std::string &label, const reco::BaseTagInfo &info) {
00184 std::string::size_type idx = label.find("TagInfos");
00185 if (idx == std::string::npos) {
00186 tagInfoLabels_.push_back(label);
00187 } else {
00188 tagInfoLabels_.push_back(label.substr(0,idx));
00189 }
00190 tagInfos_.push_back(info.clone());
00191 }
00192
00194 float Jet::jetCharge() const {
00195 return jetCharge_;
00196 }
00197
00199 const reco::TrackRefVector & Jet::associatedTracks() const {
00200 return associatedTracks_;
00201 }
00202
00204 void Jet::setAssociatedTracks(const reco::TrackRefVector &tracks) {
00205 associatedTracks_ = tracks;
00206 }
00207
00209 void Jet::setCaloTowers(const std::vector<CaloTowerPtr> & caloTowers) {
00210 for(unsigned int i = 0; i < caloTowers.size(); ++i) {
00211 caloTowers_.push_back(*caloTowers.at(i));
00212 }
00213
00214
00215
00216
00217 embeddedCaloTowers_ = true;
00218 }
00219
00221 void Jet::setGenJet(const reco::GenJet & gj) {
00222 genJet_.clear();
00223 genJet_.push_back(gj);
00224 }
00225
00227 void Jet::setPartonFlavour(int partonFl) {
00228 partonFlavour_ = partonFl;
00229 }
00230
00232 void Jet::setCorrFactors(const JetCorrFactors & jetCorrF) {
00233 jetEnergyCorrections_.clear();
00234 jetEnergyCorrections_.push_back(jetCorrF);
00235 activeJetCorrIndex_ = 0;
00236 }
00237
00239 void Jet::addCorrFactors(const JetCorrFactors & jetCorrF) {
00240 jetEnergyCorrections_.push_back(jetCorrF);
00241 }
00242
00244 void Jet::setCorrStep(JetCorrFactors::CorrStep step) {
00245 jetEnergyCorrectionStep_ = step;
00246 setP4(corrFactors_()->correction( step ) * p4());
00247 }
00248
00251 Jet Jet::correctedJet(const std::string &step, const std::string &flavour) const {
00252 Jet ret(*this);
00253 ret.setP4(p4() * corrFactors_()->correction(corrFactors_()->corrStep(step, flavour), jetEnergyCorrectionStep_));
00254 ret.jetEnergyCorrectionStep_ = corrFactors_()->corrStep(step, flavour);
00255 return ret;
00256 }
00257
00260 Jet Jet::correctedJet(const JetCorrFactors::CorrStep &step) const {
00261 Jet ret(*this);
00262 ret.setP4(p4() * corrFactors_()->correction(step, jetEnergyCorrectionStep_));
00263 ret.jetEnergyCorrectionStep_ = step;
00264 return ret;
00265 }
00266
00269 Jet Jet::correctedJet(const std::string &step, const std::string &flavour, const std::string &set) const {
00270 Jet ret(*this);
00271 const JetCorrFactors * jetCorrFac = corrFactors_(set);
00272 if (!jetCorrFac)
00273 throw cms::Exception("InvalidRequest")
00274 << "invalid JetCorrectionModule label '" << set
00275 << "' requested in Jet::correctedJet!";
00276 ret.setP4(p4() * jetCorrFac->correction(jetCorrFac->corrStep(step, flavour), jetEnergyCorrectionStep_));
00277 ret.jetEnergyCorrectionStep_ = jetCorrFac->corrStep(step, flavour);
00278 return ret;
00279 }
00280
00283 Jet Jet::correctedJet(const JetCorrFactors::CorrStep &step, const std::string &set) const {
00284 Jet ret(*this);
00285 const JetCorrFactors * jetCorrFac = corrFactors_(set);
00286 if (!jetCorrFac)
00287 throw cms::Exception("InvalidRequest")
00288 << "invalid JetCorrectionModule label '" << set
00289 << "' requested in Jet::correctedJet!";
00290 ret.setP4(p4() * jetCorrFac->correction(step, jetEnergyCorrectionStep_));
00291 ret.jetEnergyCorrectionStep_ = step;
00292 return ret;
00293 }
00294
00296 bool Jet::hasCorrFactorSet(const std::string &set) const
00297 {
00298 for (std::vector<pat::JetCorrFactors>::const_iterator it=jetEnergyCorrections_.begin();
00299 it!=jetEnergyCorrections_.end(); ++it)
00300 if (it->getLabel()==set)
00301 return true;
00302 return false;
00303 }
00304
00306 const JetCorrFactors * Jet::corrFactors_(const std::string &set) const
00307 {
00308 const JetCorrFactors * result = 0;
00309 for (std::vector<pat::JetCorrFactors>::const_iterator it=jetEnergyCorrections_.begin();
00310 it!=jetEnergyCorrections_.end(); ++it)
00311 if (it->getLabel()==set){
00312 result = &(*it);
00313 break;
00314 }
00315 return result;
00316 }
00317
00319 const JetCorrFactors * Jet::corrFactors_() const {
00320 return &jetEnergyCorrections_.at( activeJetCorrIndex_ );
00321 }
00322
00324 std::string Jet::corrStep() const {
00325 return corrFactors_()->corrStep( jetEnergyCorrectionStep_ );
00326 }
00327
00329 std::string Jet::corrFlavour() const {
00330 return corrFactors_()->flavour( jetEnergyCorrectionStep_ );
00331 }
00332
00335 float Jet::corrFactor(const std::string &step, const std::string &flavour) const {
00336 return corrFactors_()->correction(corrFactors_()->corrStep(step, flavour), jetEnergyCorrectionStep_);
00337 }
00338
00341 float Jet::corrFactor(const std::string &step, const std::string &flavour, const std::string &set) const {
00342 const JetCorrFactors * jetCorrFac = corrFactors_(set);
00343 if (!jetCorrFac)
00344 throw cms::Exception("InvalidRequest")
00345 << "invalid JetCorrectionModule label '" << set << "' requested in Jet::jetCorrFactor!"<<std::endl;;
00346 return jetCorrFac->correction(jetCorrFac->corrStep(step, flavour), jetEnergyCorrectionStep_);
00347 }
00348
00350 const std::vector<std::string> Jet::corrFactorSetLabels() const
00351 {
00352 std::vector<std::string> result;
00353 for (std::vector<pat::JetCorrFactors>::const_iterator it=jetEnergyCorrections_.begin();
00354 it!=jetEnergyCorrections_.end(); ++it)
00355 result.push_back(it->getLabel());
00356 return result;
00357 }
00358
00360 void Jet::addBDiscriminatorPair(const std::pair<std::string, float> & thePair) {
00361 pairDiscriVector_.push_back(thePair);
00362 }
00363
00365 void Jet::setJetCharge(float jetCharge) {
00366 jetCharge_ = jetCharge;
00367 }
00368