Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-03 00:11:33

0001 import sys
0002 import FWCore.ParameterSet.Config as cms
0003 
0004 def customlog(s):
0005     print("# MSG-i trackselectionRefitting:  %s" % s)
0006 
0007 def getSequence(process, collection,
0008                 saveCPU = False,
0009                 TTRHBuilder = "WithAngleAndTemplate",
0010                 usePixelQualityFlag = None,
0011                 openMassWindow = False,
0012                 cosmicsDecoMode = False,
0013                 cosmicsZeroTesla = True,
0014                 momentumConstraint = None,
0015                 cosmicTrackSplitting = False,
0016                 isPVValidation = False,
0017                 use_d0cut = True,
0018                 g4Refitting = False):
0019     """This function returns a cms.Sequence containing as last element the
0020     module 'FinalTrackRefitter', which can be used as cms.InputTag for
0021     subsequent processing steps.
0022     The modules in the sequence are already attached to the given `process`
0023     object using the given track collection `collection` and the given
0024     optional arguments.
0025 
0026     Arguments:
0027     - `process`: 'cms.Process' object to which the modules of the sequence will
0028                  be attached.
0029     - `collection`: String indicating the input track collection.
0030     - `saveCPU`: If set to 'True', some steps are merged to reduce CPU time.
0031                  Reduces a little the accuracy of the results.
0032                  This option is currently not recommended.
0033     - `TTRHBuilder`: Option used for the Track(Re)Fitter modules.
0034     - `usePixelQualityFlag`: Option used for the TrackHitFilter module.
0035                              Defaults to 'True' but is automatically set to
0036                              'False' if a `TTRHBuilder` without templates is
0037                              used.
0038                              If this is still wanted for some reason, one can
0039                              explicitely specify it as 'True'.
0040     - `openMassWindow`: Used to configure the TwoBodyDecaySelector for ZMuMu.
0041     - `cosmicsDecoMode`: If set to 'True' a lower Signal/Noise cut is used.
0042     - `cosmicsZeroTesla`: If set to 'True' a 0T-specific selection is used.
0043     - `momentumConstraint`: If you want to apply a momentum constraint for the
0044                             track refitting, e.g. for CRUZET data, you need
0045                             to provide here the name of the constraint module.
0046     - `cosmicTrackSplitting`: If set to 'True' cosmic tracks are split before the
0047                               second track refitter.
0048     - `isPVValidation`: If set to 'True' most of the selection cuts are overridden
0049                         to allow unbiased selection of tracks for vertex refitting 
0050     - `use_d0cut`: If 'True' (default), apply a cut |d0| < 50.
0051     """
0052 
0053     ###################################################
0054     # resolve default values incl. consistency checks #
0055     ###################################################
0056 
0057     customlog("g4Refitting=%s" % g4Refitting)
0058 
0059     if usePixelQualityFlag is None:
0060         if "Template" not in TTRHBuilder:
0061             usePixelQualityFlag = False # not defined without templates
0062             customlog("Using 'TTRHBuilder' without templates %s" % TTRHBuilder)
0063             customlog(" --> Turning off pixel quality flag in hit filter.")
0064         else:
0065             usePixelQualityFlag = True # default for usage with templates
0066 
0067 
0068     #############################
0069     ## setting general options ##
0070     #############################
0071 
0072     options = {"TrackHitFilter": {},
0073                "TrackFitter": {},
0074                "TrackRefitter": {},
0075                "TrackSelector": {},
0076                "geopro": {} }
0077 
0078     options["TrackSelector"]["HighPurity"] = {
0079         "trackQualities": ["highPurity"],
0080         "filter": True,
0081         "etaMin": -3.0,
0082         "etaMax": 3.0,
0083         "pMin": 8.0
0084         }
0085     options["TrackSelector"]["Alignment"] = {
0086         "filter": True,
0087         "pMin": 3.0,
0088         "nHitMin2D": 2,
0089         "d0Min": -50.0,
0090         "d0Max": 50.0,
0091         "etaMin": -3.0,
0092         "etaMax": 3.0,
0093         "nHitMin": 8,
0094         "chi2nMax": 9999.0
0095         }
0096     options["TrackRefitter"]["First"] = {
0097         "NavigationSchool": "",
0098         "TTRHBuilder": TTRHBuilder,
0099         }
0100     options["TrackRefitter"]["Second"] = {
0101         "NavigationSchool": "",
0102         "TTRHBuilder": TTRHBuilder,
0103         }
0104     options["TrackHitFilter"]["Tracker"] = {
0105         "useTrajectories": True,
0106         "minimumHits": 8,
0107         "commands": cms.vstring("keep PXB", "keep PXE", "keep TIB", "keep TID",
0108                                 "keep TOB", "keep TEC"),
0109         "replaceWithInactiveHits": True,
0110         "rejectBadStoNHits": True,
0111         "rejectLowAngleHits": True,
0112         "usePixelQualityFlag": usePixelQualityFlag,
0113         "StoNcommands": cms.vstring("ALL 12.0"),
0114         "TrackAngleCut": 0.087,
0115         }
0116     options["TrackFitter"]["HitFilteredTracks"] = {
0117         "NavigationSchool": "",
0118         "TTRHBuilder": TTRHBuilder,
0119         }
0120     options["geopro"][""] = {
0121         }
0122 
0123     if g4Refitting:
0124         options["TrackRefitter"]["Second"] = {
0125             "AlgorithmName" : cms.string('undefAlgorithm'),
0126             "Fitter" : cms.string('G4eFitterSmoother'),
0127             "GeometricInnerState" : cms.bool(False),
0128             "MeasurementTracker" : cms.string(''),
0129             "MeasurementTrackerEvent" : cms.InputTag("MeasurementTrackerEvent"),
0130             "NavigationSchool" : cms.string('SimpleNavigationSchool'),  # Correct?
0131             "Propagator" : cms.string('Geant4ePropagator'),
0132             "TTRHBuilder" : cms.string('WithAngleAndTemplate'),
0133             "TrajectoryInEvent" : cms.bool(True),
0134             "beamSpot" : cms.InputTag("offlineBeamSpot"),
0135             "constraint" : cms.string(''),
0136             "src" : cms.InputTag("AlignmentTrackSelector"),
0137             "srcConstr" : cms.InputTag(""),
0138             "useHitsSplitting" : cms.bool(False),
0139             "usePropagatorForPCA" : cms.bool(True)   # not sure whether it is needed
0140         }
0141 
0142     #########################################
0143     ## setting collection specific options ##
0144     #########################################
0145     isCosmics = False
0146 
0147     if collection in ("ALCARECOTkAlMinBias", "generalTracks",
0148                       "ALCARECOTkAlMinBiasHI", "hiGeneralTracks",
0149                       "ALCARECOTkAlJetHT", "ALCARECOTkAlDiMuonVertexTracks",
0150                       "hltMergedTracks", "ALCARECOTkAlHLTTracks"):
0151         options["TrackSelector"]["Alignment"].update({
0152                 "ptMin": 1.0,
0153                 "pMin": 8.,
0154                 })
0155         options["TrackHitFilter"]["Tracker"].update({
0156                 "minimumHits": 10,
0157                 })
0158     elif collection in ("ALCARECOTkAlCosmicsCTF0T",
0159                         "ALCARECOTkAlCosmicsCosmicTF0T",
0160                         "ALCARECOTkAlCosmicsInCollisions"):
0161         isCosmics = True
0162         options["TrackSelector"]["HighPurity"] = {} # drop high purity cut
0163         if not cosmicsDecoMode:
0164             options["TrackHitFilter"]["Tracker"].update({
0165                     "StoNcommands": cms.vstring("ALL 18.0")
0166                     })
0167         if cosmicsZeroTesla:
0168             options["TrackHitFilter"]["Tracker"].update({
0169                     "TrackAngleCut": 0.1 # Run-I: 0.087 for 0T
0170                     })
0171         else:
0172             options["TrackHitFilter"]["Tracker"].update({
0173                     "TrackAngleCut": 0.1 # Run-I: 0.35 for 3.8T
0174                     })
0175         options["TrackSelector"]["Alignment"].update({
0176                 "pMin": 4.0,
0177                 "etaMin": -99.0,
0178                 "etaMax": 99.0,
0179                 "applyMultiplicityFilter": True,
0180                 "maxMultiplicity": 1
0181                 })
0182         if cosmicTrackSplitting:
0183             options["TrackSplitting"] = {}
0184             options["TrackSplitting"]["TrackSplitting"] = {}
0185         if not use_d0cut:
0186             options["TrackSelector"]["Alignment"].update({
0187                     "d0Min": -99999.0,
0188                     "d0Max": 99999.0,
0189                     })
0190     elif collection in ("ALCARECOTkAlMuonIsolated",
0191                         "ALCARECOTkAlMuonIsolatedHI",
0192                         "ALCARECOTkAlMuonIsolatedPA"):
0193         options["TrackSelector"]["Alignment"].update({
0194                 ("minHitsPerSubDet", "inPIXEL"): 1,
0195                 "ptMin": 5.0,
0196                 "nHitMin": 10,
0197                 "applyMultiplicityFilter": True,
0198                 "maxMultiplicity": 1,
0199                 })
0200     elif collection in ("ALCARECOTkAlZMuMu",
0201                         "ALCARECOTkAlZMuMuHI",
0202                         "ALCARECOTkAlZMuMuPA",
0203                         "ALCARECOTkAlDiMuon",
0204                         "ALCARECOTkAlHLTTracksZMuMu"):
0205         options["TrackSelector"]["Alignment"].update({
0206                 "ptMin": 15.0,
0207                 "etaMin": -3.0,
0208                 "etaMax": 3.0,
0209                 "nHitMin": 10,
0210                 "applyMultiplicityFilter": True,
0211                 "minMultiplicity": 2,
0212                 "maxMultiplicity": 2,
0213                 ("minHitsPerSubDet", "inPIXEL"): 1,
0214                 ("TwoBodyDecaySelector", "applyChargeFilter"): True,
0215                 ("TwoBodyDecaySelector", "charge"): 0,
0216                 ("TwoBodyDecaySelector",
0217                  "applyMassrangeFilter"): not openMassWindow,
0218                 ("TwoBodyDecaySelector", "minXMass"): 85.8,
0219                 ("TwoBodyDecaySelector", "maxXMass"): 95.8,
0220                 ("TwoBodyDecaySelector", "daughterMass"): 0.105
0221                 })
0222         options["TrackHitFilter"]["Tracker"].update({
0223                 "minimumHits": 10,
0224                 })
0225     elif collection == "ALCARECOTkAlUpsilonMuMu":
0226         options["TrackSelector"]["Alignment"].update({
0227                 "ptMin": 3.0,
0228                 "etaMin": -2.4,
0229                 "etaMax": 2.4,
0230                 "nHitMin": 10,
0231                 "applyMultiplicityFilter": True,
0232                 "minMultiplicity": 2,
0233                 "maxMultiplicity": 2,
0234                 ("minHitsPerSubDet", "inPIXEL"): 1,
0235                 ("TwoBodyDecaySelector", "applyChargeFilter"): True,
0236                 ("TwoBodyDecaySelector", "charge"): 0,
0237                 ("TwoBodyDecaySelector",
0238                  "applyMassrangeFilter"): not openMassWindow,
0239                 ("TwoBodyDecaySelector", "minXMass"): 9.2,
0240                 ("TwoBodyDecaySelector", "maxXMass"): 9.7,
0241                 ("TwoBodyDecaySelector", "daughterMass"): 0.105
0242                 })
0243         options["TrackHitFilter"]["Tracker"].update({
0244                 "minimumHits": 10,
0245                 })
0246     elif collection == "ALCARECOTkAlJpsiMuMu":
0247         options["TrackSelector"]["Alignment"].update({
0248                 "ptMin": 1.0,
0249                 "etaMin": -2.4,
0250                 "etaMax": 2.4,
0251                 "nHitMin": 10,
0252                 "applyMultiplicityFilter": True,
0253                 "minMultiplicity": 2,
0254                 "maxMultiplicity": 2,
0255                 ("minHitsPerSubDet", "inPIXEL"): 1,
0256                 ("TwoBodyDecaySelector", "applyChargeFilter"): True,
0257                 ("TwoBodyDecaySelector", "charge"): 0,
0258                 ("TwoBodyDecaySelector",
0259                  "applyMassrangeFilter"): not openMassWindow,
0260                 ("TwoBodyDecaySelector", "minXMass"): 2.7,
0261                 ("TwoBodyDecaySelector", "maxXMass"): 3.4,
0262                 ("TwoBodyDecaySelector", "daughterMass"): 0.105
0263                 })
0264         options["TrackHitFilter"]["Tracker"].update({
0265                 "minimumHits": 10,
0266                 })
0267     else:
0268         raise ValueError("Unknown input track collection: {}".format(collection))
0269 
0270     if cosmicTrackSplitting and not isCosmics:
0271         raise ValueError("Can only do cosmic track splitting for cosmics.")
0272 
0273 
0274 
0275     ####################
0276     ## save CPU time? ##
0277     ####################
0278 
0279     if saveCPU:
0280         if cosmicTrackSplitting:
0281             raise ValueError("Can't turn on both saveCPU and cosmicTrackSplitting at the same time")
0282         mods = [("TrackSelector", "Alignment", {"method": "load"}),
0283                 ("TrackRefitter", "First", {"method": "load",
0284                                             "clone": True}),
0285                 ("TrackHitFilter", "Tracker", {"method": "load"}),
0286                 ("TrackFitter", "HitFilteredTracks", {"method": "import"})]
0287         options["TrackSelector"]["Alignment"].update(
0288             options["TrackSelector"]["HighPurity"])
0289     elif cosmicTrackSplitting:
0290         mods = [("TrackRefitter", "First", {"method": "load",
0291                                             "clone": True}),
0292                 ("TrackSelector", "Alignment", {"method": "load"}),
0293                 ("TrackSplitting", "TrackSplitting", {"method": "load"}),
0294                 ("TrackFitter", "HitFilteredTracks", {"method": "import"}),
0295                 ("TrackRefitter", "Second", {"method": "load",
0296                                              "clone": True})]
0297     elif g4Refitting:
0298         mods = [("TrackSelector", "HighPurity", {"method": "import"}),
0299                 ("TrackRefitter", "First", {"method": "load",
0300                                             "clone": True}),
0301                 ("TrackHitFilter", "Tracker", {"method": "load"}),
0302                 ("TrackFitter", "HitFilteredTracks", {"method": "import"}),
0303                 ("TrackSelector", "Alignment", {"method": "load"}),
0304                 #("geopro","", {"method": "load"}),
0305                 ("TrackRefitter", "Second", {"method": "load",
0306                                              "clone": True})]
0307         if isCosmics: mods = mods[1:] # skip high purity selector for cosmics
0308     else:
0309         mods = [("TrackSelector", "HighPurity", {"method": "import"}),
0310                 ("TrackRefitter", "First", {"method": "load",
0311                                             "clone": True}),
0312                 ("TrackHitFilter", "Tracker", {"method": "load"}),
0313                 ("TrackFitter", "HitFilteredTracks", {"method": "import"}),
0314                 ("TrackSelector", "Alignment", {"method": "load"}),
0315                 ("TrackRefitter", "Second", {"method": "load",
0316                                              "clone": True})]
0317         if isCosmics: mods = mods[1:] # skip high purity selector for cosmics
0318 
0319     #############################
0320     ## PV Validation cuts tune ##                 
0321     #############################
0322 
0323     if isPVValidation:
0324         options["TrackSelector"]["HighPurity"].update({
0325                 "trackQualities": [],
0326                 "pMin": 0.
0327                 })
0328         options["TrackSelector"]["Alignment"].update({
0329                 "pMin" :      0.,      
0330                 "ptMin" :     0.,       
0331                 "nHitMin2D" : 0,       
0332                 "nHitMin"   : 0,       
0333                 "d0Min" : -999999.0,
0334                 "d0Max" :  999999.0,
0335                 "dzMin" : -999999.0,
0336                 "dzMax" :  999999.0
0337                 })
0338 
0339     ################################
0340     ## apply momentum constraint? ##
0341     ################################
0342 
0343     if momentumConstraint is not None:
0344         for mod in options["TrackRefitter"]:
0345             momconstrspecs = momentumConstraint.split(',')
0346             if len(momconstrspecs)==1:
0347                 options["TrackRefitter"][mod].update({
0348                     "constraint": "momentum",
0349                     "srcConstr": momconstrspecs[0]
0350                     })
0351             else:
0352                 options["TrackRefitter"][mod].update({
0353                     "constraint": momconstrspecs[1],
0354                     "srcConstr": momconstrspecs[0]
0355                     })
0356 
0357 
0358 
0359     #######################################################
0360     # load offline beam spot module required by the refit #
0361     #######################################################
0362     process.load("RecoVertex.BeamSpotProducer.BeamSpot_cff")
0363 
0364     ###############################
0365     ## put the sequence together ##
0366     ###############################
0367 
0368     modules = []
0369     src = collection
0370     prevsrc = None
0371     for mod in mods[:-1]:
0372         src, prevsrc = _getModule(process, src, mod[0], "".join(reversed(mod[:-1])),
0373                                   options[mod[0]][mod[1]], isCosmics = isCosmics, prevsrc = prevsrc,
0374                                   **(mod[2])), src
0375         modules.append(getattr(process, src))
0376     else:
0377         if mods[-1][-1]["method"] == "load" and \
0378                 not mods[-1][-1].get("clone", False):
0379             customlog("Name of the last module needs to be modifiable.")
0380             sys.exit(1)
0381 
0382         if g4Refitting:
0383             customlog("Here we must include geopro first")
0384             process.load('Configuration.StandardSequences.GeometryDB_cff')
0385             process.load("TrackPropagation.Geant4e.geantRefit_cff")
0386             modules.append(getattr(process,"geopro"))
0387 
0388         src = _getModule(process, src, mods[-1][0], "FinalTrackRefitter",
0389                          options[mods[-1][0]][mods[-1][1]],
0390                          isCosmics = isCosmics, **(mods[-1][2]))
0391         modules.append(getattr(process, src))
0392 
0393     moduleSum = process.offlineBeamSpot        # first element of the sequence
0394     if g4Refitting:
0395         # g4Refitter needs measurements
0396         moduleSum += getattr(process,"MeasurementTrackerEvent")
0397 
0398     for module in modules:
0399         # Spply srcConstr fix here
0400         if hasattr(module,"srcConstr"):
0401            strSrcConstr = module.srcConstr.getModuleLabel()
0402            if strSrcConstr:
0403                procsrcconstr = getattr(process,strSrcConstr)
0404                if hasattr(procsrcconstr,"src"): # Momentum or track parameter constraints
0405                   if procsrcconstr.src != module.src:
0406                      module.srcConstr=''
0407                      module.constraint=''
0408                   else:
0409                      moduleSum += procsrcconstr # Add constraint
0410                elif hasattr(procsrcconstr,"srcTrk"): # Vertex constraint
0411                   if procsrcconstr.srcTrk != module.src:
0412                      module.srcConstr=''
0413                      module.constraint=''
0414                   else:
0415                      procsrcconstrsrcvtx = getattr(process,procsrcconstr.srcVtx.getModuleLabel())
0416                      if type(procsrcconstrsrcvtx) is cms.EDFilter: # If source of vertices is itself a filter (e.g. good PVs)
0417                         procsrcconstrsrcvtxprefilter = getattr(process,procsrcconstrsrcvtx.src.getModuleLabel())
0418                         moduleSum += procsrcconstrsrcvtxprefilter # Add vertex source to constraint before filter
0419                      moduleSum += procsrcconstrsrcvtx # Add vertex source to constraint
0420                      moduleSum += procsrcconstr # Add constraint
0421 
0422         moduleSum += module # append the other modules
0423 
0424     return cms.Sequence(moduleSum)
0425 
0426 ###############################
0427 ###############################
0428 ###                         ###
0429 ###   Auxiliary functions   ###
0430 ###                         ###
0431 ###############################
0432 ###############################
0433 
0434 
0435 def _getModule(process, src, modType, moduleName, options, **kwargs):
0436     """General function for attaching the module of type `modType` to the
0437     cms.Process `process` using `options` for customization and `moduleName` as
0438     the name of the new attribute of `process`.
0439 
0440     Arguments:
0441     - `process`: 'cms.Process' object to which the module is attached.
0442     - `src`: cms.InputTag for this module.
0443     - `modType`: Type of the requested module.
0444     - `options`: Dictionary with customized values for the module's options.
0445     - `**kwargs`: Used to supply options at construction time of the module.
0446     """
0447 
0448     objTuple = globals()["_"+modType](kwargs)
0449     method = kwargs.get("method")
0450     if method == "import":
0451         __import__(objTuple[0])
0452         obj = getattr(sys.modules[objTuple[0]], objTuple[1]).clone()
0453     elif method == "load":
0454         process.load(objTuple[0])
0455         if kwargs.get("clone", False):
0456             obj = getattr(process, objTuple[1]).clone(src=src)
0457         else:
0458             obj = getattr(process, objTuple[1])
0459             moduleName = objTuple[1]
0460     else:
0461         customlog("Unknown method: %s" % method)
0462         sys.exit(1)
0463 
0464     if modType == "TrackSplitting":
0465         #track splitting takes the TrackSelector as tracks
0466         # and the first TrackRefitter as tjTkAssociationMapTag
0467         _customSetattr(obj, "tracks", src)
0468         _customSetattr(obj, "tjTkAssociationMapTag", kwargs["prevsrc"])
0469     else:
0470         obj.src = src
0471 
0472     for option in options:
0473         _customSetattr(obj, option, options[option])
0474 
0475     if moduleName is not objTuple[1]:
0476         setattr(process, moduleName, obj)
0477     return moduleName
0478 
0479 
0480 def _TrackHitFilter(kwargs):
0481     """Returns TrackHitFilter module name.
0482 
0483     Arguments:
0484     - `kwargs`: Not used in this function.
0485     """
0486 
0487     return ("RecoTracker.FinalTrackSelectors.TrackerTrackHitFilter_cff",
0488             "TrackerTrackHitFilter")
0489 
0490 
0491 def _TrackSelector(kwargs):
0492     """Returns TrackSelector module name.
0493 
0494     Arguments:
0495     - `kwargs`: Not used in this function.
0496     """
0497 
0498     return ("Alignment.CommonAlignmentProducer.AlignmentTrackSelector_cfi",
0499             "AlignmentTrackSelector")
0500 
0501 
0502 def _TrackFitter(kwargs):
0503     """Returns TrackFitter module name.
0504 
0505     Arguments:
0506     - `kwargs`: Used to supply options at construction time of the object.
0507     """
0508 
0509     isCosmics = kwargs.get("isCosmics", False)
0510     if isCosmics:
0511         return ("RecoTracker.TrackProducer.CTFFinalFitWithMaterialP5_cff",
0512                 "ctfWithMaterialTracksCosmics")
0513     else:
0514         return ("RecoTracker.TrackProducer.CTFFinalFitWithMaterial_cff",
0515                 "ctfWithMaterialTracks")
0516 
0517 
0518 def _TrackRefitter(kwargs):
0519     """Returns TrackRefitter module name.
0520 
0521     Arguments:
0522     - `kwargs`: Used to supply options at construction time of the object.
0523     """
0524 
0525     isCosmics = kwargs.get("isCosmics", False)
0526     if isCosmics:
0527         return ("RecoTracker.TrackProducer.TrackRefitters_cff",
0528                 "TrackRefitterP5")
0529     else:
0530         return ("RecoTracker.TrackProducer.TrackRefitters_cff",
0531                 "TrackRefitter")
0532 
0533 def _TrackSplitting(kwargs):
0534     return ("RecoTracker.FinalTrackSelectors.cosmicTrackSplitter_cfi",
0535             "cosmicTrackSplitter")
0536 
0537 def _geopro(kwargs):
0538     return ("TrackPropagation.Geant4e.geantRefit_cff","geopro")
0539 
0540 
0541 def _customSetattr(obj, attr, val):
0542     """Sets the attribute `attr` of the object `obj` using the value `val`.
0543     `attr` can be a string or a tuple of strings, if one wants to set an
0544     attribute of an attribute, etc.
0545 
0546     Arguments:
0547     - `obj`: Object, which must have a '__dict__' attribute.
0548     - `attr`: String or tuple of strings describing the attribute's name.
0549     - `val`: value of the attribute.
0550     """
0551 
0552     if isinstance(attr, tuple) and len(attr) > 1:
0553         _customSetattr(getattr(obj, attr[0]), attr[1:], val)
0554     else:
0555         if isinstance(attr, tuple): attr = attr[0]
0556         setattr(obj, attr, val)
0557