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  modules = []
364  src = collection
365  prevsrc = None
366  for mod in mods[:-1]:
367  src, prevsrc = _getModule(process, src, mod[0], "".join(reversed(mod[:-1])),
368  options[mod[0]][mod[1]], isCosmics = isCosmics, prevsrc = prevsrc,
369  **(mod[2])), src
370  modules.append(getattr(process, src))
371  else:
372  if mods[-1][-1]["method"] == "load" and \
373  not mods[-1][-1].get("clone", False):
374  print("Name of the last module needs to be modifiable.")
375  sys.exit(1)
376 
377  if g4Refitting:
378  print("Here we must include geopro first")
379  process.load('Configuration.StandardSequences.GeometryDB_cff')
380  process.load("TrackPropagation.Geant4e.geantRefit_cff")
381  modules.append(getattr(process,"geopro"))
382 
383  src = _getModule(process, src, mods[-1][0], "FinalTrackRefitter",
384  options[mods[-1][0]][mods[-1][1]],
385  isCosmics = isCosmics, **(mods[-1][2]))
386  modules.append(getattr(process, src))
387 
388  moduleSum = process.offlineBeamSpot # first element of the sequence
389  if g4Refitting:
390  # g4Refitter needs measurements
391  moduleSum += getattr(process,"MeasurementTrackerEvent")
392 
393  for module in modules:
394  # Spply srcConstr fix here
395  if hasattr(module,"srcConstr"):
396  strSrcConstr = module.srcConstr.getModuleLabel()
397  if strSrcConstr:
398  procsrcconstr = getattr(process,strSrcConstr)
399  if hasattr(procsrcconstr,"src"): # Momentum or track parameter constraints
400  if procsrcconstr.src != module.src:
401  module.srcConstr=''
402  module.constraint=''
403  else:
404  moduleSum += procsrcconstr # Add constraint
405  elif hasattr(procsrcconstr,"srcTrk"): # Vertex constraint
406  if procsrcconstr.srcTrk != module.src:
407  module.srcConstr=''
408  module.constraint=''
409  else:
410  procsrcconstrsrcvtx = getattr(process,procsrcconstr.srcVtx.getModuleLabel())
411  if type(procsrcconstrsrcvtx) is cms.EDFilter: # If source of vertices is itself a filter (e.g. good PVs)
412  procsrcconstrsrcvtxprefilter = getattr(process,procsrcconstrsrcvtx.src.getModuleLabel())
413  moduleSum += procsrcconstrsrcvtxprefilter # Add vertex source to constraint before filter
414  moduleSum += procsrcconstrsrcvtx # Add vertex source to constraint
415  moduleSum += procsrcconstr # Add constraint
416 
417  moduleSum += module # append the other modules
418 
419  return cms.Sequence(moduleSum)
420 
421 
428 
429 
430 def _getModule(process, src, modType, moduleName, options, **kwargs):
431  """General function for attaching the module of type `modType` to the
432  cms.Process `process` using `options` for customization and `moduleName` as
433  the name of the new attribute of `process`.
434 
435  Arguments:
436  - `process`: 'cms.Process' object to which the module is attached.
437  - `src`: cms.InputTag for this module.
438  - `modType`: Type of the requested module.
439  - `options`: Dictionary with customized values for the module's options.
440  - `**kwargs`: Used to supply options at construction time of the module.
441  """
442 
443  objTuple = globals()["_"+modType](kwargs)
444  method = kwargs.get("method")
445  if method == "import":
446  __import__(objTuple[0])
447  obj = getattr(sys.modules[objTuple[0]], objTuple[1]).clone()
448  elif method == "load":
449  process.load(objTuple[0])
450  if kwargs.get("clone", False):
451  obj = getattr(process, objTuple[1]).clone(src=src)
452  else:
453  obj = getattr(process, objTuple[1])
454  moduleName = objTuple[1]
455  else:
456  print("Unknown method:", method)
457  sys.exit(1)
458 
459  if modType == "TrackSplitting":
460  #track splitting takes the TrackSelector as tracks
461  # and the first TrackRefitter as tjTkAssociationMapTag
462  _customSetattr(obj, "tracks", src)
463  _customSetattr(obj, "tjTkAssociationMapTag", kwargs["prevsrc"])
464  else:
465  obj.src = src
466 
467  for option in options:
468  _customSetattr(obj, option, options[option])
469 
470  if moduleName is not objTuple[1]:
471  setattr(process, moduleName, obj)
472  return moduleName
473 
474 
475 def _TrackHitFilter(kwargs):
476  """Returns TrackHitFilter module name.
477 
478  Arguments:
479  - `kwargs`: Not used in this function.
480  """
481 
482  return ("RecoTracker.FinalTrackSelectors.TrackerTrackHitFilter_cff",
483  "TrackerTrackHitFilter")
484 
485 
486 def _TrackSelector(kwargs):
487  """Returns TrackSelector module name.
488 
489  Arguments:
490  - `kwargs`: Not used in this function.
491  """
492 
493  return ("Alignment.CommonAlignmentProducer.AlignmentTrackSelector_cfi",
494  "AlignmentTrackSelector")
495 
496 
497 def _TrackFitter(kwargs):
498  """Returns TrackFitter module name.
499 
500  Arguments:
501  - `kwargs`: Used to supply options at construction time of the object.
502  """
503 
504  isCosmics = kwargs.get("isCosmics", False)
505  if isCosmics:
506  return ("RecoTracker.TrackProducer.CTFFinalFitWithMaterialP5_cff",
507  "ctfWithMaterialTracksCosmics")
508  else:
509  return ("RecoTracker.TrackProducer.CTFFinalFitWithMaterial_cff",
510  "ctfWithMaterialTracks")
511 
512 
513 def _TrackRefitter(kwargs):
514  """Returns TrackRefitter module name.
515 
516  Arguments:
517  - `kwargs`: Used to supply options at construction time of the object.
518  """
519 
520  isCosmics = kwargs.get("isCosmics", False)
521  if isCosmics:
522  return ("RecoTracker.TrackProducer.TrackRefitters_cff",
523  "TrackRefitterP5")
524  else:
525  return ("RecoTracker.TrackProducer.TrackRefitters_cff",
526  "TrackRefitter")
527 
528 def _TrackSplitting(kwargs):
529  return ("RecoTracker.FinalTrackSelectors.cosmicTrackSplitter_cfi",
530  "cosmicTrackSplitter")
531 
532 def _geopro(kwargs):
533  return ("TrackPropagation.Geant4e.geantRefit_cff","geopro")
534 
535 
536 def _customSetattr(obj, attr, val):
537  """Sets the attribute `attr` of the object `obj` using the value `val`.
538  `attr` can be a string or a tuple of strings, if one wants to set an
539  attribute of an attribute, etc.
540 
541  Arguments:
542  - `obj`: Object, which must have a '__dict__' attribute.
543  - `attr`: String or tuple of strings describing the attribute's name.
544  - `val`: value of the attribute.
545  """
546 
547  if isinstance(attr, tuple) and len(attr) > 1:
548  _customSetattr(getattr(obj, attr[0]), attr[1:], val)
549  else:
550  if isinstance(attr, tuple): attr = attr[0]
551  setattr(obj, attr, val)
552 
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)