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  "hltMergedTracks"):
152  options["TrackSelector"]["Alignment"].update({
153  "ptMin": 1.0,
154  "pMin": 8.,
155  })
156  options["TrackHitFilter"]["Tracker"].update({
157  "minimumHits": 10,
158  })
159  elif collection in ("ALCARECOTkAlCosmicsCTF0T",
160  "ALCARECOTkAlCosmicsCosmicTF0T",
161  "ALCARECOTkAlCosmicsInCollisions"):
162  isCosmics = True
163  options["TrackSelector"]["HighPurity"] = {} # drop high purity cut
164  if not cosmicsDecoMode:
165  options["TrackHitFilter"]["Tracker"].update({
166  "StoNcommands": cms.vstring("ALL 18.0")
167  })
168  if cosmicsZeroTesla:
169  options["TrackHitFilter"]["Tracker"].update({
170  "TrackAngleCut": 0.1 # Run-I: 0.087 for 0T
171  })
172  else:
173  options["TrackHitFilter"]["Tracker"].update({
174  "TrackAngleCut": 0.1 # Run-I: 0.35 for 3.8T
175  })
176  options["TrackSelector"]["Alignment"].update({
177  "pMin": 4.0,
178  "etaMin": -99.0,
179  "etaMax": 99.0,
180  "applyMultiplicityFilter": True,
181  "maxMultiplicity": 1
182  })
183  if cosmicTrackSplitting:
184  options["TrackSplitting"] = {}
185  options["TrackSplitting"]["TrackSplitting"] = {}
186  if not use_d0cut:
187  options["TrackSelector"]["Alignment"].update({
188  "d0Min": -99999.0,
189  "d0Max": 99999.0,
190  })
191  elif collection in ("ALCARECOTkAlMuonIsolated",
192  "ALCARECOTkAlMuonIsolatedHI",
193  "ALCARECOTkAlMuonIsolatedPA"):
194  options["TrackSelector"]["Alignment"].update({
195  ("minHitsPerSubDet", "inPIXEL"): 1,
196  "ptMin": 5.0,
197  "nHitMin": 10,
198  "applyMultiplicityFilter": True,
199  "maxMultiplicity": 1,
200  })
201  elif collection in ("ALCARECOTkAlZMuMu",
202  "ALCARECOTkAlZMuMuHI",
203  "ALCARECOTkAlZMuMuPA",
204  "ALCARECOTkAlDiMuon"):
205  options["TrackSelector"]["Alignment"].update({
206  "ptMin": 15.0,
207  "etaMin": -3.0,
208  "etaMax": 3.0,
209  "nHitMin": 10,
210  "applyMultiplicityFilter": True,
211  "minMultiplicity": 2,
212  "maxMultiplicity": 2,
213  ("minHitsPerSubDet", "inPIXEL"): 1,
214  ("TwoBodyDecaySelector", "applyChargeFilter"): True,
215  ("TwoBodyDecaySelector", "charge"): 0,
216  ("TwoBodyDecaySelector",
217  "applyMassrangeFilter"): not openMassWindow,
218  ("TwoBodyDecaySelector", "minXMass"): 85.8,
219  ("TwoBodyDecaySelector", "maxXMass"): 95.8,
220  ("TwoBodyDecaySelector", "daughterMass"): 0.105
221  })
222  options["TrackHitFilter"]["Tracker"].update({
223  "minimumHits": 10,
224  })
225  elif collection == "ALCARECOTkAlUpsilonMuMu":
226  options["TrackSelector"]["Alignment"].update({
227  "ptMin": 3.0,
228  "etaMin": -2.4,
229  "etaMax": 2.4,
230  "nHitMin": 10,
231  "applyMultiplicityFilter": True,
232  "minMultiplicity": 2,
233  "maxMultiplicity": 2,
234  ("minHitsPerSubDet", "inPIXEL"): 1,
235  ("TwoBodyDecaySelector", "applyChargeFilter"): True,
236  ("TwoBodyDecaySelector", "charge"): 0,
237  ("TwoBodyDecaySelector",
238  "applyMassrangeFilter"): not openMassWindow,
239  ("TwoBodyDecaySelector", "minXMass"): 9.2,
240  ("TwoBodyDecaySelector", "maxXMass"): 9.7,
241  ("TwoBodyDecaySelector", "daughterMass"): 0.105
242  })
243  options["TrackHitFilter"]["Tracker"].update({
244  "minimumHits": 10,
245  })
246  elif collection == "ALCARECOTkAlJpsiMuMu":
247  options["TrackSelector"]["Alignment"].update({
248  "ptMin": 1.0,
249  "etaMin": -2.4,
250  "etaMax": 2.4,
251  "nHitMin": 10,
252  "applyMultiplicityFilter": True,
253  "minMultiplicity": 2,
254  "maxMultiplicity": 2,
255  ("minHitsPerSubDet", "inPIXEL"): 1,
256  ("TwoBodyDecaySelector", "applyChargeFilter"): True,
257  ("TwoBodyDecaySelector", "charge"): 0,
258  ("TwoBodyDecaySelector",
259  "applyMassrangeFilter"): not openMassWindow,
260  ("TwoBodyDecaySelector", "minXMass"): 2.7,
261  ("TwoBodyDecaySelector", "maxXMass"): 3.4,
262  ("TwoBodyDecaySelector", "daughterMass"): 0.105
263  })
264  options["TrackHitFilter"]["Tracker"].update({
265  "minimumHits": 10,
266  })
267  else:
268  raise ValueError("Unknown input track collection: {}".format(collection))
269 
270  if cosmicTrackSplitting and not isCosmics:
271  raise ValueError("Can only do cosmic track splitting for cosmics.")
272 
273 
274 
275 
278 
279  if saveCPU:
280  if cosmicTrackSplitting:
281  raise ValueError("Can't turn on both saveCPU and cosmicTrackSplitting at the same time")
282  mods = [("TrackSelector", "Alignment", {"method": "load"}),
283  ("TrackRefitter", "First", {"method": "load",
284  "clone": True}),
285  ("TrackHitFilter", "Tracker", {"method": "load"}),
286  ("TrackFitter", "HitFilteredTracks", {"method": "import"})]
287  options["TrackSelector"]["Alignment"].update(
288  options["TrackSelector"]["HighPurity"])
289  elif cosmicTrackSplitting:
290  mods = [("TrackRefitter", "First", {"method": "load",
291  "clone": True}),
292  ("TrackSelector", "Alignment", {"method": "load"}),
293  ("TrackSplitting", "TrackSplitting", {"method": "load"}),
294  ("TrackFitter", "HitFilteredTracks", {"method": "import"}),
295  ("TrackRefitter", "Second", {"method": "load",
296  "clone": True})]
297  elif g4Refitting:
298  mods = [("TrackSelector", "HighPurity", {"method": "import"}),
299  ("TrackRefitter", "First", {"method": "load",
300  "clone": True}),
301  ("TrackHitFilter", "Tracker", {"method": "load"}),
302  ("TrackFitter", "HitFilteredTracks", {"method": "import"}),
303  ("TrackSelector", "Alignment", {"method": "load"}),
304  #("geopro","", {"method": "load"}),
305  ("TrackRefitter", "Second", {"method": "load",
306  "clone": True})]
307  if isCosmics: mods = mods[1:] # skip high purity selector for cosmics
308  else:
309  mods = [("TrackSelector", "HighPurity", {"method": "import"}),
310  ("TrackRefitter", "First", {"method": "load",
311  "clone": True}),
312  ("TrackHitFilter", "Tracker", {"method": "load"}),
313  ("TrackFitter", "HitFilteredTracks", {"method": "import"}),
314  ("TrackSelector", "Alignment", {"method": "load"}),
315  ("TrackRefitter", "Second", {"method": "load",
316  "clone": True})]
317  if isCosmics: mods = mods[1:] # skip high purity selector for cosmics
318 
319 
322 
323  if isPVValidation:
324  options["TrackSelector"]["HighPurity"].update({
325  "trackQualities": [],
326  "pMin": 0.
327  })
328  options["TrackSelector"]["Alignment"].update({
329  "pMin" : 0.,
330  "ptMin" : 0.,
331  "nHitMin2D" : 0,
332  "nHitMin" : 0,
333  "d0Min" : -999999.0,
334  "d0Max" : 999999.0,
335  "dzMin" : -999999.0,
336  "dzMax" : 999999.0
337  })
338 
339 
342 
343  if momentumConstraint is not None:
344  for mod in options["TrackRefitter"]:
345  momconstrspecs = momentumConstraint.split(',')
346  if len(momconstrspecs)==1:
347  options["TrackRefitter"][mod].update({
348  "constraint": "momentum",
349  "srcConstr": momconstrspecs[0]
350  })
351  else:
352  options["TrackRefitter"][mod].update({
353  "constraint": momconstrspecs[1],
354  "srcConstr": momconstrspecs[0]
355  })
356 
357 
358 
359 
362  process.load("RecoVertex.BeamSpotProducer.BeamSpot_cff")
363 
364 
367 
368  modules = []
369  src = collection
370  prevsrc = None
371  for mod in mods[:-1]:
372  src, prevsrc = _getModule(process, src, mod[0], "".join(reversed(mod[:-1])),
373  options[mod[0]][mod[1]], isCosmics = isCosmics, prevsrc = prevsrc,
374  **(mod[2])), src
375  modules.append(getattr(process, src))
376  else:
377  if mods[-1][-1]["method"] == "load" and \
378  not mods[-1][-1].get("clone", False):
379  customlog("Name of the last module needs to be modifiable.")
380  sys.exit(1)
381 
382  if g4Refitting:
383  customlog("Here we must include geopro first")
384  process.load('Configuration.StandardSequences.GeometryDB_cff')
385  process.load("TrackPropagation.Geant4e.geantRefit_cff")
386  modules.append(getattr(process,"geopro"))
387 
388  src = _getModule(process, src, mods[-1][0], "FinalTrackRefitter",
389  options[mods[-1][0]][mods[-1][1]],
390  isCosmics = isCosmics, **(mods[-1][2]))
391  modules.append(getattr(process, src))
392 
393  moduleSum = process.offlineBeamSpot # first element of the sequence
394  if g4Refitting:
395  # g4Refitter needs measurements
396  moduleSum += getattr(process,"MeasurementTrackerEvent")
397 
398  for module in modules:
399  # Spply srcConstr fix here
400  if hasattr(module,"srcConstr"):
401  strSrcConstr = module.srcConstr.getModuleLabel()
402  if strSrcConstr:
403  procsrcconstr = getattr(process,strSrcConstr)
404  if hasattr(procsrcconstr,"src"): # Momentum or track parameter constraints
405  if procsrcconstr.src != module.src:
406  module.srcConstr=''
407  module.constraint=''
408  else:
409  moduleSum += procsrcconstr # Add constraint
410  elif hasattr(procsrcconstr,"srcTrk"): # Vertex constraint
411  if procsrcconstr.srcTrk != module.src:
412  module.srcConstr=''
413  module.constraint=''
414  else:
415  procsrcconstrsrcvtx = getattr(process,procsrcconstr.srcVtx.getModuleLabel())
416  if type(procsrcconstrsrcvtx) is cms.EDFilter: # If source of vertices is itself a filter (e.g. good PVs)
417  procsrcconstrsrcvtxprefilter = getattr(process,procsrcconstrsrcvtx.src.getModuleLabel())
418  moduleSum += procsrcconstrsrcvtxprefilter # Add vertex source to constraint before filter
419  moduleSum += procsrcconstrsrcvtx # Add vertex source to constraint
420  moduleSum += procsrcconstr # Add constraint
421 
422  moduleSum += module # append the other modules
423 
424  return cms.Sequence(moduleSum)
425 
426 
433 
434 
435 def _getModule(process, src, modType, moduleName, options, **kwargs):
436  """General function for attaching the module of type `modType` to the
437  cms.Process `process` using `options` for customization and `moduleName` as
438  the name of the new attribute of `process`.
439 
440  Arguments:
441  - `process`: 'cms.Process' object to which the module is attached.
442  - `src`: cms.InputTag for this module.
443  - `modType`: Type of the requested module.
444  - `options`: Dictionary with customized values for the module's options.
445  - `**kwargs`: Used to supply options at construction time of the module.
446  """
447 
448  objTuple = globals()["_"+modType](kwargs)
449  method = kwargs.get("method")
450  if method == "import":
451  __import__(objTuple[0])
452  obj = getattr(sys.modules[objTuple[0]], objTuple[1]).clone()
453  elif method == "load":
454  process.load(objTuple[0])
455  if kwargs.get("clone", False):
456  obj = getattr(process, objTuple[1]).clone(src=src)
457  else:
458  obj = getattr(process, objTuple[1])
459  moduleName = objTuple[1]
460  else:
461  customlog("Unknown method: %s" % method)
462  sys.exit(1)
463 
464  if modType == "TrackSplitting":
465  #track splitting takes the TrackSelector as tracks
466  # and the first TrackRefitter as tjTkAssociationMapTag
467  _customSetattr(obj, "tracks", src)
468  _customSetattr(obj, "tjTkAssociationMapTag", kwargs["prevsrc"])
469  else:
470  obj.src = src
471 
472  for option in options:
473  _customSetattr(obj, option, options[option])
474 
475  if moduleName is not objTuple[1]:
476  setattr(process, moduleName, obj)
477  return moduleName
478 
479 
480 def _TrackHitFilter(kwargs):
481  """Returns TrackHitFilter module name.
482 
483  Arguments:
484  - `kwargs`: Not used in this function.
485  """
486 
487  return ("RecoTracker.FinalTrackSelectors.TrackerTrackHitFilter_cff",
488  "TrackerTrackHitFilter")
489 
490 
491 def _TrackSelector(kwargs):
492  """Returns TrackSelector module name.
493 
494  Arguments:
495  - `kwargs`: Not used in this function.
496  """
497 
498  return ("Alignment.CommonAlignmentProducer.AlignmentTrackSelector_cfi",
499  "AlignmentTrackSelector")
500 
501 
502 def _TrackFitter(kwargs):
503  """Returns TrackFitter module name.
504 
505  Arguments:
506  - `kwargs`: Used to supply options at construction time of the object.
507  """
508 
509  isCosmics = kwargs.get("isCosmics", False)
510  if isCosmics:
511  return ("RecoTracker.TrackProducer.CTFFinalFitWithMaterialP5_cff",
512  "ctfWithMaterialTracksCosmics")
513  else:
514  return ("RecoTracker.TrackProducer.CTFFinalFitWithMaterial_cff",
515  "ctfWithMaterialTracks")
516 
517 
518 def _TrackRefitter(kwargs):
519  """Returns TrackRefitter module name.
520 
521  Arguments:
522  - `kwargs`: Used to supply options at construction time of the object.
523  """
524 
525  isCosmics = kwargs.get("isCosmics", False)
526  if isCosmics:
527  return ("RecoTracker.TrackProducer.TrackRefitters_cff",
528  "TrackRefitterP5")
529  else:
530  return ("RecoTracker.TrackProducer.TrackRefitters_cff",
531  "TrackRefitter")
532 
533 def _TrackSplitting(kwargs):
534  return ("RecoTracker.FinalTrackSelectors.cosmicTrackSplitter_cfi",
535  "cosmicTrackSplitter")
536 
537 def _geopro(kwargs):
538  return ("TrackPropagation.Geant4e.geantRefit_cff","geopro")
539 
540 
541 def _customSetattr(obj, attr, val):
542  """Sets the attribute `attr` of the object `obj` using the value `val`.
543  `attr` can be a string or a tuple of strings, if one wants to set an
544  attribute of an attribute, etc.
545 
546  Arguments:
547  - `obj`: Object, which must have a '__dict__' attribute.
548  - `attr`: String or tuple of strings describing the attribute's name.
549  - `val`: value of the attribute.
550  """
551 
552  if isinstance(attr, tuple) and len(attr) > 1:
553  _customSetattr(getattr(obj, attr[0]), attr[1:], val)
554  else:
555  if isinstance(attr, tuple): attr = attr[0]
556  setattr(obj, attr, val)
557 
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:21
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
#define update(a, b)