CMS 3D CMS Logo

CAHitNtupletGenerator.cc
Go to the documentation of this file.
1 //#define GPU_DEBUG
2 //#define DUMP_GPU_TK_TUPLES
3 
4 #include <array>
5 #include <cassert>
6 #include <functional>
7 #include <vector>
8 
9 #include <alpaka/alpaka.hpp>
10 
18 
19 #include "CAHitNtupletGenerator.h"
21 #include "CAPixelDoublets.h"
22 #include "CAPixelDoubletsAlgos.h"
23 
25  namespace {
26 
27  using namespace caHitNtupletGenerator;
28  using namespace caPixelDoublets;
29  using namespace pixelTopology;
30  using namespace pixelTrack;
31 
32  template <typename T>
33  T sqr(T x) {
34  return x * x;
35  }
36 
37  //Common Params
38  void fillDescriptionsCommon(edm::ParameterSetDescription& desc) {
39  // 87 cm/GeV = 1/(3.8T * 0.3)
40  // take less than radius given by the hardPtCut and reject everything below
41  // auto hardCurvCut = 1.f/(0.35 * 87.f);
42  desc.add<double>("ptmin", 0.9f)->setComment("Cut on minimum pt");
43  desc.add<double>("CAThetaCutBarrel", 0.002f)->setComment("Cut on RZ alignement for Barrel");
44  desc.add<double>("CAThetaCutForward", 0.003f)->setComment("Cut on RZ alignment for Forward");
45  desc.add<double>("hardCurvCut", 1.f / (0.35 * 87.f))
46  ->setComment("Cut on minimum curvature, used in DCA ntuplet selection");
47  desc.add<double>("dcaCutInnerTriplet", 0.15f)->setComment("Cut on origin radius when the inner hit is on BPix1");
48  desc.add<double>("dcaCutOuterTriplet", 0.25f)->setComment("Cut on origin radius when the outer hit is on BPix1");
49  desc.add<bool>("earlyFishbone", true);
50  desc.add<bool>("lateFishbone", false);
51  desc.add<bool>("fillStatistics", false);
52  desc.add<unsigned int>("minHitsPerNtuplet", 4);
53  desc.add<unsigned int>("minHitsForSharingCut", 10)
54  ->setComment("Maximum number of hits in a tuple to clean also if the shared hit is on bpx1");
55 
56  desc.add<bool>("fitNas4", false)->setComment("fit only 4 hits out of N");
57  desc.add<bool>("doClusterCut", true);
58  desc.add<bool>("doZ0Cut", true);
59  desc.add<bool>("doPtCut", true);
60  desc.add<bool>("useRiemannFit", false)->setComment("true for Riemann, false for BrokenLine");
61  desc.add<bool>("doSharedHitCut", true)->setComment("Sharing hit nTuples cleaning");
62  desc.add<bool>("dupPassThrough", false)->setComment("Do not reject duplicate");
63  desc.add<bool>("useSimpleTripletCleaner", true)->setComment("use alternate implementation");
64  }
65 
66  AlgoParams makeCommonParams(edm::ParameterSet const& cfg) {
67  return AlgoParams({cfg.getParameter<unsigned int>("minHitsForSharingCut"),
68  cfg.getParameter<bool>("useRiemannFit"),
69  cfg.getParameter<bool>("fitNas4"),
70  cfg.getParameter<bool>("includeJumpingForwardDoublets"),
71  cfg.getParameter<bool>("earlyFishbone"),
72  cfg.getParameter<bool>("lateFishbone"),
73  cfg.getParameter<bool>("fillStatistics"),
74  cfg.getParameter<bool>("doSharedHitCut"),
75  cfg.getParameter<bool>("dupPassThrough"),
76  cfg.getParameter<bool>("useSimpleTripletCleaner")});
77  }
78 
79  //This is needed to have the partial specialization for isPhase1Topology/isPhase2Topology
80  template <typename TrackerTraits, typename Enable = void>
81  struct TopologyCuts {};
82 
83  template <typename TrackerTraits>
84  struct TopologyCuts<TrackerTraits, isPhase1Topology<TrackerTraits>> {
85  static constexpr CAParamsT<TrackerTraits> makeCACuts(edm::ParameterSet const& cfg) {
86  return CAParamsT<TrackerTraits>{{cfg.getParameter<unsigned int>("maxNumberOfDoublets"),
87  cfg.getParameter<unsigned int>("minHitsPerNtuplet"),
88  (float)cfg.getParameter<double>("ptmin"),
89  (float)cfg.getParameter<double>("CAThetaCutBarrel"),
90  (float)cfg.getParameter<double>("CAThetaCutForward"),
91  (float)cfg.getParameter<double>("hardCurvCut"),
92  (float)cfg.getParameter<double>("dcaCutInnerTriplet"),
93  (float)cfg.getParameter<double>("dcaCutOuterTriplet")}};
94  };
95 
96  static constexpr ::pixelTrack::QualityCutsT<TrackerTraits> makeQualityCuts(edm::ParameterSet const& pset) {
97  auto coeff = pset.getParameter<std::array<double, 2>>("chi2Coeff");
98  auto ptMax = pset.getParameter<double>("chi2MaxPt");
99 
100  coeff[1] = (coeff[1] - coeff[0]) / log2(ptMax);
101  return ::pixelTrack::QualityCutsT<TrackerTraits>{// polynomial coefficients for the pT-dependent chi2 cut
102  {(float)coeff[0], (float)coeff[1], 0.f, 0.f},
103  // max pT used to determine the chi2 cut
104  (float)ptMax,
105  // chi2 scale factor: 8 for broken line fit, ?? for Riemann fit
106  (float)pset.getParameter<double>("chi2Scale"),
107  // regional cuts for triplets
108  {(float)pset.getParameter<double>("tripletMaxTip"),
109  (float)pset.getParameter<double>("tripletMinPt"),
110  (float)pset.getParameter<double>("tripletMaxZip")},
111  // regional cuts for quadruplets
112  {(float)pset.getParameter<double>("quadrupletMaxTip"),
113  (float)pset.getParameter<double>("quadrupletMinPt"),
114  (float)pset.getParameter<double>("quadrupletMaxZip")}};
115  }
116  };
117 
118  template <typename TrackerTraits>
119  struct TopologyCuts<TrackerTraits, isPhase2Topology<TrackerTraits>> {
120  static constexpr CAParamsT<TrackerTraits> makeCACuts(edm::ParameterSet const& cfg) {
121  return CAParamsT<TrackerTraits>{{cfg.getParameter<unsigned int>("maxNumberOfDoublets"),
122  cfg.getParameter<unsigned int>("minHitsPerNtuplet"),
123  (float)cfg.getParameter<double>("ptmin"),
124  (float)cfg.getParameter<double>("CAThetaCutBarrel"),
125  (float)cfg.getParameter<double>("CAThetaCutForward"),
126  (float)cfg.getParameter<double>("hardCurvCut"),
127  (float)cfg.getParameter<double>("dcaCutInnerTriplet"),
128  (float)cfg.getParameter<double>("dcaCutOuterTriplet")},
129  {(bool)cfg.getParameter<bool>("includeFarForwards")}};
130  }
131 
132  static constexpr ::pixelTrack::QualityCutsT<TrackerTraits> makeQualityCuts(edm::ParameterSet const& pset) {
133  return ::pixelTrack::QualityCutsT<TrackerTraits>{
134  static_cast<float>(pset.getParameter<double>("maxChi2")),
135  static_cast<float>(pset.getParameter<double>("minPt")),
136  static_cast<float>(pset.getParameter<double>("maxTip")),
137  static_cast<float>(pset.getParameter<double>("maxZip")),
138  };
139  }
140  };
141 
142  //Cell Cuts, as they are the cuts have the same logic for Phase2 and Phase1
143  //keeping them separate would allow further differentiation in the future
144  //moving them to TopologyCuts and using the same syntax
145  template <typename TrackerTraits>
146  CellCutsT<TrackerTraits> makeCellCuts(edm::ParameterSet const& cfg) {
147  return CellCutsT<TrackerTraits>{cfg.getParameter<bool>("doClusterCut"),
148  cfg.getParameter<bool>("doZ0Cut"),
149  cfg.getParameter<bool>("doPtCut"),
150  cfg.getParameter<bool>("idealConditions"),
151  (float)cfg.getParameter<double>("cellZ0Cut"),
152  (float)cfg.getParameter<double>("cellPtCut"),
153  cfg.getParameter<std::vector<int>>("phiCuts")};
154  }
155 
156  } // namespace
157 
158  using namespace std;
159 
160  template <typename TrackerTraits>
162  : m_params(makeCommonParams(cfg),
163  makeCellCuts<TrackerTraits>(cfg),
164  TopologyCuts<TrackerTraits>::makeQualityCuts(cfg.getParameterSet("trackQualityCuts")),
165  TopologyCuts<TrackerTraits>::makeCACuts(cfg)) {
166 #ifdef DUMP_GPU_TK_TUPLES
167  printf("TK: %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n",
168  "tid",
169  "qual",
170  "nh",
171  "nl",
172  "charge",
173  "pt",
174  "eta",
175  "phi",
176  "tip",
177  "zip",
178  "chi2",
179  "h1",
180  "h2",
181  "h3",
182  "h4",
183  "h5",
184  "hn");
185 #endif
186  }
187 
188  template <typename TrackerTraits>
190  static_assert(sizeof(TrackerTraits) == 0,
191  "Note: this fillPSetDescription is a dummy one. Please specialise it for the correct version of "
192  "CAHitNtupletGenerator<TrackerTraits>.");
193  }
194 
195  template <>
197  fillDescriptionsCommon(desc);
198 
199  desc.add<unsigned int>("maxNumberOfDoublets", pixelTopology::Phase1::maxNumberOfDoublets);
200  desc.add<bool>("idealConditions", true);
201  desc.add<bool>("includeJumpingForwardDoublets", false);
202  desc.add<double>("cellZ0Cut", 12.0);
203  desc.add<double>("cellPtCut", 0.5);
204 
206  trackQualityCuts.add<double>("chi2MaxPt", 10.)->setComment("max pT used to determine the pT-dependent chi2 cut");
207  trackQualityCuts.add<std::vector<double>>("chi2Coeff", {0.9, 1.8})->setComment("chi2 at 1GeV and at ptMax above");
208  trackQualityCuts.add<double>("chi2Scale", 8.)
209  ->setComment(
210  "Factor to multiply the pT-dependent chi2 cut (currently: 8 for the broken line fit, ?? for the Riemann "
211  "fit)");
212  trackQualityCuts.add<double>("tripletMinPt", 0.5)->setComment("Min pT for triplets, in GeV");
213  trackQualityCuts.add<double>("tripletMaxTip", 0.3)->setComment("Max |Tip| for triplets, in cm");
214  trackQualityCuts.add<double>("tripletMaxZip", 12.)->setComment("Max |Zip| for triplets, in cm");
215  trackQualityCuts.add<double>("quadrupletMinPt", 0.3)->setComment("Min pT for quadruplets, in GeV");
216  trackQualityCuts.add<double>("quadrupletMaxTip", 0.5)->setComment("Max |Tip| for quadruplets, in cm");
217  trackQualityCuts.add<double>("quadrupletMaxZip", 12.)->setComment("Max |Zip| for quadruplets, in cm");
218  desc.add<edm::ParameterSetDescription>("trackQualityCuts", trackQualityCuts)
219  ->setComment(
220  "Quality cuts based on the results of the track fit:\n - apply a pT-dependent chi2 cut;\n - apply "
221  "\"region "
222  "cuts\" based on the fit results (pT, Tip, Zip).");
223 
224  desc.add<std::vector<int>>(
225  "phiCuts",
226  std::vector<int>(std::begin(phase1PixelTopology::phicuts), std::end(phase1PixelTopology::phicuts)))
227  ->setComment("Cuts in phi for cells");
228  }
229 
230  template <>
232  fillDescriptionsCommon(desc);
233 
234  desc.add<unsigned int>("maxNumberOfDoublets", pixelTopology::HIonPhase1::maxNumberOfDoublets);
235  desc.add<bool>("idealConditions", false);
236  desc.add<bool>("includeJumpingForwardDoublets", false);
237  desc.add<double>("cellZ0Cut", 10.0);
238  desc.add<double>("cellPtCut", 0.0);
239 
241  trackQualityCuts.add<double>("chi2MaxPt", 10.)->setComment("max pT used to determine the pT-dependent chi2 cut");
242  trackQualityCuts.add<std::vector<double>>("chi2Coeff", {0.9, 1.8})->setComment("chi2 at 1GeV and at ptMax above");
243  trackQualityCuts.add<double>("chi2Scale", 8.)
244  ->setComment(
245  "Factor to multiply the pT-dependent chi2 cut (currently: 8 for the broken line fit, ?? for the Riemann "
246  "fit)");
247  trackQualityCuts.add<double>("tripletMinPt", 0.0)->setComment("Min pT for triplets, in GeV");
248  trackQualityCuts.add<double>("tripletMaxTip", 0.1)->setComment("Max |Tip| for triplets, in cm");
249  trackQualityCuts.add<double>("tripletMaxZip", 6.)->setComment("Max |Zip| for triplets, in cm");
250  trackQualityCuts.add<double>("quadrupletMinPt", 0.0)->setComment("Min pT for quadruplets, in GeV");
251  trackQualityCuts.add<double>("quadrupletMaxTip", 0.5)->setComment("Max |Tip| for quadruplets, in cm");
252  trackQualityCuts.add<double>("quadrupletMaxZip", 6.)->setComment("Max |Zip| for quadruplets, in cm");
253 
254  desc.add<edm::ParameterSetDescription>("trackQualityCuts", trackQualityCuts)
255  ->setComment(
256  "Quality cuts based on the results of the track fit:\n - apply a pT-dependent chi2 cut;\n - apply "
257  "\"region "
258  "cuts\" based on the fit results (pT, Tip, Zip).");
259 
260  desc.add<std::vector<int>>(
261  "phiCuts",
262  std::vector<int>(std::begin(phase1PixelTopology::phicuts), std::end(phase1PixelTopology::phicuts)))
263  ->setComment("Cuts in phi for cells");
264  }
265 
266  template <>
268  fillDescriptionsCommon(desc);
269 
270  desc.add<unsigned int>("maxNumberOfDoublets", pixelTopology::Phase2::maxNumberOfDoublets);
271  desc.add<bool>("idealConditions", false);
272  desc.add<bool>("includeFarForwards", true);
273  desc.add<bool>("includeJumpingForwardDoublets", true);
274  desc.add<double>("cellZ0Cut", 7.5);
275  desc.add<double>("cellPtCut", 0.85);
276 
278  trackQualityCuts.add<double>("maxChi2", 5.)->setComment("Max normalized chi2");
279  trackQualityCuts.add<double>("minPt", 0.5)->setComment("Min pT in GeV");
280  trackQualityCuts.add<double>("maxTip", 0.3)->setComment("Max |Tip| in cm");
281  trackQualityCuts.add<double>("maxZip", 12.)->setComment("Max |Zip|, in cm");
282  desc.add<edm::ParameterSetDescription>("trackQualityCuts", trackQualityCuts)
283  ->setComment(
284  "Quality cuts based on the results of the track fit:\n - apply cuts based on the fit results (pT, Tip, "
285  "Zip).");
286 
287  desc.add<std::vector<int>>(
288  "phiCuts",
289  std::vector<int>(std::begin(phase2PixelTopology::phicuts), std::end(phase2PixelTopology::phicuts)))
290  ->setComment("Cuts in phi for cells");
291  }
292 
293  template <typename TrackerTraits>
295  HitsOnDevice const& hits_d, ParamsOnDevice const* cpeParams, float bfield, Queue& queue) const {
299 
301 
302  // Don't bother if less than 2 this
303  if (hits_d.view().metadata().size() < 2) {
304  const auto device = alpaka::getDev(queue);
305  auto ntracks_d = cms::alpakatools::make_device_view(device, tracks.view().nTracks());
306  alpaka::memset(queue, ntracks_d, 0);
307  return tracks;
308  }
309  GPUKernels kernels(m_params, hits_d.view().metadata().size(), hits_d.offsetBPIX2(), queue);
310 
311  kernels.buildDoublets(hits_d.view(), hits_d.offsetBPIX2(), queue);
312  kernels.launchKernels(hits_d.view(), hits_d.offsetBPIX2(), tracks.view(), queue);
313 
314  HelixFit fitter(bfield, m_params.fitNas4_);
315  fitter.allocate(kernels.tupleMultiplicity(), tracks.view());
316  if (m_params.useRiemannFit_) {
317  fitter.launchRiemannKernels(
318  hits_d.view(), cpeParams, hits_d.view().metadata().size(), TrackerTraits::maxNumberOfQuadruplets, queue);
319  } else {
321  hits_d.view(), cpeParams, hits_d.view().metadata().size(), TrackerTraits::maxNumberOfQuadruplets, queue);
322  }
323  kernels.classifyTuples(hits_d.view(), tracks.view(), queue);
324 #ifdef GPU_DEBUG
326  std::cout << "finished building pixel tracks on GPU" << std::endl;
327 #endif
328 
329  return tracks;
330  }
331 
335 } // namespace ALPAKA_ACCELERATOR_NAMESPACE
constexpr int16_t phicuts[nPairs]
typename std::enable_if< std::is_base_of< Phase2, T >::value >::type isPhase2Topology
void launchBrokenLineKernels(const HitConstView &hv, ParamsOnDevice const *cpeParams, uint32_t nhits, uint32_t maxNumberOfTuples, Queue &queue)
TrackingRecHitsSoACollection< TrackerTraits > HitsOnDevice
std::enable_if_t< not std::is_array_v< T >, device_view< TDev, T > > make_device_view(TDev const &device, T &data)
Definition: memory.h:260
typename std::enable_if< std::is_base_of< Phase1, T >::value >::type isPhase1Topology
TkSoADevice makeTuplesAsync(HitsOnDevice const &hits_d, ParamsOnDevice const *cpeParams, float bfield, Queue &queue) const
constexpr int16_t phicuts[nPairs]
static constexpr uint32_t maxNumberOfDoublets
std::conditional_t< std::is_same_v< Device, alpaka::DevCpu >, TracksHost< TrackerTraits >, TracksDevice< TrackerTraits, Device > > TracksSoACollection
ParameterSet const & getParameterSet(ParameterSetID const &id)
static constexpr uint32_t maxNumberOfDoublets
void launchRiemannKernels(const HitConstView &hv, ParamsOnDevice const *cpeParams, uint32_t nhits, uint32_t maxNumberOfTuples, Queue &queue)
static constexpr uint32_t maxNumberOfDoublets
Square< F >::type sqr(const F &f)
Definition: Square.h:14
static void fillPSetDescription(edm::ParameterSetDescription &desc)
float x
void allocate(TupleMultiplicity const *tupleMultiplicity, OutputSoAView &helix_fit_results)
Definition: HelixFit.cc:6
long double T