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