CMS 3D CMS Logo

trackselectionRefitting.py
Go to the documentation of this file.
1 from __future__ import print_function
2 import sys
3 import FWCore.ParameterSet.Config as cms
4 
5 def getSequence(process, collection,
6  saveCPU = False,
7  TTRHBuilder = "WithAngleAndTemplate",
8  usePixelQualityFlag = None,
9  openMassWindow = False,
10  cosmicsDecoMode = False,
11  cosmicsZeroTesla = True,
12  momentumConstraint = None,
13  cosmicTrackSplitting = False,
14  isPVValidation = False,
15  use_d0cut = True,
16  g4Refitting = False):
17  """This function returns a cms.Sequence containing as last element the
18  module 'FinalTrackRefitter', which can be used as cms.InputTag for
19  subsequent processing steps.
20  The modules in the sequence are already attached to the given `process`
21  object using the given track collection `collection` and the given
22  optional arguments.
23 
24  Arguments:
25  - `process`: 'cms.Process' object to which the modules of the sequence will
26  be attached.
27  - `collection`: String indicating the input track collection.
28  - `saveCPU`: If set to 'True', some steps are merged to reduce CPU time.
29  Reduces a little the accuracy of the results.
30  This option is currently not recommended.
31  - `TTRHBuilder`: Option used for the Track(Re)Fitter modules.
32  - `usePixelQualityFlag`: Option used for the TrackHitFilter module.
33  Defaults to 'True' but is automatically set to
34  'False' if a `TTRHBuilder` without templates is
35  used.
36  If this is still wanted for some reason, one can
37  explicitely specify it as 'True'.
38  - `openMassWindow`: Used to configure the TwoBodyDecaySelector for ZMuMu.
39  - `cosmicsDecoMode`: If set to 'True' a lower Signal/Noise cut is used.
40  - `cosmicsZeroTesla`: If set to 'True' a 0T-specific selection is used.
41  - `momentumConstraint`: If you want to apply a momentum constraint for the
42  track refitting, e.g. for CRUZET data, you need
43  to provide here the name of the constraint module.
44  - `cosmicTrackSplitting`: If set to 'True' cosmic tracks are split before the
45  second track refitter.
46  - `isPVValidation`: If set to 'True' most of the selection cuts are overridden
47  to allow unbiased selection of tracks for vertex refitting
48  - `use_d0cut`: If 'True' (default), apply a cut |d0| < 50.
49  """
50 
51 
54 
55  print("g4Refitting=",g4Refitting)
56 
57  if usePixelQualityFlag is None:
58  if "Template" not in TTRHBuilder:
59  usePixelQualityFlag = False # not defined without templates
60  print("Using 'TTRHBuilder' without templates:", TTRHBuilder)
61  print(" --> Turning off pixel quality flag in hit filter.")
62  else:
63  usePixelQualityFlag = True # default for usage with templates
64 
65 
66 
69 
70  options = {"TrackHitFilter": {},
71  "TrackFitter": {},
72  "TrackRefitter": {},
73  "TrackSelector": {},
74  "geopro": {} }
75 
76  options["TrackSelector"]["HighPurity"] = {
77  "trackQualities": ["highPurity"],
78  "filter": True,
79  "etaMin": -3.0,
80  "etaMax": 3.0,
81  "pMin": 8.0
82  }
83  options["TrackSelector"]["Alignment"] = {
84  "filter": True,
85  "pMin": 3.0,
86  "nHitMin2D": 2,
87  "d0Min": -50.0,
88  "d0Max": 50.0,
89  "etaMin": -3.0,
90  "etaMax": 3.0,
91  "nHitMin": 8,
92  "chi2nMax": 9999.0
93  }
94  options["TrackRefitter"]["First"] = {
95  "NavigationSchool": "",
96  "TTRHBuilder": TTRHBuilder,
97  }
98  options["TrackRefitter"]["Second"] = {
99  "NavigationSchool": "",
100  "TTRHBuilder": TTRHBuilder,
101  }
102  options["TrackHitFilter"]["Tracker"] = {
103  "useTrajectories": True,
104  "minimumHits": 8,
105  "commands": cms.vstring("keep PXB", "keep PXE", "keep TIB", "keep TID",
106  "keep TOB", "keep TEC"),
107  "replaceWithInactiveHits": True,
108  "rejectBadStoNHits": True,
109  "rejectLowAngleHits": True,
110  "usePixelQualityFlag": usePixelQualityFlag,
111  "StoNcommands": cms.vstring("ALL 12.0"),
112  "TrackAngleCut": 0.087,
113  }
114  options["TrackFitter"]["HitFilteredTracks"] = {
115  "NavigationSchool": "",
116  "TTRHBuilder": TTRHBuilder,
117  }
118  options["geopro"][""] = {
119  }
120 
121  if g4Refitting:
122  options["TrackRefitter"]["Second"] = {
123  "AlgorithmName" : cms.string('undefAlgorithm'),
124  "Fitter" : cms.string('G4eFitterSmoother'),
125  "GeometricInnerState" : cms.bool(False),
126  "MeasurementTracker" : cms.string(''),
127  "MeasurementTrackerEvent" : cms.InputTag("MeasurementTrackerEvent"),
128  "NavigationSchool" : cms.string('SimpleNavigationSchool'), # Correct?
129  "Propagator" : cms.string('Geant4ePropagator'),
130  "TTRHBuilder" : cms.string('WithAngleAndTemplate'),
131  "TrajectoryInEvent" : cms.bool(True),
132  "beamSpot" : cms.InputTag("offlineBeamSpot"),
133  "constraint" : cms.string(''),
134  "src" : cms.InputTag("AlignmentTrackSelector"),
135  "srcConstr" : cms.InputTag(""),
136  "useHitsSplitting" : cms.bool(False),
137  "usePropagatorForPCA" : cms.bool(True) # not sure whether it is needed
138  }
139 
140 
143  isCosmics = False
144 
145  if collection in ("ALCARECOTkAlMinBias", "generalTracks",
146  "ALCARECOTkAlMinBiasHI", "hiGeneralTracks",
147  "ALCARECOTkAlJetHT", "ALCARECOTkAlDiMuonVertexTracks"):
148  options["TrackSelector"]["Alignment"].update({
149  "ptMin": 1.0,
150  "pMin": 8.,
151  })
152  options["TrackHitFilter"]["Tracker"].update({
153  "minimumHits": 10,
154  })
155  elif collection in ("ALCARECOTkAlCosmicsCTF0T",
156  "ALCARECOTkAlCosmicsInCollisions"):
157  isCosmics = True
158  options["TrackSelector"]["HighPurity"] = {} # drop high purity cut
159  if not cosmicsDecoMode:
160  options["TrackHitFilter"]["Tracker"].update({
161  "StoNcommands": cms.vstring("ALL 18.0")
162  })
163  if cosmicsZeroTesla:
164  options["TrackHitFilter"]["Tracker"].update({
165  "TrackAngleCut": 0.1 # Run-I: 0.087 for 0T
166  })
167  else:
168  options["TrackHitFilter"]["Tracker"].update({
169  "TrackAngleCut": 0.1 # Run-I: 0.35 for 3.8T
170  })
171  options["TrackSelector"]["Alignment"].update({
172  "pMin": 4.0,
173  "etaMin": -99.0,
174  "etaMax": 99.0,
175  "applyMultiplicityFilter": True,
176  "maxMultiplicity": 1
177  })
178  if cosmicTrackSplitting:
179  options["TrackSplitting"] = {}
180  options["TrackSplitting"]["TrackSplitting"] = {}
181  if not use_d0cut:
182  options["TrackSelector"]["Alignment"].update({
183  "d0Min": -99999.0,
184  "d0Max": 99999.0,
185  })
186  elif collection in ("ALCARECOTkAlMuonIsolated",
187  "ALCARECOTkAlMuonIsolatedHI",
188  "ALCARECOTkAlMuonIsolatedPA"):
189  options["TrackSelector"]["Alignment"].update({
190  ("minHitsPerSubDet", "inPIXEL"): 1,
191  "ptMin": 5.0,
192  "nHitMin": 10,
193  "applyMultiplicityFilter": True,
194  "maxMultiplicity": 1,
195  })
196  elif collection in ("ALCARECOTkAlZMuMu",
197  "ALCARECOTkAlZMuMuHI",
198  "ALCARECOTkAlZMuMuPA",
199  "ALCARECOTkAlDiMuon"):
200  options["TrackSelector"]["Alignment"].update({
201  "ptMin": 15.0,
202  "etaMin": -3.0,
203  "etaMax": 3.0,
204  "nHitMin": 10,
205  "applyMultiplicityFilter": True,
206  "minMultiplicity": 2,
207  "maxMultiplicity": 2,
208  ("minHitsPerSubDet", "inPIXEL"): 1,
209  ("TwoBodyDecaySelector", "applyChargeFilter"): True,
210  ("TwoBodyDecaySelector", "charge"): 0,
211  ("TwoBodyDecaySelector",
212  "applyMassrangeFilter"): not openMassWindow,
213  ("TwoBodyDecaySelector", "minXMass"): 85.8,
214  ("TwoBodyDecaySelector", "maxXMass"): 95.8,
215  ("TwoBodyDecaySelector", "daughterMass"): 0.105
216  })
217  options["TrackHitFilter"]["Tracker"].update({
218  "minimumHits": 10,
219  })
220  elif collection == "ALCARECOTkAlUpsilonMuMu":
221  options["TrackSelector"]["Alignment"].update({
222  "ptMin": 3.0,
223  "etaMin": -2.4,
224  "etaMax": 2.4,
225  "nHitMin": 10,
226  "applyMultiplicityFilter": True,
227  "minMultiplicity": 2,
228  "maxMultiplicity": 2,
229  ("minHitsPerSubDet", "inPIXEL"): 1,
230  ("TwoBodyDecaySelector", "applyChargeFilter"): True,
231  ("TwoBodyDecaySelector", "charge"): 0,
232  ("TwoBodyDecaySelector",
233  "applyMassrangeFilter"): not openMassWindow,
234  ("TwoBodyDecaySelector", "minXMass"): 9.2,
235  ("TwoBodyDecaySelector", "maxXMass"): 9.7,
236  ("TwoBodyDecaySelector", "daughterMass"): 0.105
237  })
238  options["TrackHitFilter"]["Tracker"].update({
239  "minimumHits": 10,
240  })
241  elif collection == "ALCARECOTkAlJpsiMuMu":
242  options["TrackSelector"]["Alignment"].update({
243  "ptMin": 1.0,
244  "etaMin": -2.4,
245  "etaMax": 2.4,
246  "nHitMin": 10,
247  "applyMultiplicityFilter": True,
248  "minMultiplicity": 2,
249  "maxMultiplicity": 2,
250  ("minHitsPerSubDet", "inPIXEL"): 1,
251  ("TwoBodyDecaySelector", "applyChargeFilter"): True,
252  ("TwoBodyDecaySelector", "charge"): 0,
253  ("TwoBodyDecaySelector",
254  "applyMassrangeFilter"): not openMassWindow,
255  ("TwoBodyDecaySelector", "minXMass"): 2.7,
256  ("TwoBodyDecaySelector", "maxXMass"): 3.4,
257  ("TwoBodyDecaySelector", "daughterMass"): 0.105
258  })
259  options["TrackHitFilter"]["Tracker"].update({
260  "minimumHits": 10,
261  })
262  else:
263  raise ValueError("Unknown input track collection: {}".format(collection))
264 
265  if cosmicTrackSplitting and not isCosmics:
266  raise ValueError("Can only do cosmic track splitting for cosmics.")
267 
268 
269 
270 
273 
274  if saveCPU:
275  if cosmicTrackSplitting:
276  raise ValueError("Can't turn on both saveCPU and cosmicTrackSplitting at the same time")
277  mods = [("TrackSelector", "Alignment", {"method": "load"}),
278  ("TrackRefitter", "First", {"method": "load",
279  "clone": True}),
280  ("TrackHitFilter", "Tracker", {"method": "load"}),
281  ("TrackFitter", "HitFilteredTracks", {"method": "import"})]
282  options["TrackSelector"]["Alignment"].update(
283  options["TrackSelector"]["HighPurity"])
284  elif cosmicTrackSplitting:
285  mods = [("TrackRefitter", "First", {"method": "load",
286  "clone": True}),
287  ("TrackSelector", "Alignment", {"method": "load"}),
288  ("TrackSplitting", "TrackSplitting", {"method": "load"}),
289  ("TrackFitter", "HitFilteredTracks", {"method": "import"}),
290  ("TrackRefitter", "Second", {"method": "load",
291  "clone": True})]
292  elif g4Refitting:
293  mods = [("TrackSelector", "HighPurity", {"method": "import"}),
294  ("TrackRefitter", "First", {"method": "load",
295  "clone": True}),
296  ("TrackHitFilter", "Tracker", {"method": "load"}),
297  ("TrackFitter", "HitFilteredTracks", {"method": "import"}),
298  ("TrackSelector", "Alignment", {"method": "load"}),
299  #("geopro","", {"method": "load"}),
300  ("TrackRefitter", "Second", {"method": "load",
301  "clone": True})]
302  if isCosmics: mods = mods[1:] # skip high purity selector for cosmics
303  else:
304  mods = [("TrackSelector", "HighPurity", {"method": "import"}),
305  ("TrackRefitter", "First", {"method": "load",
306  "clone": True}),
307  ("TrackHitFilter", "Tracker", {"method": "load"}),
308  ("TrackFitter", "HitFilteredTracks", {"method": "import"}),
309  ("TrackSelector", "Alignment", {"method": "load"}),
310  ("TrackRefitter", "Second", {"method": "load",
311  "clone": True})]
312  if isCosmics: mods = mods[1:] # skip high purity selector for cosmics
313 
314 
317 
318  if isPVValidation:
319  options["TrackSelector"]["HighPurity"].update({
320  "trackQualities": [],
321  "pMin": 0.
322  })
323  options["TrackSelector"]["Alignment"].update({
324  "pMin" : 0.,
325  "ptMin" : 0.,
326  "nHitMin2D" : 0,
327  "nHitMin" : 0,
328  "d0Min" : -999999.0,
329  "d0Max" : 999999.0,
330  "dzMin" : -999999.0,
331  "dzMax" : 999999.0
332  })
333 
334 
337 
338  if momentumConstraint is not None:
339  for mod in options["TrackRefitter"]:
340  momconstrspecs = momentumConstraint.split(',')
341  if len(momconstrspecs)==1:
342  options["TrackRefitter"][mod].update({
343  "constraint": "momentum",
344  "srcConstr": momconstrspecs[0]
345  })
346  else:
347  options["TrackRefitter"][mod].update({
348  "constraint": momconstrspecs[1],
349  "srcConstr": momconstrspecs[0]
350  })
351 
352 
353 
354 
357  process.load("RecoVertex.BeamSpotProducer.BeamSpot_cff")
358 
359 
362 
363  if "Fast" in TTRHBuilder:
364  print("PixelCPEFast has been chosen, here we must include CUDAService first")
365  process.load('HeterogeneousCore.CUDAServices.CUDAService_cfi')
366 
367  modules = []
368  src = collection
369  prevsrc = None
370  for mod in mods[:-1]:
371  src, prevsrc = _getModule(process, src, mod[0], "".join(reversed(mod[:-1])),
372  options[mod[0]][mod[1]], isCosmics = isCosmics, prevsrc = prevsrc,
373  **(mod[2])), src
374  modules.append(getattr(process, src))
375  else:
376  if mods[-1][-1]["method"] == "load" and \
377  not mods[-1][-1].get("clone", False):
378  print("Name of the last module needs to be modifiable.")
379  sys.exit(1)
380 
381  if g4Refitting:
382  print("Here we must include geopro first")
383  process.load('Configuration.StandardSequences.GeometryDB_cff')
384  process.load("TrackPropagation.Geant4e.geantRefit_cff")
385  modules.append(getattr(process,"geopro"))
386 
387  src = _getModule(process, src, mods[-1][0], "FinalTrackRefitter",
388  options[mods[-1][0]][mods[-1][1]],
389  isCosmics = isCosmics, **(mods[-1][2]))
390  modules.append(getattr(process, src))
391 
392  moduleSum = process.offlineBeamSpot # first element of the sequence
393  if g4Refitting:
394  # g4Refitter needs measurements
395  moduleSum += getattr(process,"MeasurementTrackerEvent")
396 
397  for module in modules:
398  # Spply srcConstr fix here
399  if hasattr(module,"srcConstr"):
400  strSrcConstr = module.srcConstr.getModuleLabel()
401  if strSrcConstr:
402  procsrcconstr = getattr(process,strSrcConstr)
403  if hasattr(procsrcconstr,"src"): # Momentum or track parameter constraints
404  if procsrcconstr.src != module.src:
405  module.srcConstr=''
406  module.constraint=''
407  else:
408  moduleSum += procsrcconstr # Add constraint
409  elif hasattr(procsrcconstr,"srcTrk"): # Vertex constraint
410  if procsrcconstr.srcTrk != module.src:
411  module.srcConstr=''
412  module.constraint=''
413  else:
414  procsrcconstrsrcvtx = getattr(process,procsrcconstr.srcVtx.getModuleLabel())
415  if type(procsrcconstrsrcvtx) is cms.EDFilter: # If source of vertices is itself a filter (e.g. good PVs)
416  procsrcconstrsrcvtxprefilter = getattr(process,procsrcconstrsrcvtx.src.getModuleLabel())
417  moduleSum += procsrcconstrsrcvtxprefilter # Add vertex source to constraint before filter
418  moduleSum += procsrcconstrsrcvtx # Add vertex source to constraint
419  moduleSum += procsrcconstr # Add constraint
420 
421  moduleSum += module # append the other modules
422 
423  return cms.Sequence(moduleSum)
424 
425 
432 
433 
434 def _getModule(process, src, modType, moduleName, options, **kwargs):
435  """General function for attaching the module of type `modType` to the
436  cms.Process `process` using `options` for customization and `moduleName` as
437  the name of the new attribute of `process`.
438 
439  Arguments:
440  - `process`: 'cms.Process' object to which the module is attached.
441  - `src`: cms.InputTag for this module.
442  - `modType`: Type of the requested module.
443  - `options`: Dictionary with customized values for the module's options.
444  - `**kwargs`: Used to supply options at construction time of the module.
445  """
446 
447  objTuple = globals()["_"+modType](kwargs)
448  method = kwargs.get("method")
449  if method == "import":
450  __import__(objTuple[0])
451  obj = getattr(sys.modules[objTuple[0]], objTuple[1]).clone()
452  elif method == "load":
453  process.load(objTuple[0])
454  if kwargs.get("clone", False):
455  obj = getattr(process, objTuple[1]).clone(src=src)
456  else:
457  obj = getattr(process, objTuple[1])
458  moduleName = objTuple[1]
459  else:
460  print("Unknown method:", method)
461  sys.exit(1)
462 
463  if modType == "TrackSplitting":
464  #track splitting takes the TrackSelector as tracks
465  # and the first TrackRefitter as tjTkAssociationMapTag
466  _customSetattr(obj, "tracks", src)
467  _customSetattr(obj, "tjTkAssociationMapTag", kwargs["prevsrc"])
468  else:
469  obj.src = src
470 
471  for option in options:
472  _customSetattr(obj, option, options[option])
473 
474  if moduleName is not objTuple[1]:
475  setattr(process, moduleName, obj)
476  return moduleName
477 
478 
479 def _TrackHitFilter(kwargs):
480  """Returns TrackHitFilter module name.
481 
482  Arguments:
483  - `kwargs`: Not used in this function.
484  """
485 
486  return ("RecoTracker.FinalTrackSelectors.TrackerTrackHitFilter_cff",
487  "TrackerTrackHitFilter")
488 
489 
490 def _TrackSelector(kwargs):
491  """Returns TrackSelector module name.
492 
493  Arguments:
494  - `kwargs`: Not used in this function.
495  """
496 
497  return ("Alignment.CommonAlignmentProducer.AlignmentTrackSelector_cfi",
498  "AlignmentTrackSelector")
499 
500 
501 def _TrackFitter(kwargs):
502  """Returns TrackFitter module name.
503 
504  Arguments:
505  - `kwargs`: Used to supply options at construction time of the object.
506  """
507 
508  isCosmics = kwargs.get("isCosmics", False)
509  if isCosmics:
510  return ("RecoTracker.TrackProducer.CTFFinalFitWithMaterialP5_cff",
511  "ctfWithMaterialTracksCosmics")
512  else:
513  return ("RecoTracker.TrackProducer.CTFFinalFitWithMaterial_cff",
514  "ctfWithMaterialTracks")
515 
516 
517 def _TrackRefitter(kwargs):
518  """Returns TrackRefitter module name.
519 
520  Arguments:
521  - `kwargs`: Used to supply options at construction time of the object.
522  """
523 
524  isCosmics = kwargs.get("isCosmics", False)
525  if isCosmics:
526  return ("RecoTracker.TrackProducer.TrackRefitters_cff",
527  "TrackRefitterP5")
528  else:
529  return ("RecoTracker.TrackProducer.TrackRefitters_cff",
530  "TrackRefitter")
531 
532 def _TrackSplitting(kwargs):
533  return ("RecoTracker.FinalTrackSelectors.cosmicTrackSplitter_cfi",
534  "cosmicTrackSplitter")
535 
536 def _geopro(kwargs):
537  return ("TrackPropagation.Geant4e.geantRefit_cff","geopro")
538 
539 
540 def _customSetattr(obj, attr, val):
541  """Sets the attribute `attr` of the object `obj` using the value `val`.
542  `attr` can be a string or a tuple of strings, if one wants to set an
543  attribute of an attribute, etc.
544 
545  Arguments:
546  - `obj`: Object, which must have a '__dict__' attribute.
547  - `attr`: String or tuple of strings describing the attribute's name.
548  - `val`: value of the attribute.
549  """
550 
551  if isinstance(attr, tuple) and len(attr) > 1:
552  _customSetattr(getattr(obj, attr[0]), attr[1:], val)
553  else:
554  if isinstance(attr, tuple): attr = attr[0]
555  setattr(obj, attr, val)
556 
def _customSetattr(obj, attr, val)
def getSequence(process, collection, saveCPU=False, TTRHBuilder="WithAngleAndTemplate", usePixelQualityFlag=None, openMassWindow=False, cosmicsDecoMode=False, cosmicsZeroTesla=True, momentumConstraint=None, cosmicTrackSplitting=False, isPVValidation=False, use_d0cut=True, g4Refitting=False)
def _getModule(process, src, modType, moduleName, options, kwargs)
Auxiliary functions ###
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
static std::string join(char **cmd)
Definition: RemoteFile.cc:19
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
#define update(a, b)