Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-08-26 00:19:25

0001 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0002 #include "HLTDoubletDZ.h"
0003 
0004 #include "DataFormats/Common/interface/Handle.h"
0005 
0006 #include "DataFormats/Common/interface/Ref.h"
0007 #include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h"
0008 
0009 //#include "DataFormats/Candidate/interface/Particle.h"
0010 #include "DataFormats/RecoCandidate/interface/RecoEcalCandidate.h"
0011 #include "DataFormats/RecoCandidate/interface/RecoEcalCandidateFwd.h"
0012 #include "DataFormats/EgammaCandidates/interface/Electron.h"
0013 #include "DataFormats/EgammaCandidates/interface/ElectronFwd.h"
0014 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h"
0015 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h"
0016 #include "DataFormats/L1TMuonPhase2/interface/TrackerMuon.h"
0017 #include "DataFormats/L1TParticleFlow/interface/PFTau.h"
0018 #include "DataFormats/L1TParticleFlow/interface/HPSPFTau.h"
0019 #include "DataFormats/L1TParticleFlow/interface/HPSPFTauFwd.h"
0020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0021 
0022 #include "FWCore/Framework/interface/MakerMacros.h"
0023 
0024 #include "DataFormats/Math/interface/deltaR.h"
0025 
0026 #include "HLTrigger/HLTcore/interface/defaultModuleLabel.h"
0027 #include <cmath>
0028 
0029 //
0030 // constructors and destructor
0031 //
0032 template <typename T1, typename T2>
0033 HLTDoubletDZ<T1, T2>::HLTDoubletDZ(const edm::ParameterSet& iConfig)
0034     : HLTFilter(iConfig),
0035       originTag1_(iConfig.template getParameter<std::vector<edm::InputTag>>("originTag1")),
0036       originTag2_(iConfig.template getParameter<std::vector<edm::InputTag>>("originTag2")),
0037       inputTag1_(iConfig.template getParameter<edm::InputTag>("inputTag1")),
0038       inputTag2_(iConfig.template getParameter<edm::InputTag>("inputTag2")),
0039       inputToken1_(consumes<trigger::TriggerFilterObjectWithRefs>(inputTag1_)),
0040       inputToken2_(consumes<trigger::TriggerFilterObjectWithRefs>(inputTag2_)),
0041       //electronToken_ (consumes<reco::ElectronCollection>(iConfig.template getParameter<edm::InputTag>("electronTag"))),
0042       triggerType1_(iConfig.template getParameter<int>("triggerType1")),
0043       triggerType2_(iConfig.template getParameter<int>("triggerType2")),
0044       minDR_(iConfig.template getParameter<double>("MinDR")),
0045       maxDZ_(iConfig.template getParameter<double>("MaxDZ")),
0046       minPixHitsForDZ_(iConfig.template getParameter<int>("MinPixHitsForDZ")),
0047       min_N_(iConfig.template getParameter<int>("MinN")),
0048       checkSC_(iConfig.template getParameter<bool>("checkSC")),
0049       same_(inputTag1_.encode() == inputTag2_.encode())  // same collections to be compared?
0050 {}
0051 
0052 template <>
0053 HLTDoubletDZ<reco::RecoEcalCandidate, reco::RecoEcalCandidate>::HLTDoubletDZ(const edm::ParameterSet& iConfig)
0054     : HLTFilter(iConfig),
0055       originTag1_(iConfig.template getParameter<std::vector<edm::InputTag>>("originTag1")),
0056       originTag2_(iConfig.template getParameter<std::vector<edm::InputTag>>("originTag2")),
0057       inputTag1_(iConfig.template getParameter<edm::InputTag>("inputTag1")),
0058       inputTag2_(iConfig.template getParameter<edm::InputTag>("inputTag2")),
0059       inputToken1_(consumes<trigger::TriggerFilterObjectWithRefs>(inputTag1_)),
0060       inputToken2_(consumes<trigger::TriggerFilterObjectWithRefs>(inputTag2_)),
0061       electronToken_(consumes<reco::ElectronCollection>(iConfig.template getParameter<edm::InputTag>("electronTag"))),
0062       triggerType1_(iConfig.template getParameter<int>("triggerType1")),
0063       triggerType2_(iConfig.template getParameter<int>("triggerType2")),
0064       minDR_(iConfig.template getParameter<double>("MinDR")),
0065       maxDZ_(iConfig.template getParameter<double>("MaxDZ")),
0066       minPixHitsForDZ_(iConfig.template getParameter<int>("MinPixHitsForDZ")),
0067       min_N_(iConfig.template getParameter<int>("MinN")),
0068       checkSC_(iConfig.template getParameter<bool>("checkSC")),
0069       same_(inputTag1_.encode() == inputTag2_.encode())  // same collections to be compared?
0070 {}
0071 
0072 template <>
0073 HLTDoubletDZ<reco::RecoChargedCandidate, reco::RecoEcalCandidate>::HLTDoubletDZ(const edm::ParameterSet& iConfig)
0074     : HLTFilter(iConfig),
0075       originTag1_(iConfig.template getParameter<std::vector<edm::InputTag>>("originTag1")),
0076       originTag2_(iConfig.template getParameter<std::vector<edm::InputTag>>("originTag2")),
0077       inputTag1_(iConfig.template getParameter<edm::InputTag>("inputTag1")),
0078       inputTag2_(iConfig.template getParameter<edm::InputTag>("inputTag2")),
0079       inputToken1_(consumes<trigger::TriggerFilterObjectWithRefs>(inputTag1_)),
0080       inputToken2_(consumes<trigger::TriggerFilterObjectWithRefs>(inputTag2_)),
0081       electronToken_(consumes<reco::ElectronCollection>(iConfig.template getParameter<edm::InputTag>("electronTag"))),
0082       triggerType1_(iConfig.template getParameter<int>("triggerType1")),
0083       triggerType2_(iConfig.template getParameter<int>("triggerType2")),
0084       minDR_(iConfig.template getParameter<double>("MinDR")),
0085       maxDZ_(iConfig.template getParameter<double>("MaxDZ")),
0086       minPixHitsForDZ_(iConfig.template getParameter<int>("MinPixHitsForDZ")),
0087       min_N_(iConfig.template getParameter<int>("MinN")),
0088       checkSC_(iConfig.template getParameter<bool>("checkSC")),
0089       same_(inputTag1_.encode() == inputTag2_.encode())  // same collections to be compared?
0090 {}
0091 
0092 template <>
0093 HLTDoubletDZ<reco::RecoEcalCandidate, reco::RecoChargedCandidate>::HLTDoubletDZ(const edm::ParameterSet& iConfig)
0094     : HLTFilter(iConfig),
0095       originTag1_(iConfig.template getParameter<std::vector<edm::InputTag>>("originTag1")),
0096       originTag2_(iConfig.template getParameter<std::vector<edm::InputTag>>("originTag2")),
0097       inputTag1_(iConfig.template getParameter<edm::InputTag>("inputTag1")),
0098       inputTag2_(iConfig.template getParameter<edm::InputTag>("inputTag2")),
0099       inputToken1_(consumes<trigger::TriggerFilterObjectWithRefs>(inputTag1_)),
0100       inputToken2_(consumes<trigger::TriggerFilterObjectWithRefs>(inputTag2_)),
0101       electronToken_(consumes<reco::ElectronCollection>(iConfig.template getParameter<edm::InputTag>("electronTag"))),
0102       triggerType1_(iConfig.template getParameter<int>("triggerType1")),
0103       triggerType2_(iConfig.template getParameter<int>("triggerType2")),
0104       minDR_(iConfig.template getParameter<double>("MinDR")),
0105       maxDZ_(iConfig.template getParameter<double>("MaxDZ")),
0106       minPixHitsForDZ_(iConfig.template getParameter<int>("MinPixHitsForDZ")),
0107       min_N_(iConfig.template getParameter<int>("MinN")),
0108       checkSC_(iConfig.template getParameter<bool>("checkSC")),
0109       same_(inputTag1_.encode() == inputTag2_.encode())  // same collections to be compared?
0110 {}
0111 
0112 template <>
0113 HLTDoubletDZ<reco::RecoChargedCandidate, reco::RecoChargedCandidate>::HLTDoubletDZ(const edm::ParameterSet& iConfig)
0114     : HLTFilter(iConfig),
0115       originTag1_(iConfig.template getParameter<std::vector<edm::InputTag>>("originTag1")),
0116       originTag2_(iConfig.template getParameter<std::vector<edm::InputTag>>("originTag2")),
0117       inputTag1_(iConfig.template getParameter<edm::InputTag>("inputTag1")),
0118       inputTag2_(iConfig.template getParameter<edm::InputTag>("inputTag2")),
0119       inputToken1_(consumes<trigger::TriggerFilterObjectWithRefs>(inputTag1_)),
0120       inputToken2_(consumes<trigger::TriggerFilterObjectWithRefs>(inputTag2_)),
0121       //electronToken_ (consumes<reco::ElectronCollection>(iConfig.template getParameter<edm::InputTag>("electronTag"))),
0122       triggerType1_(iConfig.template getParameter<int>("triggerType1")),
0123       triggerType2_(iConfig.template getParameter<int>("triggerType2")),
0124       minDR_(iConfig.template getParameter<double>("MinDR")),
0125       maxDZ_(iConfig.template getParameter<double>("MaxDZ")),
0126       minPixHitsForDZ_(iConfig.template getParameter<int>("MinPixHitsForDZ")),
0127       min_N_(iConfig.template getParameter<int>("MinN")),
0128       checkSC_(iConfig.template getParameter<bool>("checkSC")),
0129       same_(inputTag1_.encode() == inputTag2_.encode())  // same collections to be compared?
0130 {}
0131 
0132 template <>
0133 HLTDoubletDZ<l1t::TrackerMuon, l1t::TrackerMuon>::HLTDoubletDZ(const edm::ParameterSet& iConfig)
0134     : HLTFilter(iConfig),
0135       originTag1_(iConfig.template getParameter<std::vector<edm::InputTag>>("originTag1")),
0136       originTag2_(iConfig.template getParameter<std::vector<edm::InputTag>>("originTag2")),
0137       inputTag1_(iConfig.template getParameter<edm::InputTag>("inputTag1")),
0138       inputTag2_(iConfig.template getParameter<edm::InputTag>("inputTag2")),
0139       inputToken1_(consumes<trigger::TriggerFilterObjectWithRefs>(inputTag1_)),
0140       inputToken2_(consumes<trigger::TriggerFilterObjectWithRefs>(inputTag2_)),
0141       triggerType1_(iConfig.template getParameter<int>("triggerType1")),
0142       triggerType2_(iConfig.template getParameter<int>("triggerType2")),
0143       minDR_(iConfig.template getParameter<double>("MinDR")),
0144       maxDZ_(iConfig.template getParameter<double>("MaxDZ")),
0145       minPixHitsForDZ_(iConfig.template getParameter<int>("MinPixHitsForDZ")),
0146       min_N_(iConfig.template getParameter<int>("MinN")),
0147       checkSC_(iConfig.template getParameter<bool>("checkSC")),
0148       same_(inputTag1_.encode() == inputTag2_.encode())  // same collections to be compared?
0149 {}
0150 
0151 template <typename T1, typename T2>
0152 HLTDoubletDZ<T1, T2>::~HLTDoubletDZ() {}
0153 
0154 template <typename T1, typename T2>
0155 void HLTDoubletDZ<T1, T2>::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0156   edm::ParameterSetDescription desc;
0157   makeHLTFilterDescription(desc);
0158   std::vector<edm::InputTag> originTag1(1, edm::InputTag("hltOriginal1"));
0159   std::vector<edm::InputTag> originTag2(1, edm::InputTag("hltOriginal2"));
0160   desc.add<std::vector<edm::InputTag>>("originTag1", originTag1);
0161   desc.add<std::vector<edm::InputTag>>("originTag2", originTag2);
0162   desc.add<edm::InputTag>("inputTag1", edm::InputTag("hltFiltered1"));
0163   desc.add<edm::InputTag>("inputTag2", edm::InputTag("hltFiltered2"));
0164   desc.add<int>("triggerType1", 0);
0165   desc.add<int>("triggerType2", 0);
0166   desc.add<double>("MinDR", -1.0);
0167   desc.add<double>("MaxDZ", 0.2);
0168   desc.add<int>("MinPixHitsForDZ", 0);
0169   desc.add<bool>("checkSC", false);
0170   desc.add<int>("MinN", 1);
0171   descriptions.add(defaultModuleLabel<HLTDoubletDZ<T1, T2>>(), desc);
0172 }
0173 
0174 template <>
0175 void HLTDoubletDZ<reco::RecoEcalCandidate, reco::RecoEcalCandidate>::fillDescriptions(
0176     edm::ConfigurationDescriptions& descriptions) {
0177   edm::ParameterSetDescription desc;
0178   makeHLTFilterDescription(desc);
0179   std::vector<edm::InputTag> originTag1(1, edm::InputTag("hltOriginal1"));
0180   std::vector<edm::InputTag> originTag2(1, edm::InputTag("hltOriginal2"));
0181   desc.add<std::vector<edm::InputTag>>("originTag1", originTag1);
0182   desc.add<std::vector<edm::InputTag>>("originTag2", originTag2);
0183   desc.add<edm::InputTag>("inputTag1", edm::InputTag("hltFiltered1"));
0184   desc.add<edm::InputTag>("inputTag2", edm::InputTag("hltFiltered2"));
0185   desc.add<edm::InputTag>("electronTag", edm::InputTag("electronTag"));
0186   desc.add<int>("triggerType1", 0);
0187   desc.add<int>("triggerType2", 0);
0188   desc.add<double>("MinDR", -1.0);
0189   desc.add<double>("MaxDZ", 0.2);
0190   desc.add<int>("MinPixHitsForDZ", 0);
0191   desc.add<bool>("checkSC", false);
0192   desc.add<int>("MinN", 1);
0193   descriptions.add(defaultModuleLabel<HLTDoubletDZ<reco::RecoEcalCandidate, reco::RecoEcalCandidate>>(), desc);
0194 }
0195 
0196 template <>
0197 void HLTDoubletDZ<reco::RecoChargedCandidate, reco::RecoEcalCandidate>::fillDescriptions(
0198     edm::ConfigurationDescriptions& descriptions) {
0199   edm::ParameterSetDescription desc;
0200   makeHLTFilterDescription(desc);
0201   std::vector<edm::InputTag> originTag1(1, edm::InputTag("hltOriginal1"));
0202   std::vector<edm::InputTag> originTag2(1, edm::InputTag("hltOriginal2"));
0203   desc.add<std::vector<edm::InputTag>>("originTag1", originTag1);
0204   desc.add<std::vector<edm::InputTag>>("originTag2", originTag2);
0205   desc.add<edm::InputTag>("inputTag1", edm::InputTag("hltFiltered1"));
0206   desc.add<edm::InputTag>("inputTag2", edm::InputTag("hltFiltered2"));
0207   desc.add<edm::InputTag>("electronTag", edm::InputTag("electronTag"));
0208   desc.add<int>("triggerType1", 0);
0209   desc.add<int>("triggerType2", 0);
0210   desc.add<double>("MinDR", -1.0);
0211   desc.add<double>("MaxDZ", 0.2);
0212   desc.add<int>("MinPixHitsForDZ", 0);
0213   desc.add<bool>("checkSC", false);
0214   desc.add<int>("MinN", 1);
0215   descriptions.add(defaultModuleLabel<HLTDoubletDZ<reco::RecoChargedCandidate, reco::RecoEcalCandidate>>(), desc);
0216 }
0217 
0218 template <>
0219 void HLTDoubletDZ<reco::RecoEcalCandidate, reco::RecoChargedCandidate>::fillDescriptions(
0220     edm::ConfigurationDescriptions& descriptions) {
0221   edm::ParameterSetDescription desc;
0222   makeHLTFilterDescription(desc);
0223   std::vector<edm::InputTag> originTag1(1, edm::InputTag("hltOriginal1"));
0224   std::vector<edm::InputTag> originTag2(1, edm::InputTag("hltOriginal2"));
0225   desc.add<std::vector<edm::InputTag>>("originTag1", originTag1);
0226   desc.add<std::vector<edm::InputTag>>("originTag2", originTag2);
0227   desc.add<edm::InputTag>("inputTag1", edm::InputTag("hltFiltered1"));
0228   desc.add<edm::InputTag>("inputTag2", edm::InputTag("hltFiltered2"));
0229   desc.add<edm::InputTag>("electronTag", edm::InputTag("electronTag"));
0230   desc.add<int>("triggerType1", 0);
0231   desc.add<int>("triggerType2", 0);
0232   desc.add<double>("MinDR", -1.0);
0233   desc.add<double>("MaxDZ", 0.2);
0234   desc.add<int>("MinPixHitsForDZ", 0);
0235   desc.add<bool>("checkSC", false);
0236   desc.add<int>("MinN", 1);
0237   descriptions.add(defaultModuleLabel<HLTDoubletDZ<reco::RecoEcalCandidate, reco::RecoChargedCandidate>>(), desc);
0238 }
0239 
0240 template <>
0241 void HLTDoubletDZ<reco::RecoChargedCandidate, reco::RecoChargedCandidate>::fillDescriptions(
0242     edm::ConfigurationDescriptions& descriptions) {
0243   edm::ParameterSetDescription desc;
0244   makeHLTFilterDescription(desc);
0245   std::vector<edm::InputTag> originTag1(1, edm::InputTag("hltOriginal1"));
0246   std::vector<edm::InputTag> originTag2(1, edm::InputTag("hltOriginal2"));
0247   desc.add<std::vector<edm::InputTag>>("originTag1", originTag1);
0248   desc.add<std::vector<edm::InputTag>>("originTag2", originTag2);
0249   desc.add<edm::InputTag>("inputTag1", edm::InputTag("hltFiltered1"));
0250   desc.add<edm::InputTag>("inputTag2", edm::InputTag("hltFiltered2"));
0251   desc.add<int>("triggerType1", 0);
0252   desc.add<int>("triggerType2", 0);
0253   desc.add<double>("MinDR", -1.0);
0254   desc.add<double>("MaxDZ", 0.2);
0255   desc.add<int>("MinPixHitsForDZ", 0);
0256   desc.add<bool>("checkSC", false);
0257   desc.add<int>("MinN", 1);
0258   descriptions.add(defaultModuleLabel<HLTDoubletDZ<reco::RecoChargedCandidate, reco::RecoChargedCandidate>>(), desc);
0259 }
0260 
0261 template <typename T1, typename T2>
0262 bool
0263 //HLTDoubletDZ<T1, T2>::getCollections(edm::Event& iEvent, std::vector<T1Ref>& coll1, std::vector<T2Ref>& coll2) const {
0264 HLTDoubletDZ<T1, T2>::getCollections(edm::Event& iEvent,
0265                                      std::vector<T1Ref>& coll1,
0266                                      std::vector<T2Ref>& coll2,
0267                                      trigger::TriggerFilterObjectWithRefs& filterproduct) const {
0268   edm::Handle<trigger::TriggerFilterObjectWithRefs> handle1, handle2;
0269   if (iEvent.getByToken(inputToken1_, handle1) and iEvent.getByToken(inputToken2_, handle2)) {
0270     // get hold of pre-filtered object collections
0271     handle1->getObjects(triggerType1_, coll1);
0272     handle2->getObjects(triggerType2_, coll2);
0273     const trigger::size_type n1(coll1.size());
0274     const trigger::size_type n2(coll2.size());
0275 
0276     if (saveTags()) {
0277       edm::InputTag tagOld;
0278       for (unsigned int i = 0; i < originTag1_.size(); ++i) {
0279         filterproduct.addCollectionTag(originTag1_[i]);
0280       }
0281       tagOld = edm::InputTag();
0282       for (trigger::size_type i1 = 0; i1 != n1; ++i1) {
0283         const edm::ProductID pid(coll1[i1].id());
0284         const auto& prov = iEvent.getStableProvenance(pid);
0285         const std::string& label(prov.moduleLabel());
0286         const std::string& instance(prov.productInstanceName());
0287         const std::string& process(prov.processName());
0288         edm::InputTag tagNew(edm::InputTag(label, instance, process));
0289         if (tagOld.encode() != tagNew.encode()) {
0290           filterproduct.addCollectionTag(tagNew);
0291           tagOld = tagNew;
0292         }
0293       }
0294       for (unsigned int i = 0; i < originTag2_.size(); ++i) {
0295         filterproduct.addCollectionTag(originTag2_[i]);
0296       }
0297       tagOld = edm::InputTag();
0298       for (trigger::size_type i2 = 0; i2 != n2; ++i2) {
0299         const edm::ProductID pid(coll2[i2].id());
0300         const auto& prov = iEvent.getStableProvenance(pid);
0301         const std::string& label(prov.moduleLabel());
0302         const std::string& instance(prov.productInstanceName());
0303         const std::string& process(prov.processName());
0304         edm::InputTag tagNew(edm::InputTag(label, instance, process));
0305         if (tagOld.encode() != tagNew.encode()) {
0306           filterproduct.addCollectionTag(tagNew);
0307           tagOld = tagNew;
0308         }
0309       }
0310     }
0311 
0312     return true;
0313   } else
0314     return false;
0315 }
0316 
0317 template <typename T1, typename T2>
0318 bool HLTDoubletDZ<T1, T2>::computeDZ(edm::Event& iEvent, T1Ref& r1, T2Ref& r2) const {
0319   const reco::Candidate& candidate1(*r1);
0320   const reco::Candidate& candidate2(*r2);
0321   if (reco::deltaR(candidate1, candidate2) < minDR_)
0322     return false;
0323   if (std::abs(candidate1.vz() - candidate2.vz()) > maxDZ_)
0324     return false;
0325 
0326   return true;
0327 }
0328 
0329 template <>
0330 bool HLTDoubletDZ<reco::RecoEcalCandidate, reco::RecoChargedCandidate>::computeDZ(edm::Event& iEvent,
0331                                                                                   T1Ref& r1,
0332                                                                                   T2Ref& r2) const {
0333   edm::Handle<reco::ElectronCollection> electronHandle_;
0334   iEvent.getByToken(electronToken_, electronHandle_);
0335   if (!electronHandle_.isValid())
0336     edm::LogError("HLTDoubletDZ") << "HLTDoubletDZ: Electron Handle not valid.";
0337 
0338   if (reco::deltaR(*r1, *r2) < minDR_)
0339     return false;
0340   reco::Electron e1;
0341   for (auto const& eleIt : *electronHandle_) {
0342     if (eleIt.superCluster() == r1->superCluster())
0343       e1 = eleIt;
0344   }
0345 
0346   const reco::RecoChargedCandidate& candidate2(*r2);
0347   bool skipDZ = false;
0348   if (minPixHitsForDZ_ > 0 && (e1.gsfTrack()->hitPattern().numberOfValidPixelHits() < minPixHitsForDZ_ ||
0349                                candidate2.track()->hitPattern().numberOfValidPixelHits() < minPixHitsForDZ_))
0350     skipDZ = true;
0351   if (!skipDZ && std::abs(e1.vz() - candidate2.vz()) > maxDZ_)
0352     return false;
0353 
0354   return true;
0355 }
0356 
0357 template <>
0358 bool HLTDoubletDZ<reco::RecoChargedCandidate, reco::RecoEcalCandidate>::computeDZ(edm::Event& iEvent,
0359                                                                                   T1Ref& r1,
0360                                                                                   T2Ref& r2) const {
0361   edm::Handle<reco::ElectronCollection> electronHandle_;
0362   iEvent.getByToken(electronToken_, electronHandle_);
0363   if (!electronHandle_.isValid())
0364     edm::LogError("HLTDoubletDZ") << "HLTDoubletDZ: Electron Handle not valid.";
0365 
0366   if (reco::deltaR(*r1, *r2) < minDR_)
0367     return false;
0368   reco::Electron e2;
0369   for (auto const& eleIt : *electronHandle_) {
0370     if (eleIt.superCluster() == r2->superCluster())
0371       e2 = eleIt;
0372   }
0373 
0374   const reco::RecoChargedCandidate& candidate1(*r1);
0375   bool skipDZ = false;
0376   if (minPixHitsForDZ_ > 0 && (candidate1.track()->hitPattern().numberOfValidPixelHits() < minPixHitsForDZ_ ||
0377                                e2.gsfTrack()->hitPattern().numberOfValidPixelHits() < minPixHitsForDZ_))
0378     skipDZ = true;
0379   if (!skipDZ && std::abs(e2.vz() - candidate1.vz()) > maxDZ_)
0380     return false;
0381 
0382   return true;
0383 }
0384 
0385 template <>
0386 bool HLTDoubletDZ<reco::RecoEcalCandidate, reco::RecoEcalCandidate>::computeDZ(edm::Event& iEvent,
0387                                                                                T1Ref& r1,
0388                                                                                T2Ref& r2) const {
0389   edm::Handle<reco::ElectronCollection> electronHandle_;
0390   iEvent.getByToken(electronToken_, electronHandle_);
0391   if (!electronHandle_.isValid())
0392     edm::LogError("HLTDoubletDZ") << "HLTDoubletDZ: Electron Handle not valid.";
0393 
0394   if (reco::deltaR(*r1, *r2) < minDR_)
0395     return false;
0396   reco::Electron e1, e2;
0397   for (auto const& eleIt : *electronHandle_) {
0398     if (eleIt.superCluster() == r2->superCluster())
0399       e2 = eleIt;
0400     if (eleIt.superCluster() == r1->superCluster())
0401       e1 = eleIt;
0402   }
0403 
0404   bool skipDZ = false;
0405   if (minPixHitsForDZ_ > 0 && (e1.gsfTrack()->hitPattern().numberOfValidPixelHits() < minPixHitsForDZ_ ||
0406                                e2.gsfTrack()->hitPattern().numberOfValidPixelHits() < minPixHitsForDZ_))
0407     skipDZ = true;
0408   if (!skipDZ && std::abs(e2.vz() - e1.vz()) > maxDZ_)
0409     return false;
0410 
0411   return true;
0412 }
0413 
0414 template <>
0415 bool HLTDoubletDZ<reco::RecoChargedCandidate, reco::RecoChargedCandidate>::computeDZ(edm::Event& iEvent,
0416                                                                                      T1Ref& r1,
0417                                                                                      T2Ref& r2) const {
0418   const reco::RecoChargedCandidate& candidate1(*r1);
0419   const reco::RecoChargedCandidate& candidate2(*r2);
0420   if (reco::deltaR(candidate1, candidate2) < minDR_)
0421     return false;
0422   bool skipDZ = false;
0423   if (minPixHitsForDZ_ > 0 && (candidate1.track()->hitPattern().numberOfValidPixelHits() < minPixHitsForDZ_ ||
0424                                candidate2.track()->hitPattern().numberOfValidPixelHits() < minPixHitsForDZ_))
0425     skipDZ = true;
0426   if (!skipDZ && std::abs(candidate1.vz() - candidate2.vz()) > maxDZ_)
0427     return false;
0428 
0429   return true;
0430 }
0431 
0432 template <>
0433 bool HLTDoubletDZ<l1t::TrackerMuon, l1t::TrackerMuon>::computeDZ(edm::Event& iEvent,
0434                                                                  l1t::TrackerMuonRef& r1,
0435                                                                  l1t::TrackerMuonRef& r2) const {
0436   // We don't care about minPixHitsForDZ_ with the L1TTrackerMuons,
0437   // especially because the pixel does not participate in the L1T
0438   if (std::abs(r1->phZ0() - r2->phZ0()) > maxDZ_)
0439     return false;
0440 
0441   if (reco::deltaR2(r1->phEta(), r1->phPhi(), r2->phEta(), r2->phPhi()) < minDR_ * minDR_)
0442     return false;
0443 
0444   return true;
0445 }
0446 
0447 template <>
0448 bool HLTDoubletDZ<l1t::HPSPFTau, l1t::HPSPFTau>::computeDZ(edm::Event& iEvent,
0449                                                            l1t::HPSPFTauRef& r1,
0450                                                            l1t::HPSPFTauRef& r2) const {
0451   const l1t::HPSPFTau& candidate1(*r1);
0452   const l1t::HPSPFTau& candidate2(*r2);
0453   if (reco::deltaR(candidate1, candidate2) < minDR_)
0454     return false;
0455 
0456   // We don't care about minPixHitsForDZ_ with the L1HPSPFTaus,
0457   // especially because the pixel does not participate in the L1T
0458   if (std::abs(candidate1.leadChargedPFCand()->pfTrack()->vertex().z() -
0459                candidate2.leadChargedPFCand()->pfTrack()->vertex().z()) > maxDZ_)
0460     return false;
0461 
0462   return true;
0463 }
0464 
0465 // ------------ method called to produce the data  ------------
0466 template <typename T1, typename T2>
0467 bool HLTDoubletDZ<T1, T2>::hltFilter(edm::Event& iEvent,
0468                                      const edm::EventSetup& iSetup,
0469                                      trigger::TriggerFilterObjectWithRefs& filterproduct) const {
0470   // All HLT filters must create and fill an HLT filter object,
0471   // recording any reconstructed physics objects satisfying (or not)
0472   // this HLT filter, and place it in the Event.
0473   bool accept(false);
0474 
0475   std::vector<T1Ref> coll1;
0476   std::vector<T2Ref> coll2;
0477 
0478   if (getCollections(iEvent, coll1, coll2, filterproduct)) {
0479     int n(0);
0480     T1Ref r1;
0481     T2Ref r2;
0482 
0483     for (unsigned int i1 = 0; i1 != coll1.size(); i1++) {
0484       r1 = coll1[i1];
0485       //const reco::Candidate& candidate1(*r1);
0486       unsigned int I(0);
0487       if (same_) {
0488         I = i1 + 1;
0489       }
0490       for (unsigned int i2 = I; i2 != coll2.size(); i2++) {
0491         r2 = coll2[i2];
0492         if (checkSC_) {
0493           if (r1->superCluster().isNonnull() && r2->superCluster().isNonnull()) {
0494             if (r1->superCluster() == r2->superCluster())
0495               continue;
0496           }
0497         }
0498 
0499         if (!computeDZ(iEvent, r1, r2))
0500           continue;
0501 
0502         n++;
0503         filterproduct.addObject(triggerType1_, r1);
0504         filterproduct.addObject(triggerType2_, r2);
0505       }
0506     }
0507 
0508     accept = accept || (n >= min_N_);
0509   }
0510 
0511   return accept;
0512 }
0513 
0514 /// Special instantiation for L1TTrackerMuon
0515 /// L1TTrackerMuon are *not* RecoCandidates, therefore they don't implement superCluster()
0516 /// They are LeafCandidates instead
0517 template <>
0518 bool HLTDoubletDZ<l1t::TrackerMuon, l1t::TrackerMuon>::hltFilter(
0519     edm::Event& iEvent, const edm::EventSetup& iSetup, trigger::TriggerFilterObjectWithRefs& filterproduct) const {
0520   // All HLT filters must create and fill an HLT filter object,
0521   // recording any reconstructed physics objects satisfying (or not)
0522   // this HLT filter, and place it in the Event.
0523   bool accept(false);
0524 
0525   std::vector<l1t::TrackerMuonRef> coll1;
0526   std::vector<l1t::TrackerMuonRef> coll2;
0527 
0528   if (getCollections(iEvent, coll1, coll2, filterproduct)) {
0529     int n(0);
0530     l1t::TrackerMuonRef r1;
0531     l1t::TrackerMuonRef r2;
0532 
0533     for (unsigned int i1 = 0; i1 != coll1.size(); i1++) {
0534       r1 = coll1[i1];
0535       unsigned int I(0);
0536       if (same_) {
0537         I = i1 + 1;
0538       }
0539       for (unsigned int i2 = I; i2 != coll2.size(); i2++) {
0540         r2 = coll2[i2];
0541 
0542         if (!computeDZ(iEvent, r1, r2))
0543           continue;
0544 
0545         n++;
0546         filterproduct.addObject(triggerType1_, r1);
0547         filterproduct.addObject(triggerType2_, r2);
0548       }
0549     }
0550 
0551     accept = accept || (n >= min_N_);
0552   }
0553 
0554   return accept;
0555 }
0556 
0557 /// Special instantiation for L1PFTau
0558 /// L1PFTau are *not* RecoCandidates, therefore they don't implement superCluster()
0559 /// They are LeafCandidates instead
0560 template <>
0561 bool HLTDoubletDZ<l1t::PFTau, l1t::PFTau>::hltFilter(edm::Event& iEvent,
0562                                                      const edm::EventSetup& iSetup,
0563                                                      trigger::TriggerFilterObjectWithRefs& filterproduct) const {
0564   // All HLT filters must create and fill an HLT filter object,
0565   // recording any reconstructed physics objects satisfying (or not)
0566   // this HLT filter, and place it in the Event.
0567   bool accept(false);
0568 
0569   std::vector<l1t::PFTauRef> coll1;
0570   std::vector<l1t::PFTauRef> coll2;
0571 
0572   if (getCollections(iEvent, coll1, coll2, filterproduct)) {
0573     int n(0);
0574     l1t::PFTauRef r1;
0575     l1t::PFTauRef r2;
0576 
0577     for (unsigned int i1 = 0; i1 != coll1.size(); i1++) {
0578       r1 = coll1[i1];
0579       unsigned int I(0);
0580       if (same_) {
0581         I = i1 + 1;
0582       }
0583       for (unsigned int i2 = I; i2 != coll2.size(); i2++) {
0584         r2 = coll2[i2];
0585 
0586         if (!computeDZ(iEvent, r1, r2))
0587           continue;
0588 
0589         n++;
0590         filterproduct.addObject(triggerType1_, r1);
0591         filterproduct.addObject(triggerType2_, r2);
0592       }
0593     }
0594 
0595     accept = accept || (n >= min_N_);
0596   }
0597 
0598   return accept;
0599 }
0600 
0601 /// Special instantiation for L1HPSPFTau
0602 /// L1HPSPFTau are *not* RecoCandidates, therefore they don't implement superCluster()
0603 /// They are LeafCandidates instead
0604 template <>
0605 bool HLTDoubletDZ<l1t::HPSPFTau, l1t::HPSPFTau>::hltFilter(edm::Event& iEvent,
0606                                                            const edm::EventSetup& iSetup,
0607                                                            trigger::TriggerFilterObjectWithRefs& filterproduct) const {
0608   // All HLT filters must create and fill an HLT filter object,
0609   // recording any reconstructed physics objects satisfying (or not)
0610   // this HLT filter, and place it in the Event.
0611   bool accept(false);
0612 
0613   std::vector<l1t::HPSPFTauRef> coll1;
0614   std::vector<l1t::HPSPFTauRef> coll2;
0615 
0616   if (getCollections(iEvent, coll1, coll2, filterproduct)) {
0617     int n(0);
0618     l1t::HPSPFTauRef r1;
0619     l1t::HPSPFTauRef r2;
0620 
0621     for (unsigned int i1 = 0; i1 != coll1.size(); i1++) {
0622       r1 = coll1[i1];
0623       unsigned int I(0);
0624       if (same_) {
0625         I = i1 + 1;
0626       }
0627       for (unsigned int i2 = I; i2 != coll2.size(); i2++) {
0628         r2 = coll2[i2];
0629 
0630         if (!computeDZ(iEvent, r1, r2))
0631           continue;
0632 
0633         n++;
0634         filterproduct.addObject(triggerType1_, r1);
0635         filterproduct.addObject(triggerType2_, r2);
0636       }
0637     }
0638 
0639     accept = accept || (n >= min_N_);
0640   }
0641 
0642   return accept;
0643 }
0644 
0645 typedef HLTDoubletDZ<reco::Electron, reco::Electron> HLT2ElectronElectronDZ;
0646 typedef HLTDoubletDZ<reco::RecoChargedCandidate, reco::RecoChargedCandidate> HLT2MuonMuonDZ;
0647 typedef HLTDoubletDZ<reco::Electron, reco::RecoChargedCandidate> HLT2ElectronMuonDZ;
0648 typedef HLTDoubletDZ<reco::RecoEcalCandidate, reco::RecoEcalCandidate> HLT2PhotonPhotonDZ;
0649 typedef HLTDoubletDZ<reco::RecoChargedCandidate, reco::RecoEcalCandidate> HLT2MuonPhotonDZ;
0650 typedef HLTDoubletDZ<reco::RecoEcalCandidate, reco::RecoChargedCandidate> HLT2PhotonMuonDZ;
0651 typedef HLTDoubletDZ<l1t::TrackerMuon, l1t::TrackerMuon> HLT2L1TkMuonL1TkMuonDZ;
0652 typedef HLTDoubletDZ<l1t::PFTau, l1t::PFTau> HLT2L1PFTauL1PFTauDZ;
0653 typedef HLTDoubletDZ<l1t::HPSPFTau, l1t::HPSPFTau> HLT2L1HPSPFTauL1HPSPFTauDZ;
0654 
0655 DEFINE_FWK_MODULE(HLT2ElectronElectronDZ);
0656 DEFINE_FWK_MODULE(HLT2MuonMuonDZ);
0657 DEFINE_FWK_MODULE(HLT2ElectronMuonDZ);
0658 DEFINE_FWK_MODULE(HLT2PhotonPhotonDZ);
0659 DEFINE_FWK_MODULE(HLT2PhotonMuonDZ);
0660 DEFINE_FWK_MODULE(HLT2MuonPhotonDZ);
0661 DEFINE_FWK_MODULE(HLT2L1TkMuonL1TkMuonDZ);
0662 DEFINE_FWK_MODULE(HLT2L1PFTauL1PFTauDZ);
0663 DEFINE_FWK_MODULE(HLT2L1HPSPFTauL1HPSPFTauDZ);