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 customlog(s):
6  print("# MSG-i trackselectionRefitting: %s" % s)
7 
8 def getSequence(process, collection,
9  saveCPU = False,
10  TTRHBuilder = "WithAngleAndTemplate",
11  usePixelQualityFlag = None,
12  openMassWindow = False,
13  cosmicsDecoMode = False,
14  cosmicsZeroTesla = True,
15  momentumConstraint = None,
16  cosmicTrackSplitting = False,
17  isPVValidation = False,
18  use_d0cut = True,
19  g4Refitting = False):
20  """This function returns a cms.Sequence containing as last element the
21  module 'FinalTrackRefitter', which can be used as cms.InputTag for
22  subsequent processing steps.
23  The modules in the sequence are already attached to the given `process`
24  object using the given track collection `collection` and the given
25  optional arguments.
26 
27  Arguments:
28  - `process`: 'cms.Process' object to which the modules of the sequence will
29  be attached.
30  - `collection`: String indicating the input track collection.
31  - `saveCPU`: If set to 'True', some steps are merged to reduce CPU time.
32  Reduces a little the accuracy of the results.
33  This option is currently not recommended.
34  - `TTRHBuilder`: Option used for the Track(Re)Fitter modules.
35  - `usePixelQualityFlag`: Option used for the TrackHitFilter module.
36  Defaults to 'True' but is automatically set to
37  'False' if a `TTRHBuilder` without templates is
38  used.
39  If this is still wanted for some reason, one can
40  explicitely specify it as 'True'.
41  - `openMassWindow`: Used to configure the TwoBodyDecaySelector for ZMuMu.
42  - `cosmicsDecoMode`: If set to 'True' a lower Signal/Noise cut is used.
43  - `cosmicsZeroTesla`: If set to 'True' a 0T-specific selection is used.
44  - `momentumConstraint`: If you want to apply a momentum constraint for the
45  track refitting, e.g. for CRUZET data, you need
46  to provide here the name of the constraint module.
47  - `cosmicTrackSplitting`: If set to 'True' cosmic tracks are split before the
48  second track refitter.
49  - `isPVValidation`: If set to 'True' most of the selection cuts are overridden
50  to allow unbiased selection of tracks for vertex refitting
51  - `use_d0cut`: If 'True' (default), apply a cut |d0| < 50.
52  """
53 
54 
57 
58  customlog("g4Refitting=%s" % g4Refitting)
59 
60  if usePixelQualityFlag is None:
61  if "Template" not in TTRHBuilder:
62  usePixelQualityFlag = False # not defined without templates
63  customlog("Using 'TTRHBuilder' without templates %s" % TTRHBuilder)
64  customlog(" --> Turning off pixel quality flag in hit filter.")
65  else:
66  usePixelQualityFlag = True # default for usage with templates
67 
68 
69 
72 
73  options = {"TrackHitFilter": {},
74  "TrackFitter": {},
75  "TrackRefitter": {},
76  "TrackSelector": {},
77  "geopro": {} }
78 
79  options["TrackSelector"]["HighPurity"] = {
80  "trackQualities": ["highPurity"],
81  "filter": True,
82  "etaMin": -3.0,
83  "etaMax": 3.0,
84  "pMin": 8.0
85  }
86  options["TrackSelector"]["Alignment"] = {
87  "filter": True,
88  "pMin": 3.0,
89  "nHitMin2D": 2,
90  "d0Min": -50.0,
91  "d0Max": 50.0,
92  "etaMin": -3.0,
93  "etaMax": 3.0,
94  "nHitMin": 8,
95  "chi2nMax": 9999.0
96  }
97  options["TrackRefitter"]["First"] = {
98  "NavigationSchool": "",
99  "TTRHBuilder": TTRHBuilder,
100  }
101  options["TrackRefitter"]["Second"] = {
102  "NavigationSchool": "",
103  "TTRHBuilder": TTRHBuilder,
104  }
105  options["TrackHitFilter"]["Tracker"] = {
106  "useTrajectories": True,
107  "minimumHits": 8,
108  "commands": cms.vstring("keep PXB", "keep PXE", "keep TIB", "keep TID",
109  "keep TOB", "keep TEC"),
110  "replaceWithInactiveHits": True,
111  "rejectBadStoNHits": True,
112  "rejectLowAngleHits": True,
113  "usePixelQualityFlag": usePixelQualityFlag,
114  "StoNcommands": cms.vstring("ALL 12.0"),
115  "TrackAngleCut": 0.087,
116  }
117  options["TrackFitter"]["HitFilteredTracks"] = {
118  "NavigationSchool": "",
119  "TTRHBuilder": TTRHBuilder,
120  }
121  options["geopro"][""] = {
122  }
123 
124  if g4Refitting:
125  options["TrackRefitter"]["Second"] = {
126  "AlgorithmName" : cms.string('undefAlgorithm'),
127  "Fitter" : cms.string('G4eFitterSmoother'),
128  "GeometricInnerState" : cms.bool(False),
129  "MeasurementTracker" : cms.string(''),
130  "MeasurementTrackerEvent" : cms.InputTag("MeasurementTrackerEvent"),
131  "NavigationSchool" : cms.string('SimpleNavigationSchool'), # Correct?
132  "Propagator" : cms.string('Geant4ePropagator'),
133  "TTRHBuilder" : cms.string('WithAngleAndTemplate'),
134  "TrajectoryInEvent" : cms.bool(True),
135  "beamSpot" : cms.InputTag("offlineBeamSpot"),
136  "constraint" : cms.string(''),
137  "src" : cms.InputTag("AlignmentTrackSelector"),
138  "srcConstr" : cms.InputTag(""),
139  "useHitsSplitting" : cms.bool(False),
140  "usePropagatorForPCA" : cms.bool(True) # not sure whether it is needed
141  }
142 
143 
146  isCosmics = False
147 
148  if collection in ("ALCARECOTkAlMinBias", "generalTracks",
149  "ALCARECOTkAlMinBiasHI", "hiGeneralTracks",
150  "ALCARECOTkAlJetHT", "ALCARECOTkAlDiMuonVertexTracks"):
151  options["TrackSelector"]["Alignment"].update({
152  "ptMin": 1.0,
153  "pMin": 8.,
154  })
155  options["TrackHitFilter"]["Tracker"].update({
156  "minimumHits": 10,
157  })
158  elif collection in ("ALCARECOTkAlCosmicsCTF0T",
159  "ALCARECOTkAlCosmicsCosmicTF0T",
160  "ALCARECOTkAlCosmicsInCollisions"):
161  isCosmics = True
162  options["TrackSelector"]["HighPurity"] = {} # drop high purity cut
163  if not cosmicsDecoMode:
164  options["TrackHitFilter"]["Tracker"].update({
165  "StoNcommands": cms.vstring("ALL 18.0")
166  })
167  if cosmicsZeroTesla:
168  options["TrackHitFilter"]["Tracker"].update({
169  "TrackAngleCut": 0.1 # Run-I: 0.087 for 0T
170  })
171  else:
172  options["TrackHitFilter"]["Tracker"].update({
173  "TrackAngleCut": 0.1 # Run-I: 0.35 for 3.8T
174  })
175  options["TrackSelector"]["Alignment"].update({
176  "pMin": 4.0,
177  "etaMin": -99.0,
178  "etaMax": 99.0,
179  "applyMultiplicityFilter": True,
180  "maxMultiplicity": 1
181  })
182  if cosmicTrackSplitting:
183  options["TrackSplitting"] = {}
184  options["TrackSplitting"]["TrackSplitting"] = {}
185  if not use_d0cut:
186  options["TrackSelector"]["Alignment"].update({
187  "d0Min": -99999.0,
188  "d0Max": 99999.0,
189  })
190  elif collection in ("ALCARECOTkAlMuonIsolated",
191  "ALCARECOTkAlMuonIsolatedHI",
192  "ALCARECOTkAlMuonIsolatedPA"):
193  options["TrackSelector"]["Alignment"].update({
194  ("minHitsPerSubDet", "inPIXEL"): 1,
195  "ptMin": 5.0,
196  "nHitMin": 10,
197  "applyMultiplicityFilter": True,
198  "maxMultiplicity": 1,
199  })
200  elif collection in ("ALCARECOTkAlZMuMu",
201  "ALCARECOTkAlZMuMuHI",
202  "ALCARECOTkAlZMuMuPA",
203  "ALCARECOTkAlDiMuon"):
204  options["TrackSelector"]["Alignment"].update({
205  "ptMin": 15.0,
206  "etaMin": -3.0,
207  "etaMax": 3.0,
208  "nHitMin": 10,
209  "applyMultiplicityFilter": True,
210  "minMultiplicity": 2,
211  "maxMultiplicity": 2,
212  ("minHitsPerSubDet", "inPIXEL"): 1,
213  ("TwoBodyDecaySelector", "applyChargeFilter"): True,
214  ("TwoBodyDecaySelector", "charge"): 0,
215  ("TwoBodyDecaySelector",
216  "applyMassrangeFilter"): not openMassWindow,
217  ("TwoBodyDecaySelector", "minXMass"): 85.8,
218  ("TwoBodyDecaySelector", "maxXMass"): 95.8,
219  ("TwoBodyDecaySelector", "daughterMass"): 0.105
220  })
221  options["TrackHitFilter"]["Tracker"].update({
222  "minimumHits": 10,
223  })
224  elif collection == "ALCARECOTkAlUpsilonMuMu":
225  options["TrackSelector"]["Alignment"].update({
226  "ptMin": 3.0,
227  "etaMin": -2.4,
228  "etaMax": 2.4,
229  "nHitMin": 10,
230  "applyMultiplicityFilter": True,
231  "minMultiplicity": 2,
232  "maxMultiplicity": 2,
233  ("minHitsPerSubDet", "inPIXEL"): 1,
234  ("TwoBodyDecaySelector", "applyChargeFilter"): True,
235  ("TwoBodyDecaySelector", "charge"): 0,
236  ("TwoBodyDecaySelector",
237  "applyMassrangeFilter"): not openMassWindow,
238  ("TwoBodyDecaySelector", "minXMass"): 9.2,
239  ("TwoBodyDecaySelector", "maxXMass"): 9.7,
240  ("TwoBodyDecaySelector", "daughterMass"): 0.105
241  })
242  options["TrackHitFilter"]["Tracker"].update({
243  "minimumHits": 10,
244  })
245  elif collection == "ALCARECOTkAlJpsiMuMu":
246  options["TrackSelector"]["Alignment"].update({
247  "ptMin": 1.0,
248  "etaMin": -2.4,
249  "etaMax": 2.4,
250  "nHitMin": 10,
251  "applyMultiplicityFilter": True,
252  "minMultiplicity": 2,
253  "maxMultiplicity": 2,
254  ("minHitsPerSubDet", "inPIXEL"): 1,
255  ("TwoBodyDecaySelector", "applyChargeFilter"): True,
256  ("TwoBodyDecaySelector", "charge"): 0,
257  ("TwoBodyDecaySelector",
258  "applyMassrangeFilter"): not openMassWindow,
259  ("TwoBodyDecaySelector", "minXMass"): 2.7,
260  ("TwoBodyDecaySelector", "maxXMass"): 3.4,
261  ("TwoBodyDecaySelector", "daughterMass"): 0.105
262  })
263  options["TrackHitFilter"]["Tracker"].update({
264  "minimumHits": 10,
265  })
266  else:
267  raise ValueError("Unknown input track collection: {}".format(collection))
268 
269  if cosmicTrackSplitting and not isCosmics:
270  raise ValueError("Can only do cosmic track splitting for cosmics.")
271 
272 
273 
274 
277 
278  if saveCPU:
279  if cosmicTrackSplitting:
280  raise ValueError("Can't turn on both saveCPU and cosmicTrackSplitting at the same time")
281  mods = [("TrackSelector", "Alignment", {"method": "load"}),
282  ("TrackRefitter", "First", {"method": "load",
283  "clone": True}),
284  ("TrackHitFilter", "Tracker", {"method": "load"}),
285  ("TrackFitter", "HitFilteredTracks", {"method": "import"})]
286  options["TrackSelector"]["Alignment"].update(
287  options["TrackSelector"]["HighPurity"])
288  elif cosmicTrackSplitting:
289  mods = [("TrackRefitter", "First", {"method": "load",
290  "clone": True}),
291  ("TrackSelector", "Alignment", {"method": "load"}),
292  ("TrackSplitting", "TrackSplitting", {"method": "load"}),
293  ("TrackFitter", "HitFilteredTracks", {"method": "import"}),
294  ("TrackRefitter", "Second", {"method": "load",
295  "clone": True})]
296  elif g4Refitting:
297  mods = [("TrackSelector", "HighPurity", {"method": "import"}),
298  ("TrackRefitter", "First", {"method": "load",
299  "clone": True}),
300  ("TrackHitFilter", "Tracker", {"method": "load"}),
301  ("TrackFitter", "HitFilteredTracks", {"method": "import"}),
302  ("TrackSelector", "Alignment", {"method": "load"}),
303  #("geopro","", {"method": "load"}),
304  ("TrackRefitter", "Second", {"method": "load",
305  "clone": True})]
306  if isCosmics: mods = mods[1:] # skip high purity selector for cosmics
307  else:
308  mods = [("TrackSelector", "HighPurity", {"method": "import"}),
309  ("TrackRefitter", "First", {"method": "load",
310  "clone": True}),
311  ("TrackHitFilter", "Tracker", {"method": "load"}),
312  ("TrackFitter", "HitFilteredTracks", {"method": "import"}),
313  ("TrackSelector", "Alignment", {"method": "load"}),
314  ("TrackRefitter", "Second", {"method": "load",
315  "clone": True})]
316  if isCosmics: mods = mods[1:] # skip high purity selector for cosmics
317 
318 
321 
322  if isPVValidation:
323  options["TrackSelector"]["HighPurity"].update({
324  "trackQualities": [],
325  "pMin": 0.
326  })
327  options["TrackSelector"]["Alignment"].update({
328  "pMin" : 0.,
329  "ptMin" : 0.,
330  "nHitMin2D" : 0,
331  "nHitMin" : 0,
332  "d0Min" : -999999.0,
333  "d0Max" : 999999.0,
334  "dzMin" : -999999.0,
335  "dzMax" : 999999.0
336  })
337 
338 
341 
342  if momentumConstraint is not None:
343  for mod in options["TrackRefitter"]:
344  momconstrspecs = momentumConstraint.split(',')
345  if len(momconstrspecs)==1:
346  options["TrackRefitter"][mod].update({
347  "constraint": "momentum",
348  "srcConstr": momconstrspecs[0]
349  })
350  else:
351  options["TrackRefitter"][mod].update({
352  "constraint": momconstrspecs[1],
353  "srcConstr": momconstrspecs[0]
354  })
355 
356 
357 
358 
361  process.load("RecoVertex.BeamSpotProducer.BeamSpot_cff")
362 
363 
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  customlog("Name of the last module needs to be modifiable.")
379  sys.exit(1)
380 
381  if g4Refitting:
382  customlog("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  customlog("Unknown method: %s" % 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)