Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-05-12 01:51:30

0001 //
0002 // HLTFilter selecting events with a minimum number of tri-object candidates passing invariant-mass cuts
0003 //
0004 
0005 #include "DataFormats/Candidate/interface/Particle.h"
0006 #include "DataFormats/Common/interface/Handle.h"
0007 #include "DataFormats/Common/interface/Ref.h"
0008 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h"
0009 #include "DataFormats/RecoCandidate/interface/RecoEcalCandidate.h"
0010 #include "DataFormats/Math/interface/deltaR.h"
0011 #include "FWCore/Framework/interface/MakerMacros.h"
0012 #include "FWCore/Utilities/interface/Exception.h"
0013 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0014 #include "HLTrigger/HLTcore/interface/HLTFilter.h"
0015 #include <string>
0016 #include <vector>
0017 
0018 template <typename T1, typename T2, typename T3>
0019 class HLTTripletMass : public HLTFilter {
0020   typedef edm::Ref<std::vector<T1>> T1Ref;
0021   typedef edm::Ref<std::vector<T2>> T2Ref;
0022   typedef edm::Ref<std::vector<T3>> T3Ref;
0023 
0024 public:
0025   explicit HLTTripletMass(const edm::ParameterSet&);
0026   ~HLTTripletMass() override = default;
0027   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0028   bool hltFilter(edm::Event&,
0029                  const edm::EventSetup&,
0030                  trigger::TriggerFilterObjectWithRefs& filterproduct) const override;
0031   bool getCollections(edm::Event& iEvent,
0032                       std::vector<T1Ref>& coll1,
0033                       std::vector<T2Ref>& coll2,
0034                       std::vector<T3Ref>& coll3,
0035                       trigger::TriggerFilterObjectWithRefs& filterproduct) const;
0036 
0037 private:
0038   // configuration
0039   const std::vector<edm::InputTag> originTag1_;  // input tag identifying originals 1st product
0040   const std::vector<edm::InputTag> originTag2_;  // input tag identifying originals 2nd product
0041   const std::vector<edm::InputTag> originTag3_;  // input tag identifying originals 3rd product
0042   const edm::EDGetTokenT<trigger::TriggerFilterObjectWithRefs> inputToken1_;
0043   const edm::EDGetTokenT<trigger::TriggerFilterObjectWithRefs> inputToken2_;
0044   const edm::EDGetTokenT<trigger::TriggerFilterObjectWithRefs> inputToken3_;
0045   const int triggerType1_;
0046   const int triggerType2_;
0047   const int triggerType3_;
0048   const std::vector<double> min_InvMass_;  // minimum invariant mass of pair
0049   const std::vector<double> max_InvMass_;  // maximum invariant mass of pair
0050   const double max_DR_;                    // maximum deltaR between the p4 of 3rd product and p4 of (1+2) product
0051   const double max_DR2_;                   // maximum deltaR^2 between the p4 of 3rd product and p4 of (1+2) product
0052   const int min_N_;
0053   const bool is1and2Same_;
0054   const bool is2and3Same_;
0055 };
0056 
0057 template <typename T1, typename T2, typename T3>
0058 HLTTripletMass<T1, T2, T3>::HLTTripletMass(const edm::ParameterSet& iConfig)
0059     : HLTFilter(iConfig),
0060       originTag1_(iConfig.getParameter<std::vector<edm::InputTag>>("originTag1")),
0061       originTag2_(iConfig.getParameter<std::vector<edm::InputTag>>("originTag2")),
0062       originTag3_(iConfig.getParameter<std::vector<edm::InputTag>>("originTag3")),
0063       inputToken1_(consumes(iConfig.getParameter<edm::InputTag>("inputTag1"))),
0064       inputToken2_(consumes(iConfig.getParameter<edm::InputTag>("inputTag2"))),
0065       inputToken3_(consumes(iConfig.getParameter<edm::InputTag>("inputTag3"))),
0066       triggerType1_(iConfig.getParameter<int>("triggerType1")),
0067       triggerType2_(iConfig.getParameter<int>("triggerType2")),
0068       triggerType3_(iConfig.getParameter<int>("triggerType3")),
0069       min_InvMass_(iConfig.getParameter<vector<double>>("MinInvMass")),
0070       max_InvMass_(iConfig.getParameter<vector<double>>("MaxInvMass")),
0071       max_DR_(iConfig.getParameter<double>("MaxDR")),
0072       max_DR2_(max_DR_ * max_DR_),
0073       min_N_(iConfig.getParameter<int>("MinN")),
0074       is1and2Same_(iConfig.getParameter<bool>("is1and2Same")),
0075       is2and3Same_(iConfig.getParameter<bool>("is2and3Same")) {
0076   if (min_InvMass_.size() != max_InvMass_.size()) {
0077     throw cms::Exception("Configuration") << "size of \"MinInvMass\" (" << min_InvMass_.size()
0078                                           << ") and \"MaxInvMass\" (" << max_InvMass_.size() << ") differ";
0079   }
0080   if (max_DR_ < 0) {
0081     throw cms::Exception("Configuration") << "invalid value for parameter \"MaxDR\" (must be >= 0): " << max_DR_;
0082   }
0083 }
0084 
0085 template <typename T1, typename T2, typename T3>
0086 void HLTTripletMass<T1, T2, T3>::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0087   edm::ParameterSetDescription desc;
0088   makeHLTFilterDescription(desc);
0089   desc.add<std::vector<edm::InputTag>>("originTag1", {edm::InputTag("hltOriginal1")});
0090   desc.add<std::vector<edm::InputTag>>("originTag2", {edm::InputTag("hltOriginal2")});
0091   desc.add<std::vector<edm::InputTag>>("originTag3", {edm::InputTag("hltOriginal3")});
0092   desc.add<edm::InputTag>("inputTag1", edm::InputTag("hltFiltered1"));
0093   desc.add<edm::InputTag>("inputTag2", edm::InputTag("hltFiltered2"));
0094   desc.add<edm::InputTag>("inputTag3", edm::InputTag("hltFiltered3"));
0095   desc.add<int>("triggerType1", 0);
0096   desc.add<int>("triggerType2", 0);
0097   desc.add<int>("triggerType3", 0);
0098 
0099   desc.add<vector<double>>("MinInvMass", {0});
0100   desc.add<vector<double>>("MaxInvMass", {1e12});
0101 
0102   desc.add<double>("MaxDR", 1e4);
0103   desc.add<int>("MinN", 0);
0104 
0105   desc.add<bool>("is1and2Same", false);
0106   desc.add<bool>("is2and3Same", false);
0107   descriptions.addWithDefaultLabel(desc);
0108 }
0109 
0110 template <typename T1, typename T2, typename T3>
0111 bool HLTTripletMass<T1, T2, T3>::getCollections(edm::Event& iEvent,
0112                                                 std::vector<T1Ref>& coll1,
0113                                                 std::vector<T2Ref>& coll2,
0114                                                 std::vector<T3Ref>& coll3,
0115                                                 trigger::TriggerFilterObjectWithRefs& filterproduct) const {
0116   edm::Handle<trigger::TriggerFilterObjectWithRefs> handle1, handle2, handle3;
0117   if (iEvent.getByToken(inputToken1_, handle1) and iEvent.getByToken(inputToken2_, handle2) and
0118       iEvent.getByToken(inputToken3_, handle3)) {
0119     // get hold of pre-filtered object collections
0120     handle1->getObjects(triggerType1_, coll1);
0121     handle2->getObjects(triggerType2_, coll2);
0122     handle3->getObjects(triggerType3_, coll3);
0123     const trigger::size_type n1(coll1.size());
0124     const trigger::size_type n2(coll2.size());
0125     const trigger::size_type n3(coll3.size());
0126 
0127     if (saveTags()) {
0128       edm::InputTag tagOld;
0129       for (unsigned int i = 0; i < originTag1_.size(); ++i) {
0130         filterproduct.addCollectionTag(originTag1_[i]);
0131       }
0132       tagOld = edm::InputTag();
0133       for (trigger::size_type i1 = 0; i1 != n1; ++i1) {
0134         const edm::ProductID pid(coll1[i1].id());
0135         const auto& prov = iEvent.getStableProvenance(pid);
0136         const std::string& label(prov.moduleLabel());
0137         const std::string& instance(prov.productInstanceName());
0138         const std::string& process(prov.processName());
0139         edm::InputTag tagNew(edm::InputTag(label, instance, process));
0140         if (tagOld.encode() != tagNew.encode()) {
0141           filterproduct.addCollectionTag(tagNew);
0142           tagOld = tagNew;
0143         }
0144       }
0145       for (unsigned int i = 0; i < originTag2_.size(); ++i) {
0146         filterproduct.addCollectionTag(originTag2_[i]);
0147       }
0148       tagOld = edm::InputTag();
0149       for (trigger::size_type i2 = 0; i2 != n2; ++i2) {
0150         const edm::ProductID pid(coll2[i2].id());
0151         const auto& prov = iEvent.getStableProvenance(pid);
0152         const std::string& label(prov.moduleLabel());
0153         const std::string& instance(prov.productInstanceName());
0154         const std::string& process(prov.processName());
0155         edm::InputTag tagNew(edm::InputTag(label, instance, process));
0156         if (tagOld.encode() != tagNew.encode()) {
0157           filterproduct.addCollectionTag(tagNew);
0158           tagOld = tagNew;
0159         }
0160       }
0161       for (unsigned int i = 0; i < originTag3_.size(); ++i) {
0162         filterproduct.addCollectionTag(originTag3_[i]);
0163       }
0164       tagOld = edm::InputTag();
0165       for (trigger::size_type i3 = 0; i3 != n3; ++i3) {
0166         const edm::ProductID pid(coll3[i3].id());
0167         const auto& prov = iEvent.getStableProvenance(pid);
0168         const std::string& label(prov.moduleLabel());
0169         const std::string& instance(prov.productInstanceName());
0170         const std::string& process(prov.processName());
0171         edm::InputTag tagNew(edm::InputTag(label, instance, process));
0172         if (tagOld.encode() != tagNew.encode()) {
0173           filterproduct.addCollectionTag(tagNew);
0174           tagOld = tagNew;
0175         }
0176       }
0177     }
0178 
0179     return true;
0180   } else
0181     return false;
0182 }
0183 
0184 // ------------ method called to produce the data  ------------
0185 template <typename T1, typename T2, typename T3>
0186 bool HLTTripletMass<T1, T2, T3>::hltFilter(edm::Event& iEvent,
0187                                            const edm::EventSetup& iSetup,
0188                                            trigger::TriggerFilterObjectWithRefs& filterproduct) const {
0189   // All HLT filters must create and fill an HLT filter object,
0190   // recording any reconstructed physics objects satisfying (or not)
0191   // this HLT filter, and place it in the Event.
0192 
0193   std::vector<T1Ref> coll1;
0194   std::vector<T2Ref> coll2;
0195   std::vector<T3Ref> coll3;
0196 
0197   int n(0);
0198   if (getCollections(iEvent, coll1, coll2, coll3, filterproduct)) {
0199     T1Ref r1;
0200     T2Ref r2;
0201     T3Ref r3;
0202 
0203     reco::Particle::LorentzVector dauA_p4, dauB_p4, dauAB_p4, dauC_p4;
0204     for (unsigned int i1 = 0; i1 != coll1.size(); i1++) {
0205       r1 = coll1[i1];
0206       dauA_p4 = reco::Particle::LorentzVector(r1->px(), r1->py(), r1->pz(), r1->energy());
0207       unsigned int i2 = is1and2Same_ ? i1 + 1 : 0;
0208       for (; i2 != coll2.size(); i2++) {
0209         r2 = coll2[i2];
0210         dauB_p4 = reco::Particle::LorentzVector(r2->px(), r2->py(), r2->pz(), r2->energy());
0211         dauAB_p4 = dauA_p4 + dauB_p4;
0212 
0213         unsigned int i3 = is2and3Same_ ? i2 + 1 : 0;
0214         for (; i3 != coll3.size(); i3++) {
0215           r3 = coll3[i3];
0216           dauC_p4 = reco::Particle::LorentzVector(r3->px(), r3->py(), r3->pz(), r3->energy());
0217           if (reco::deltaR2(dauAB_p4, dauC_p4) > max_DR2_) {
0218             continue;
0219           }
0220           bool passesMassCut = false;
0221           auto const mass_ABC = (dauC_p4 + dauAB_p4).mass();
0222           for (unsigned int j = 0; j < max_InvMass_.size(); j++) {
0223             if ((mass_ABC >= min_InvMass_[j]) and (mass_ABC < max_InvMass_[j])) {
0224               passesMassCut = true;
0225               break;
0226             }
0227           }
0228           if (passesMassCut) {
0229             n++;
0230             filterproduct.addObject(triggerType1_, r1);
0231             filterproduct.addObject(triggerType2_, r2);
0232             filterproduct.addObject(triggerType3_, r3);
0233           }
0234         }
0235       }
0236     }
0237   }
0238 
0239   return (n >= min_N_);
0240 }
0241 
0242 typedef HLTTripletMass<reco::RecoChargedCandidate, reco::RecoChargedCandidate, reco::RecoEcalCandidate>
0243     HLT3MuonMuonPhotonMass;
0244 
0245 DEFINE_FWK_MODULE(HLT3MuonMuonPhotonMass);