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  const reco::Vertex vtx = vertices->at(0);
87 
88  // Preselection of long quality tracks
89  std::vector<reco::Track> selTracks;
90  reco::Track bestTrack;
91  unsigned int tMuon = 0;
92  double fitProb = 100;
93 
94  for (const auto &track : *tracks) {
95  const reco::HitPattern &hitpattern = track.hitPattern();
96  double dR2min = 100.;
97  double chiNdof = track.normalizedChi2();
98  double dxy = std::abs(track.dxy(vtx.position()));
99  double dz = std::abs(track.dz(vtx.position()));
100 
101  if (track.pt() < minPt)
102  continue;
103 
104  if (std::abs(track.eta()) > maxEta)
105  continue;
106 
108  continue;
109 
110  // Long track needs to be close to a good muon (only if requested)
111  if (matchInDr > 0.) {
112  for (const auto &m : *muons) {
113  if (m.isTrackerMuon()) {
114  tMuon++;
115  reco::Track matchedTrack = *(m.innerTrack());
116  // match to general track in deltaR
117  double dr2 = reco::deltaR2(track, matchedTrack);
118  if (dr2 < dR2min)
119  dR2min = dr2;
120  }
121  }
122  // matchInDr here is defined positive
123  if (dR2min >= matchInDr * matchInDr)
124  continue;
125  }
126  // do vertex consistency:
127  bool vertex_match = dxy < maxDxy && dz < maxDz;
128  if (!(vertex_match))
129  continue;
130  if (track.validFraction() < 1.0)
131  continue;
132  // only save the track with the smallest chiNdof
133  if (chiNdof < fitProb) {
134  fitProb = chiNdof;
135  bestTrack = track;
136  bestTrack.setExtra(track.extra());
137  }
138  if (debug)
139  edm::LogPrint("SingleLongTrackProducer") << " deltaR2 (general) track to matched Track: " << dR2min;
140  if (debug)
141  edm::LogPrint("SingleLongTrackProducer") << "chi2Ndof:" << chiNdof << " best Track: " << fitProb;
142  }
143 
144  selTracks.push_back(bestTrack);
145 
146  if (debug)
147  edm::LogPrint("SingleLongTrackProducer")
148  << " number of Tracker Muons: " << tMuon << ", thereof " << selTracks.size() << " tracks passed preselection.";
149 
150  // check hits validity in preselected tracks
151  bool hitIsNotValid{false};
152 
153  for (const auto &track : selTracks) {
154  reco::HitPattern hitpattern = track.hitPattern();
155  int deref{0};
156 
157  // this checks track recHits
158  try { // (Un)Comment this line with /* to (not) allow for events with not valid hits
159  auto hb = track.recHitsBegin();
160 
161  for (unsigned int h = 0; h < track.recHitsSize(); h++) {
162  auto recHit = *(hb + h);
163  auto const &hit = *recHit;
164 
165  if (onlyValidHits && !hit.isValid()) {
166  hitIsNotValid = true;
167  continue;
168  }
169  }
170  } catch (cms::Exception const &e) {
171  deref += 1;
172  if (debug)
173  std::cerr << e.explainSelf() << std::endl;
174  }
175 
176  if (hitIsNotValid == true)
177  break; // (Un)Comment this line with */ to (not) allow for events with not valid hits
178 
179  int deref2{0};
180 
181  // this checks track hitPattern hits
182  try {
183  auto hb = track.recHitsBegin();
184 
185  for (unsigned int h = 0; h < track.recHitsSize(); h++) {
186  uint32_t pHit = hitpattern.getHitPattern(reco::HitPattern::TRACK_HITS, h);
187 
188  auto recHit = *(hb + h);
189  auto const &hit = *recHit;
190 
191  if (onlyValidHits && !hit.isValid()) {
192  if (debug)
193  edm::LogPrint("SingleLongTrackProducer") << "hit not valid: " << h;
194  continue;
195  }
196 
197  // loop over the hits of the track.
198  if (onlyValidHits && !(hitpattern.validHitFilter(pHit))) {
199  if (debug)
200  edm::LogPrint("SingleLongTrackProducer") << "hit not valid: " << h;
201  continue;
202  }
203  }
204  goodTracks->push_back(track);
205  } catch (cms::Exception const &e) {
206  deref2 += 1;
207  if (debug)
208  std::cerr << e.explainSelf() << std::endl;
209  }
210 
211  if (debug)
212  edm::LogPrint("SingleLongTrackProducer")
213  << "found tracks with " << deref << "missing valid hits and " << deref2 << " missing hit pattern";
214  }
215 
216  if (debug) {
217  auto const &moduleType = moduleDescription().moduleName();
218  auto const &moduleLabel = moduleDescription().moduleLabel();
219  edm::LogPrint("SingleLongTrackProducer") << "[" << moduleType << "] (" << moduleLabel << ") "
220  << " output track size: " << goodTracks.get()->size();
221  }
222 
223  // save track collection in event:
224  iEvent.put(std::move(goodTracks), "");
225 }
226 
229  desc.add<edm::InputTag>("allTracks", edm::InputTag("generalTracks"))->setComment("input track collection");
230  desc.add<edm::InputTag>("matchMuons", edm::InputTag("earlyMuons"))->setComment("input muon collection for matching");
231  desc.add<edm::InputTag>("PrimaryVertex", edm::InputTag("offlinePrimaryVertices"))
232  ->setComment("input primary vertex collection");
233  desc.add<int>("minNumberOfLayers", 10)->setComment("minimum number of layers");
234  desc.add<double>("requiredDr", 0.01)->setComment("matching muons deltaR. If negative do not match");
235  desc.add<bool>("onlyValidHits", true)->setComment("use only valid hits");
236  desc.add<bool>("debug", false)->setComment("verbose?");
237  desc.add<double>("minPt", 15.0)->setComment("minimum pT");
238  desc.add<double>("maxEta", 2.2)->setComment("maximum pseudorapidity (absolute value)");
239  desc.add<double>("maxDxy", 0.02)->setComment("maximum transverse impact parameter");
240  desc.add<double>("maxDz", 0.5)->setComment("maximum longitudinal impact parameter");
241  descriptions.addWithDefaultLabel(desc);
242 }
243 
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
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
void setExtra(const TrackExtraRef &ref)
set reference to "extra" object
Definition: Track.h:136
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