CMS 3D CMS Logo

SingleLongTrackProducer.cc
Go to the documentation of this file.
1 // user includes
12 
13 // ROOT includes
14 #include "TLorentzVector.h"
15 
17 public:
19  ~SingleLongTrackProducer() override = default;
20 
21  static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
22 
23 private:
24  void produce(edm::Event &, const edm::EventSetup &) override;
25 
29 
30  const int minNumberOfLayers;
31  const double matchInDr;
32  const bool onlyValidHits;
33  const bool debug;
34  const double minPt;
35  const double maxEta;
36  const double maxDxy;
37  const double maxDz;
38 };
39 
41  : tracksToken{consumes<reco::TrackCollection>(iConfig.getParameter<edm::InputTag>("allTracks"))},
42  muonsToken{consumes<std::vector<reco::Muon>>(iConfig.getParameter<edm::InputTag>("matchMuons"))},
43  PrimVtxToken{consumes<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("PrimaryVertex"))},
44  minNumberOfLayers{iConfig.getParameter<int>("minNumberOfLayers")},
45  matchInDr{iConfig.getParameter<double>("requiredDr")},
46  onlyValidHits{iConfig.getParameter<bool>("onlyValidHits")},
47  debug{iConfig.getParameter<bool>("debug")},
48  minPt{iConfig.getParameter<double>("minPt")},
49  maxEta{iConfig.getParameter<double>("maxEta")},
50  maxDxy{iConfig.getParameter<double>("maxDxy")},
51  maxDz{iConfig.getParameter<double>("maxDz")} {
52  produces<reco::TrackCollection>("").setBranchAlias("");
53 }
54 
56  using namespace edm;
57 
58  // register output collection:
59  std::unique_ptr<reco::TrackCollection> goodTracks(new reco::TrackCollection);
60 
61  // register input collections:
62  const auto &tracks = iEvent.getHandle(tracksToken);
63  if (!tracks.isValid()) {
64  edm::LogError("SingleLongTrackProducer")
65  << "Input track collection is not valid.\n Returning empty output track collection.";
66  iEvent.put(std::move(goodTracks), "");
67  return;
68  }
69 
70  const auto &muons = iEvent.getHandle(muonsToken);
71  if (!muons.isValid() && matchInDr > 0.) {
72  edm::LogError("SingleLongTrackProducer")
73  << "Input muon collection is not valid.\n Returning empty output track collection.";
74  iEvent.put(std::move(goodTracks), "");
75  return;
76  }
77 
78  const auto &vertices = iEvent.getHandle(PrimVtxToken);
79  if (!vertices.isValid()) {
80  edm::LogError("SingleLongTrackProducer")
81  << "Input vertex collection is not valid.\n Returning empty output track collection.";
82  iEvent.put(std::move(goodTracks), "");
83  return;
84  }
85 
86  // Preselection of long quality tracks
87  const reco::Vertex &vtx = vertices->at(0);
88  std::vector<reco::Track> selTracks;
89  reco::Track bestTrack;
90  unsigned int tMuon = 0;
91  double fitProb = std::numeric_limits<double>::max();
92 
93  for (const auto &track : *tracks) {
94  const reco::HitPattern &hitpattern = track.hitPattern();
95  double dR2min = std::numeric_limits<double>::max();
96  double chiNdof = track.normalizedChi2();
97  double dxy = std::abs(track.dxy(vtx.position()));
98  double dz = std::abs(track.dz(vtx.position()));
99 
100  if (track.pt() < minPt || std::abs(track.eta()) > maxEta ||
102  continue;
103  }
104 
105  if (matchInDr > 0.0) {
106  for (const auto &muon : *muons) {
107  if (muon.isTrackerMuon()) {
108  tMuon++;
109  double dr2 = reco::deltaR2(track, *(muon.innerTrack()));
110  dR2min = std::min(dR2min, dr2);
111  }
112  }
113  if (dR2min >= matchInDr * matchInDr)
114  continue;
115  }
116 
117  if (dxy < maxDxy && dz < maxDz && track.validFraction() >= 1.0 && chiNdof < fitProb) {
118  fitProb = chiNdof;
119  bestTrack = track;
120  }
121 
122  if (debug) {
123  edm::LogPrint("SingleLongTrackProducer") << "deltaR2 (general) track to matched Track: " << dR2min
124  << " chi2Ndof: " << chiNdof << " best Track chi2Ndof: " << fitProb;
125  }
126  }
127 
128  // Only push if bestTrack was set
129  if (bestTrack.recHitsOk()) {
130  selTracks.push_back(bestTrack);
131  }
132 
133  if (debug)
134  edm::LogPrint("SingleLongTrackProducer")
135  << " number of Tracker Muons: " << tMuon << ", thereof " << selTracks.size() << " tracks passed preselection.";
136 
137  // check hits validity in preselected tracks
138  bool hitIsNotValid{false};
139 
140  for (const auto &track : selTracks) {
141  // Check validity of track extra and rechits
142  if (track.recHitsOk()) {
143  reco::HitPattern hitpattern = track.hitPattern();
144  auto hb = track.recHitsBegin();
145 
146  // Checking if rechits are valid
147  for (unsigned int h = 0; h < track.recHitsSize(); h++) {
148  auto recHit = *(hb + h);
149  auto const &hit = *recHit;
150  if (onlyValidHits && !hit.isValid()) {
151  hitIsNotValid = true;
152  continue;
153  }
154  }
155 
156  if (hitIsNotValid == true)
157  break; // (Un)Comment this line to (not) allow for events with not valid hits
158 
159  // Checking if hitpattern hits are valid
160  for (unsigned int h = 0; h < track.recHitsSize(); h++) {
161  uint32_t pHit = hitpattern.getHitPattern(reco::HitPattern::TRACK_HITS, h);
162  if (onlyValidHits && !(hitpattern.validHitFilter(pHit))) {
163  if (debug)
164  edm::LogPrint("SingleLongTrackProducer") << "hit not valid: " << h;
165  continue;
166  }
167  }
168  goodTracks->push_back(track);
169  } else
170  break;
171  }
172 
173  if (debug) {
174  auto const &moduleType = moduleDescription().moduleName();
175  auto const &moduleLabel = moduleDescription().moduleLabel();
176  edm::LogPrint("SingleLongTrackProducer") << "[" << moduleType << "] (" << moduleLabel << ") "
177  << " output track size: " << goodTracks.get()->size();
178  }
179 
180  // save track collection in event:
181  iEvent.put(std::move(goodTracks), "");
182 }
183 
186  desc.add<edm::InputTag>("allTracks", edm::InputTag("generalTracks"))->setComment("input track collection");
187  desc.add<edm::InputTag>("matchMuons", edm::InputTag("earlyMuons"))->setComment("input muon collection for matching");
188  desc.add<edm::InputTag>("PrimaryVertex", edm::InputTag("offlinePrimaryVertices"))
189  ->setComment("input primary vertex collection");
190  desc.add<int>("minNumberOfLayers", 10)->setComment("minimum number of layers");
191  desc.add<double>("requiredDr", 0.01)->setComment("matching muons deltaR. If negative do not match");
192  desc.add<bool>("onlyValidHits", true)->setComment("use only valid hits");
193  desc.add<bool>("debug", false)->setComment("verbose?");
194  desc.add<double>("minPt", 15.0)->setComment("minimum pT");
195  desc.add<double>("maxEta", 2.2)->setComment("maximum pseudorapidity (absolute value)");
196  desc.add<double>("maxDxy", 0.02)->setComment("maximum transverse impact parameter");
197  desc.add<double>("maxDz", 0.5)->setComment("maximum longitudinal impact parameter");
198  descriptions.addWithDefaultLabel(desc);
199 }
200 
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
bool recHitsOk() const
Definition: Track.h:161
const edm::EDGetTokenT< std::vector< reco::Track > > tracksToken
int trackerLayersWithMeasurement() const
Definition: HitPattern.cc:534
SingleLongTrackProducer(const edm::ParameterSet &)
const edm::EDGetTokenT< std::vector< reco::Muon > > muonsToken
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:14
minPt
Definition: PV_cfg.py:223
Log< level::Error, false > LogError
muons
the two sets of parameters below are mutually exclusive, depending if RECO or ALCARECO is used the us...
Definition: DiMuonV_cfg.py:214
static bool validHitFilter(uint16_t pattern)
Definition: HitPattern.h:796
int iEvent
Definition: GenABIO.cc:224
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
Log< level::Warning, true > LogPrint
~SingleLongTrackProducer() override=default
uint16_t getHitPattern(HitCategory category, int position) const
Definition: HitPattern.h:537
const edm::EDGetTokenT< reco::VertexCollection > PrimVtxToken
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
#define debug
Definition: HDRShower.cc:19
void produce(edm::Event &, const edm::EventSetup &) override
HLT enums.
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
def move(src, dest)
Definition: eostools.py:511