File indexing completed on 2024-04-06 12:18:28
0001
0002
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
0039 const std::vector<edm::InputTag> originTag1_;
0040 const std::vector<edm::InputTag> originTag2_;
0041 const std::vector<edm::InputTag> originTag3_;
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_;
0049 const std::vector<double> max_InvMass_;
0050 const double max_DR_;
0051 const double max_DR2_;
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
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
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
0190
0191
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);