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