Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-04-30 22:23:55

0001 from copy import copy, deepcopy
0002 from collections import OrderedDict
0003 from .MatrixUtil import merge, Kby, Mby, check_dups
0004 import re
0005 
0006 undefInput = "UNDEF"
0007 
0008 U2000by1={'--relval': '2000,1'}
0009 
0010 # DON'T CHANGE THE ORDER, only append new keys. Otherwise the numbering for the runTheMatrix tests will change.
0011 
0012 upgradeKeys = {}
0013 
0014 upgradeKeys[2017] = [
0015     '2017',
0016     '2017PU',
0017     '2017Design',
0018     '2017DesignPU',
0019     '2018',
0020     '2018PU',
0021     '2018Design',
0022     '2018DesignPU',
0023     '2022',
0024     '2022PU',
0025     '2022Design',
0026     '2022DesignPU',
0027     '2023',
0028     '2023PU',
0029     '2024',
0030     '2024PU',
0031     '2022FS',
0032     '2022FSPU',
0033     '2022postEE',
0034     '2022postEEPU',
0035     '2023FS',
0036     '2023FSPU',
0037     '2022HI',
0038     '2022HIRP', #RawPrime
0039     '2023HI',
0040     '2023HIRP', #RawPrime
0041     '2024HLTOnDigi',
0042     '2024HLTOnDigiPU',
0043     '2024GenOnly',
0044     '2024SimOnGen',
0045     '2024FS',
0046     '2024FSPU',
0047     '2025',
0048     '2025PU',
0049     '2025HLTOnDigi',
0050     '2025HLTOnDigiPU',
0051     '2025SimOnGen',
0052     '2025GenOnly',
0053 ]
0054 
0055 upgradeKeys['Run4'] = [
0056     'Run4D95',
0057     'Run4D95PU',
0058     'Run4D96',
0059     'Run4D96PU',
0060     'Run4D98',
0061     'Run4D98PU',
0062     'Run4D99',
0063     'Run4D99PU',
0064     'Run4D100',
0065     'Run4D100PU',
0066     'Run4D101',
0067     'Run4D101PU',
0068     'Run4D102',
0069     'Run4D102PU',
0070     'Run4D103',
0071     'Run4D103PU',
0072     'Run4D104',
0073     'Run4D104PU',
0074     'Run4D105',
0075     'Run4D105PU',
0076     'Run4D106',
0077     'Run4D106PU',
0078     'Run4D107',
0079     'Run4D107PU',
0080     'Run4D108',
0081     'Run4D108PU',
0082     'Run4D109',
0083     'Run4D109PU',
0084     'Run4D110',
0085     'Run4D110PU',
0086     'Run4D111',
0087     'Run4D111PU',
0088     'Run4D112',
0089     'Run4D112PU',
0090     'Run4D113',
0091     'Run4D113PU',
0092     'Run4D114',
0093     'Run4D114PU',
0094     'Run4D110GenOnly',
0095     'Run4D110SimOnGen',
0096     'Run4D115',
0097     'Run4D115PU',
0098     'Run4D116',
0099     'Run4D116PU',
0100     'Run4D117',
0101     'Run4D117PU',
0102     'Run4D118',
0103     'Run4D118PU',
0104     'Run4D119',
0105     'Run4D119PU',
0106     'Run4D120',
0107     'Run4D120PU',
0108 ]
0109 
0110 # pre-generation of WF numbers
0111 numWFStart={
0112     2017: 10000,
0113     'Run4': 23600,
0114 }
0115 numWFSkip=200
0116 # temporary measure to keep other WF numbers the same
0117 numWFConflict = [[14400,14800], #2022ReReco, 2022ReRecoPU (in 12_4)
0118                  [24400,24800], #D97
0119                  [50000,51000]]
0120 numWFAll={
0121     2017: [],
0122     'Run4': []
0123 }
0124 
0125 for year in upgradeKeys:
0126     for i in range(0,len(upgradeKeys[year])):
0127         numWFtmp = numWFStart[year] if i==0 else (numWFAll[year][i-1] + numWFSkip)
0128         for conflict in numWFConflict:
0129             if numWFtmp>=conflict[0] and numWFtmp<conflict[1]:
0130                 numWFtmp = conflict[1]
0131                 break
0132         numWFAll[year].append(numWFtmp)
0133 
0134 # workflows for baseline and for variations
0135 # setup() automatically loops over all steps and applies any customizations specified in setup_() -> called in relval_steps.py
0136 # setupPU() and setupPU_() operate similarly -> called in relval_steps.py *after* merging PUDataSets w/ regular steps
0137 # workflow() adds a concrete workflow to the list based on condition() -> called in relval_upgrade.py
0138 # every special workflow gets its own derived class, which must then be added to the global dict upgradeWFs
0139 preventReuseKeyword = 'NOREUSE'
0140 class UpgradeWorkflow(object):
0141     def __init__(self,steps,PU,suffix,offset):
0142         self.steps = steps
0143         self.PU = PU
0144         self.allowReuse = True
0145 
0146         # ensure all PU steps are in normal step list
0147         for step in self.PU:
0148             if not step in self.steps:
0149                 self.steps.append(step)
0150 
0151         self.suffix = suffix
0152         if len(self.suffix)>0 and self.suffix[0]!='_': self.suffix = '_'+self.suffix
0153         self.offset = offset
0154         if self.offset < 0.0 or self.offset > 1.0:
0155             raise ValueError("Special workflow offset must be between 0.0 and 1.0")
0156     def getStepName(self, step, extra=""):
0157         stepName = step + self.suffix + extra
0158         return stepName
0159     def getStepNamePU(self, step, extra=""):
0160         stepNamePU = step + 'PU' + self.suffix + extra
0161         return stepNamePU
0162     def init(self, stepDict):
0163         for step in self.steps:
0164             stepDict[self.getStepName(step)] = {}
0165             if not self.allowReuse: stepDict[self.getStepName(step,preventReuseKeyword)] = {}
0166         for step in self.PU:
0167             stepDict[self.getStepNamePU(step)] = {}
0168             if not self.allowReuse: stepDict[self.getStepNamePU(step,preventReuseKeyword)] = {}
0169     def setup(self, stepDict, k, properties):
0170         for step in self.steps:
0171             self.setup_(step, self.getStepName(step), stepDict, k, properties)
0172             if not self.allowReuse: self.preventReuse(self.getStepName(step,preventReuseKeyword), stepDict, k)
0173     def setupPU(self, stepDict, k, properties):
0174         for step in self.PU:
0175             self.setupPU_(step, self.getStepNamePU(step), stepDict, k, properties)
0176             if not self.allowReuse: self.preventReuse(self.getStepNamePU(step,preventReuseKeyword), stepDict, k)
0177     def setup_(self, step, stepName, stepDict, k, properties):
0178         pass
0179     def setupPU_(self, step, stepName, stepDict, k, properties):
0180         pass
0181     def workflow(self, workflows, num, fragment, stepList, key, hasHarvest):
0182         if self.condition(fragment, stepList, key, hasHarvest):
0183             self.workflow_(workflows, num, fragment, stepList, key)
0184     def workflow_(self, workflows, num, fragment, stepList, key):
0185         fragmentTmp = [fragment, key]
0186         if len(self.suffix)>0: fragmentTmp.append(self.suffix)
0187         # avoid spurious workflows (no steps modified)
0188         if self.offset==0 or workflows[num][1]!=stepList:
0189             workflows[num+self.offset] = [ fragmentTmp, stepList ]
0190     def condition(self, fragment, stepList, key, hasHarvest):
0191         return False
0192     def preventReuse(self, stepName, stepDict, k):
0193         if "Sim" in stepName and stepName != "Sim":
0194             stepDict[stepName][k] = None
0195         if "Gen" in stepName:
0196             stepDict[stepName][k] = None
0197 upgradeWFs = OrderedDict()
0198 
0199 class UpgradeWorkflow_baseline(UpgradeWorkflow):
0200     def setup_(self, step, stepName, stepDict, k, properties):
0201   
0202         cust=properties.get('Custom', None)
0203         era=properties.get('Era', None)
0204         modifier=properties.get('ProcessModifier',None)
0205 
0206         if cust is not None: stepDict[stepName][k]['--customise']=cust
0207         if era is not None:
0208             stepDict[stepName][k]['--era']=era
0209         if modifier is not None: stepDict[stepName][k]['--procModifier']=modifier
0210     def condition(self, fragment, stepList, key, hasHarvest):
0211         return True
0212 upgradeWFs['baseline'] = UpgradeWorkflow_baseline(
0213     steps =  [
0214         'Gen',
0215         'GenHLBeamSpot',
0216         'GenHLBeamSpot14',
0217         'Sim',
0218         'GenSim',
0219         'GenSimHLBeamSpot',
0220         'GenSimHLBeamSpot14',
0221         'GenSimHLBeamSpotHGCALCloseBy',
0222         'Digi',
0223         'DigiNoHLT',
0224         'DigiTrigger',
0225         'HLTRun3',
0226         'HLTOnly',
0227         'RecoLocal',
0228         'Reco',
0229         'RecoFakeHLT',
0230         'RecoGlobal',
0231         'RecoGlobalFakeHLT',
0232         'RecoNano',
0233         'RecoNanoFakeHLT',
0234         'HARVEST',
0235         'HARVESTFakeHLT',
0236         'HARVESTNano',
0237         'HARVESTNanoFakeHLT',
0238         'FastSim',
0239         'HARVESTFast',
0240         'HARVESTGlobal',
0241         'HARVESTGlobalFakeHLT',
0242         'ALCA',
0243         'ALCAPhase2',
0244         'Nano',
0245         'MiniAOD',
0246         'HLT75e33',
0247         'FastSimRun3',
0248         'HARVESTFastRun3',
0249     ],
0250     PU =  [
0251         'DigiTrigger',
0252         'RecoLocal',
0253         'RecoGlobal',
0254         'RecoGlobalFakeHLT',
0255         'Digi',
0256         'DigiNoHLT',
0257         'HLTOnly',
0258         'Reco',
0259         'RecoFakeHLT',
0260         'RecoNano',
0261         'RecoNanoFakeHLT',
0262         'HARVEST',
0263         'HARVESTFakeHLT',
0264         'HARVESTNano',
0265         'HARVESTNanoFakeHLT',
0266         'HARVESTGlobal',
0267         'HARVESTGlobalFakeHLT',
0268         'MiniAOD',
0269         'Nano',
0270         'HLT75e33',
0271         'FastSimRun3',
0272         'HARVESTFastRun3',
0273     ],
0274     suffix = '',
0275     offset = 0.0,
0276 )
0277 
0278 
0279 class UpgradeWorkflow_DigiNoHLT(UpgradeWorkflow):
0280     def setup_(self, step, stepName, stepDict, k, properties):
0281         if stepDict[step][k] != None:
0282             if 'ALCA' in step:
0283                 stepDict[stepName][k] = None
0284             if 'RecoNano' in step:
0285                 stepDict[stepName][k] = merge([{'--filein': 'file:step3.root', '--secondfilein': 'file:step2.root'}, stepDict[step][k]])
0286             if 'Digi' in step and 'NoHLT' not in step:
0287                 stepDict[stepName][k] = merge([{'-s': re.sub(',HLT.*', '', stepDict[step][k]['-s'])}, stepDict[step][k]])
0288     def condition(self, fragment, stepList, key, hasHarvest):
0289         if ('TTbar_14TeV' in fragment and '2022' == key):
0290             stepList.insert(stepList.index('Digi_DigiNoHLT_2022')+1, 'HLTRun3_2022')
0291         return ('TTbar_14TeV' in fragment and '2022' == key)
0292 upgradeWFs['DigiNoHLT'] = UpgradeWorkflow_DigiNoHLT(
0293     steps = [
0294         'Digi',
0295         'RecoNano',
0296         'RecoNanoFakeHLT',
0297         'ALCA'
0298     ],
0299     PU = [],
0300     suffix = '_DigiNoHLT',
0301     offset = 0.601,
0302 )
0303 
0304 # some commonalities among tracking WFs
0305 class UpgradeWorkflowTracking(UpgradeWorkflow):
0306 
0307     def __init__(self, steps, PU, suffix, offset):
0308         # always include some steps that will be skipped
0309         steps = steps + ["ALCA","Nano"]
0310         super().__init__(steps, PU, suffix, offset)
0311     def condition(self, fragment, stepList, key, hasHarvest):
0312         result = (fragment=="TTbar_13" or fragment=="TTbar_14TeV" or 'Hydjet' in fragment) and not 'PU' in key and hasHarvest and self.condition_(fragment, stepList, key, hasHarvest)
0313         return result
0314     def condition_(self, fragment, stepList, key, hasHarvest):
0315         return True
0316     def setup_(self, step, stepName, stepDict, k, properties):
0317         # skip ALCA and Nano steps (but not RecoNano or HARVESTNano for Run3)
0318         if 'ALCA' in step or 'Nano'==step:
0319             stepDict[stepName][k] = None
0320         self.setup__(step, stepName, stepDict, k, properties)
0321     # subordinate function for inherited classes
0322     def setup__(self, step, stepName, stepDict, k, properties):
0323         pass
0324 
0325 class UpgradeWorkflow_trackingOnly(UpgradeWorkflowTracking):
0326     def setup__(self, step, stepName, stepDict, k, properties):
0327         if 'Reco' in step: stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0328         elif 'HARVEST' in step: stepDict[stepName][k] = merge([{'-s': 'HARVESTING:@trackingOnlyValidation+@trackingOnlyDQM'}, stepDict[step][k]])
0329 
0330     def condition(self, fragment, stepList, key, hasHarvest):
0331         result = (fragment=="TTbar_13" or fragment=="TTbar_14TeV") and hasHarvest and self.condition_(fragment, stepList, key, hasHarvest)
0332         return result
0333 
0334 
0335 
0336 upgradeWFs['trackingOnly'] = UpgradeWorkflow_trackingOnly(
0337     steps = [
0338         'Reco',
0339         'RecoFakeHLT',
0340         'HARVEST',
0341         'HARVESTFakeHLT',
0342         'RecoGlobal',
0343         'RecoGlobalFakeHLT',
0344         'HARVESTGlobal',
0345         'HARVESTGlobalFakeHLT',
0346         'RecoNano',
0347         'RecoNanoFakeHLT',
0348         'HARVESTNano',
0349         'HARVESTNanoFakeHLT',
0350     ],
0351     PU = [
0352         'Reco',
0353         'RecoFakeHLT',
0354         'HARVEST',
0355         'HARVESTFakeHLT',
0356         'RecoGlobal',
0357         'HARVESTGlobal',
0358         'HARVESTGlobalFakeHLT',
0359         'RecoNano',
0360         'RecoNanoFakeHLT',
0361         'HARVESTNano',
0362         'HARVESTNanoFakeHLT',
0363     ],
0364 
0365 
0366     suffix = '_trackingOnly',
0367     offset = 0.1,
0368 )
0369 upgradeWFs['trackingOnly'].step3 = {
0370     '-s': 'RAW2DIGI,RECO:reconstruction_trackingOnly,VALIDATION:@trackingOnlyValidation,DQM:@trackingOnlyDQM',
0371     '--datatier':'GEN-SIM-RECO,DQMIO',
0372     '--eventcontent':'RECOSIM,DQM',
0373 }
0374 # used outside of upgrade WFs
0375 step3_trackingOnly = upgradeWFs['trackingOnly'].step3
0376 
0377 class UpgradeWorkflow_trackingRun2(UpgradeWorkflowTracking):
0378     def setup__(self, step, stepName, stepDict, k, properties):
0379         if 'Reco' in step and stepDict[step][k]['--era']=='Run2_2017':
0380             stepDict[stepName][k] = merge([{'--era': 'Run2_2017_trackingRun2'}, stepDict[step][k]])
0381     def condition_(self, fragment, stepList, key, hasHarvest):
0382         return '2017' in key
0383 upgradeWFs['trackingRun2'] = UpgradeWorkflow_trackingRun2(
0384     steps = [
0385         'Reco',
0386         'RecoFakeHLT',
0387     ],
0388     PU = [],
0389     suffix = '_trackingRun2',
0390     offset = 0.2,
0391 )
0392 
0393 class UpgradeWorkflow_trackingOnlyRun2(UpgradeWorkflowTracking):
0394     def setup__(self, step, stepName, stepDict, k, properties):
0395         if 'Reco' in step and stepDict[step][k]['--era']=='Run2_2017':
0396             stepDict[stepName][k] = merge([{'--era': 'Run2_2017_trackingRun2'}, self.step3, stepDict[step][k]])
0397         elif 'HARVEST' in step: stepDict[stepName][k] = merge([{'-s': 'HARVESTING:@trackingOnlyValidation+@trackingOnlyDQM'}, stepDict[step][k]])
0398     def condition_(self, fragment, stepList, key, hasHarvest):
0399         return '2017' in key
0400 upgradeWFs['trackingOnlyRun2'] = UpgradeWorkflow_trackingOnlyRun2(
0401     steps = [
0402         'Reco',
0403         'RecoFakeHLT',
0404         'HARVEST',
0405         'HARVESTFakeHLT',
0406     ],
0407     PU = [],
0408     suffix = '_trackingOnlyRun2',
0409     offset = 0.3,
0410 )
0411 upgradeWFs['trackingOnlyRun2'].step3 = upgradeWFs['trackingOnly'].step3
0412 
0413 class UpgradeWorkflow_trackingLowPU(UpgradeWorkflowTracking):
0414     def setup__(self, step, stepName, stepDict, k, properties):
0415         if 'Reco' in step and stepDict[step][k]['--era']=='Run2_2017':
0416             stepDict[stepName][k] = merge([{'--era': 'Run2_2017_trackingLowPU'}, stepDict[step][k]])
0417     def condition_(self, fragment, stepList, key, hasHarvest):
0418         return '2017' in key
0419 upgradeWFs['trackingLowPU'] = UpgradeWorkflow_trackingLowPU(
0420     steps = [
0421         'Reco',
0422         'RecoFakeHLT',
0423     ],
0424     PU = [],
0425     suffix = '_trackingLowPU',
0426     offset = 0.4,
0427 )
0428 
0429 class UpgradeWorkflow_pixelTrackingOnly(UpgradeWorkflowTracking):
0430     def setup__(self, step, stepName, stepDict, k, properties):
0431         if 'Reco' in step: stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0432         # skip ALCA step as products might not be available
0433         elif 'ALCA' in step: stepDict[stepName][k] = None
0434         elif 'HARVEST' in step: stepDict[stepName][k] = merge([{'-s': 'HARVESTING:@trackingOnlyValidation+@pixelTrackingOnlyDQM'}, stepDict[step][k]])
0435     def condition_(self, fragment, stepList, key, hasHarvest):
0436         return ('2022' in key or '2023' in key or '2024' in key or 'Run4' in key or 'HI' in key) and ('FS' not in key)
0437 upgradeWFs['pixelTrackingOnly'] = UpgradeWorkflow_pixelTrackingOnly(
0438     steps = [
0439         'Reco',
0440         'RecoFakeHLT',
0441         'HARVEST',
0442         'HARVESTFakeHLT',
0443         'RecoGlobal',
0444         'RecoGlobalFakeHLT',
0445         'HARVESTGlobal',
0446         'HARVESTGlobalFakeHLT',
0447         'RecoNano',
0448         'RecoNanoFakeHLT',
0449         'HARVESTNano',
0450         'HARVESTNanoFakeHLT',
0451         'ALCA',
0452         'ALCAPhase2'
0453     ],
0454     PU = [],
0455     suffix = '_pixelTrackingOnly',
0456     offset = 0.5,
0457 )
0458 upgradeWFs['pixelTrackingOnly'].step3 = {
0459     '-s': 'RAW2DIGI:RawToDigi_pixelOnly,RECO:reconstruction_pixelTrackingOnly,VALIDATION:@pixelTrackingOnlyValidation,DQM:@pixelTrackingOnlyDQM',
0460     '--datatier': 'GEN-SIM-RECO,DQMIO',
0461     '--eventcontent': 'RECOSIM,DQM',
0462 }
0463 
0464 class UpgradeWorkflow_trackingMkFit(UpgradeWorkflowTracking):
0465     def setup__(self, step, stepName, stepDict, k, properties):
0466         if ('Digi' in step and 'NoHLT' not in step) or ('HLTOnly' in step): stepDict[stepName][k] = merge([self.step2, stepDict[step][k]])
0467         if 'Reco' in step: stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0468     def condition_(self, fragment, stepList, key, hasHarvest):     
0469         return any(y in key for y in ['2017','2022','2023','2024','2025']) and ('FS' not in key)
0470 upgradeWFs['trackingMkFit'] = UpgradeWorkflow_trackingMkFit(
0471     steps = [
0472         'Digi',
0473         'HLTOnly',
0474         'DigiTrigger',
0475         'Reco',
0476         'RecoFakeHLT',
0477         'RecoGlobal',
0478         'RecoGlobalFakeHLT',
0479         'RecoNano',
0480         'RecoNanoFakeHLT',
0481     ],
0482     PU = [],
0483     suffix = '_trackingMkFit',
0484     offset = 0.7,
0485 )
0486 upgradeWFs['trackingMkFit'].step2 = {
0487     '--customise': 'RecoTracker/MkFit/customizeHLTIter0ToMkFit.customizeHLTIter0ToMkFit'
0488 }
0489 upgradeWFs['trackingMkFit'].step3 = {
0490     '--procModifiers': 'trackingMkFitDevel'
0491 }
0492 
0493 # mkFit for phase-2 initialStep tracking
0494 class UpgradeWorkflow_trackingMkFitPhase2(UpgradeWorkflowTracking):
0495     def setup__(self, step, stepName, stepDict, k, properties):
0496         if 'Reco' in step: stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0497     def condition_(self, fragment, stepList, key, hasHarvest):
0498         return ('Run4' in key)
0499 upgradeWFs['trackingMkFitPhase2'] = UpgradeWorkflow_trackingMkFitPhase2(
0500     steps = [
0501         'Reco',
0502         'RecoFakeHLT',
0503         'RecoGlobal',
0504         'RecoNano',
0505         'RecoNanoFakeHLT',
0506     ],
0507     PU = [],
0508     suffix = '_trackingMkFitPhase2',
0509     offset = 0.702,
0510 )
0511 upgradeWFs['trackingMkFitPhase2'].step3 = {
0512     '--procModifiers': 'trackingMkFitCommon,trackingMkFitInitialStep'
0513 }
0514 
0515 # LST on CPU, initialStep+highPtTripletStep-only tracking-only
0516 class UpgradeWorkflow_lstOnCPUIters01TrackingOnly(UpgradeWorkflowTracking):
0517     def setup__(self, step, stepName, stepDict, k, properties):
0518         if 'Reco' in step: stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0519         elif 'HARVEST' in step: stepDict[stepName][k] = merge([{'-s': 'HARVESTING:@trackingOnlyValidation+@trackingOnlyDQM'}, stepDict[step][k]])
0520         elif 'ALCA' in step: stepDict[stepName][k] = None
0521     def condition(self, fragment, stepList, key, hasHarvest):
0522         result = (fragment=="TTbar_14TeV") and hasHarvest and ('Run4' in key)
0523         return result
0524 upgradeWFs['lstOnCPUIters01TrackingOnly'] = UpgradeWorkflow_lstOnCPUIters01TrackingOnly(
0525     steps = [
0526         'RecoGlobal',
0527         'HARVESTGlobal',
0528         # Add ALCA steps explicitly, so that they can be properly removed
0529         'ALCA',
0530         'ALCAPhase2'
0531     ],
0532     PU = [
0533         'RecoGlobal',
0534         'HARVESTGlobal',
0535     ],
0536     suffix = '_lstOnCPUIters01TrackingOnly',
0537     offset = 0.703,
0538 )
0539 upgradeWFs['lstOnCPUIters01TrackingOnly'].step3 = upgradeWFs['trackingOnly'].step3 | {
0540     '--procModifiers': 'trackingIters01,trackingLST',
0541     '--accelerators' : 'cpu'
0542 }
0543 
0544 # LST on GPU (if available), initialStep+highPtTripletStep-only tracking-only
0545 class UpgradeWorkflow_lstOnGPUIters01TrackingOnly(UpgradeWorkflowTracking):
0546     def setup__(self, step, stepName, stepDict, k, properties):
0547         if 'Reco' in step: stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0548         elif 'HARVEST' in step: stepDict[stepName][k] = merge([{'-s': 'HARVESTING:@trackingOnlyValidation+@trackingOnlyDQM'}, stepDict[step][k]])
0549         elif 'ALCA' in step: stepDict[stepName][k] = None
0550     def condition(self, fragment, stepList, key, hasHarvest):
0551         result = (fragment=="TTbar_14TeV") and hasHarvest and ('Run4' in key)
0552         return result
0553 upgradeWFs['lstOnGPUIters01TrackingOnly'] = UpgradeWorkflow_lstOnGPUIters01TrackingOnly(
0554     steps = [
0555         'RecoGlobal',
0556         'HARVESTGlobal',
0557         # Add ALCA steps explicitly, so that they can be properly removed
0558         'ALCA',
0559         'ALCAPhase2'
0560     ],
0561     PU = [
0562         'RecoGlobal',
0563         'HARVESTGlobal',
0564     ],
0565     suffix = '_lstOnGPUIters01TrackingOnly',
0566     offset = 0.704,
0567 )
0568 upgradeWFs['lstOnGPUIters01TrackingOnly'].step3 = upgradeWFs['trackingOnly'].step3 | {
0569     '--procModifiers': 'trackingIters01,trackingLST',
0570 }
0571 
0572 #DeepCore seeding for JetCore iteration workflow
0573 class UpgradeWorkflow_seedingDeepCore(UpgradeWorkflow):
0574     def setup_(self, step, stepName, stepDict, k, properties):
0575         # skip ALCA and Nano steps (but not RecoNano or HARVESTNano for Run3)
0576         if 'ALCA' in step or 'Nano'==step:
0577             stepDict[stepName][k] = None
0578         elif 'Reco' in step or 'HARVEST' in step: stepDict[stepName][k] = merge([{'--procModifiers': 'seedingDeepCore'}, stepDict[step][k]])
0579     def condition(self, fragment, stepList, key, hasHarvest):
0580         result = (fragment=="QCD_Pt_1800_2400_14" or fragment=="TTbar_14TeV" ) and any(y in key for y in ['2022','2024','2025']) and hasHarvest
0581         return result
0582 upgradeWFs['seedingDeepCore'] = UpgradeWorkflow_seedingDeepCore(
0583     steps = [
0584         'Reco',
0585         'RecoFakeHLT',
0586         'HARVEST',
0587         'HARVESTFakeHLT',
0588         'RecoGlobal',
0589         'RecoGlobalFakeHLT',
0590         'HARVESTGlobal',
0591         'HARVESTGlobalFakeHLT',
0592         'RecoNano',
0593         'RecoNanoFakeHLT',
0594         'HARVESTNano',
0595         'HARVESTNanoFakeHLT',
0596         'Nano',
0597         'ALCA',
0598     ],
0599     PU = [
0600         'Reco',
0601         'RecoFakeHLT',
0602         'RecoGlobal',
0603         'RecoGlobalFakeHLT',
0604         'HARVESTGlobal',
0605         'HARVESTGlobalFakeHLT',
0606         'RecoNano',
0607         'RecoNanoFakeHLT',
0608         'HARVESTNano',
0609         'HARVESTNanoFakeHLT',
0610     ],
0611     suffix = '_seedingDeepCore',
0612     offset = 0.17,
0613 )
0614 # pixel digiMorphing workflows
0615 class UpgradeWorkflow_siPixelDigiMorphing(UpgradeWorkflow):
0616     def setup_(self, step, stepName, stepDict, k, properties):
0617         if 'Reco' in step:
0618             stepDict[stepName][k] = merge([{'--procModifiers': 'siPixelDigiMorphing'}, stepDict[step][k]])
0619     def condition(self, fragment, stepList, key, hasHarvest):
0620         result = (fragment=="QCD_Pt_1800_2400_14" or fragment=="TTbar_14TeV" ) and any(y in key for y in ['2022','2023','2024','2025'])
0621         return result
0622 upgradeWFs['siPixelDigiMorphing'] = UpgradeWorkflow_siPixelDigiMorphing(
0623     steps = [
0624         'Reco',
0625         'RecoFakeHLT',
0626         'RecoGlobal',
0627         'RecoGlobalFakeHLT',
0628         'RecoNano',
0629         'RecoNanoFakeHLT',
0630     ],
0631     PU = [
0632         'Reco',
0633         'RecoFakeHLT',
0634         'RecoGlobal',
0635         'RecoGlobalFakeHLT',
0636         'RecoNano',
0637         'RecoNanoFakeHLT',
0638     ],
0639     suffix = '_siPixelDigiMorphing',
0640     offset = 0.18,
0641 )
0642 
0643 
0644 #Workflow to enable displacedRegionalStep tracking iteration
0645 class UpgradeWorkflow_displacedRegional(UpgradeWorkflowTracking):
0646     def setup__(self, step, stepName, stepDict, k, properties):
0647         if 'Reco' in step: stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0648     def condition_(self, fragment, stepList, key, hasHarvest):
0649         return any(y in key for y in ['2022','2023','2024','2025'])
0650 upgradeWFs['displacedRegional'] = UpgradeWorkflow_displacedRegional(
0651     steps = [
0652         'Reco',
0653         'RecoFakeHLT',
0654         'RecoGlobal',
0655         'RecoGlobalFakeHLT',
0656         'RecoNano',
0657         'RecoNanoFakeHLT',
0658     ],
0659     PU = [],
0660     suffix = '_displacedRegional',
0661     offset = 0.701,
0662 )
0663 upgradeWFs['displacedRegional'].step3 = {
0664     '--procModifiers': 'displacedRegionalTracking'
0665 }
0666 
0667 # Vector Hits workflows
0668 class UpgradeWorkflow_vectorHits(UpgradeWorkflow):
0669     def setup_(self, step, stepName, stepDict, k, properties):
0670         stepDict[stepName][k] = merge([{'--procModifiers': 'vectorHits'}, stepDict[step][k]])
0671     def condition(self, fragment, stepList, key, hasHarvest):
0672         return (fragment=="TTbar_14TeV" or fragment=="SingleMuPt10Extended") and 'Run4' in key
0673 upgradeWFs['vectorHits'] = UpgradeWorkflow_vectorHits(
0674     steps = [
0675         'RecoGlobal',
0676         'RecoGlobalFakeHLT',
0677         'HARVESTGlobal'
0678     ],
0679     PU = [
0680         'RecoGlobal',
0681         'RecoGlobalFakeHLT',
0682         'HARVESTGlobal'
0683     ],
0684     suffix = '_vectorHits',
0685     offset = 0.9,
0686 )
0687 
0688 # WeightedMeanFitter vertexing workflows
0689 class UpgradeWorkflow_weightedVertex(UpgradeWorkflow):
0690     def __init__(self, **kwargs):
0691         # adapt the parameters for the UpgradeWorkflow init method
0692         super(UpgradeWorkflow_weightedVertex, self).__init__(
0693             steps = [
0694                 'Reco',
0695                 'RecoFakeHLT',
0696                 'HARVEST',
0697                 'HARVESTFakeHLT',
0698                 'RecoGlobal',
0699                 'RecoGlobalFakeHLT',
0700                 'HARVESTGlobal',
0701                 'HARVESTGlobalFakeHLT',
0702                 'RecoNano',
0703                 'RecoNanoFakeHLT',
0704                 'HARVESTNano',
0705                 'HARVESTNanoFakeHLT',
0706             ],
0707             PU = [
0708                 'Reco',
0709                 'RecoFakeHLT',
0710                 'HARVEST',
0711                 'HARVESTFakeHLT',
0712                 'RecoGlobal',
0713                 'RecoGlobalFakeHLT',
0714                 'HARVESTGlobal',
0715                 'HARVESTGlobalFakeHLT',
0716                 'RecoNano',
0717                 'RecoNanoFakeHLT',
0718                 'HARVESTNano',
0719                 'HARVESTNanoFakeHLT',
0720             ],
0721             **kwargs)
0722 
0723     def setup_(self, step, stepName, stepDict, k, properties):
0724         # temporarily remove trigger & downstream steps
0725         if 'Reco' in step:
0726             mod = {'--procModifiers': 'weightedVertexing,vertexInBlocks', '--datatier':'GEN-SIM-RECO,DQMIO',
0727             '--eventcontent':'RECOSIM,DQM'}
0728             stepDict[stepName][k] = merge([mod,self.step3, stepDict[step][k]])
0729         if 'HARVEST' in step:
0730             stepDict[stepName][k] = merge([self.step4,stepDict[step][k]])
0731 
0732     def condition(self, fragment, stepList, key, hasHarvest):
0733         # select only a subset of the workflows
0734         selected = (fragment == "TTbar_14TeV") and ('FS' not in key) and hasHarvest
0735         result =  selected and any(y in key for y in ['2022','2024','2025','Run4'])
0736 
0737         return result
0738 
0739 
0740 upgradeWFs['weightedVertex'] = UpgradeWorkflow_weightedVertex(
0741     suffix = '_weightedVertex',
0742     offset = 0.278,
0743 )
0744 
0745 upgradeWFs['weightedVertex'].step3 = {}
0746 upgradeWFs['weightedVertex'].step4 = {}
0747 
0748 upgradeWFs['weightedVertexTrackingOnly'] = UpgradeWorkflow_weightedVertex(
0749     suffix = '_weightedVertexTrackingOnly',
0750     offset = 0.279,
0751 )
0752 
0753 upgradeWFs['weightedVertexTrackingOnly'].step3 = {
0754     '-s': 'RAW2DIGI,RECO:reconstruction_trackingOnly,VALIDATION:@trackingOnlyValidation,DQM:@trackingOnlyDQM',
0755     '--datatier':'GEN-SIM-RECO,DQMIO',
0756     '--eventcontent':'RECOSIM,DQM',
0757 }
0758 
0759 upgradeWFs['weightedVertexTrackingOnly'].step4 = {
0760     '-s': 'HARVESTING:@trackingOnlyValidation+@pixelTrackingOnlyDQM'
0761 }
0762 
0763 # Special TICL Pattern recognition Workflows
0764 class UpgradeWorkflow_ticl_clue3D(UpgradeWorkflow):
0765     def setup_(self, step, stepName, stepDict, k, properties):
0766         if 'RecoGlobal' in step:
0767             stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0768         if 'HARVESTGlobal' in step:
0769             stepDict[stepName][k] = merge([self.step4, stepDict[step][k]])
0770     def condition(self, fragment, stepList, key, hasHarvest):
0771         return (fragment=="TTbar_14TeV" or 'CloseByPGun_CE' in fragment) and 'Run4' in key
0772 upgradeWFs['ticl_clue3D'] = UpgradeWorkflow_ticl_clue3D(
0773     steps = [
0774         'RecoGlobal',
0775         'RecoGlobalFakeHLT',
0776         'HARVESTGlobal'
0777     ],
0778     PU = [
0779         'RecoGlobal',
0780         'RecoGlobalFakeHLT',
0781         'HARVESTGlobal'
0782     ],
0783     suffix = '_ticl_clue3D',
0784     offset = 0.201,
0785 )
0786 upgradeWFs['ticl_clue3D'].step3 = {'--procModifiers': 'clue3D'}
0787 upgradeWFs['ticl_clue3D'].step4 = {'--procModifiers': 'clue3D'}
0788 
0789 class UpgradeWorkflow_ticl_FastJet(UpgradeWorkflow):
0790     def setup_(self, step, stepName, stepDict, k, properties):
0791         if 'RecoGlobal' in step:
0792             stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0793         if 'HARVESTGlobal' in step:
0794             stepDict[stepName][k] = merge([self.step4, stepDict[step][k]])
0795     def condition(self, fragment, stepList, key, hasHarvest):
0796         return (fragment=="TTbar_14TeV" or 'CloseByPGun_CE' in fragment) and 'Run4' in key
0797 upgradeWFs['ticl_FastJet'] = UpgradeWorkflow_ticl_FastJet(
0798     steps = [
0799         'RecoGlobal',
0800         'RecoGlobalFakeHLT',
0801         'HARVESTGlobal'
0802     ],
0803     PU = [
0804         'RecoGlobal',
0805         'RecoGlobalFakeHLT',
0806         'HARVESTGlobal'
0807     ],
0808     suffix = '_ticl_FastJet',
0809     offset = 0.202,
0810 )
0811 upgradeWFs['ticl_FastJet'].step3 = {'--procModifiers': 'fastJetTICL'}
0812 upgradeWFs['ticl_FastJet'].step4 = {'--procModifiers': 'fastJetTICL'}
0813 
0814 class UpgradeWorkflow_ticl_v5(UpgradeWorkflow):
0815     def setup_(self, step, stepName, stepDict, k, properties):
0816         if ('Digi' in step and 'NoHLT' not in step) or ('HLTOnly' in step):
0817             stepDict[stepName][k] = merge([self.step2, stepDict[step][k]])
0818         if 'RecoGlobal' in step:
0819             stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0820         if 'HARVESTGlobal' in step:
0821             stepDict[stepName][k] = merge([self.step4, stepDict[step][k]])
0822     def condition(self, fragment, stepList, key, hasHarvest):
0823         return (fragment=="TTbar_14TeV" or 'CloseByP' in fragment or 'Eta1p7_2p7' in fragment) and 'Run4' in key
0824 
0825 upgradeWFs['ticl_v5'] = UpgradeWorkflow_ticl_v5(
0826     steps = [
0827         'HLTOnly',
0828         'DigiTrigger',
0829         'RecoGlobal',
0830         'HARVESTGlobal'
0831     ],
0832     PU = [
0833         'HLTOnly',
0834         'DigiTrigger',
0835         'RecoGlobal',
0836         'HARVESTGlobal'
0837     ],
0838     suffix = '_ticl_v5',
0839     offset = 0.203,
0840 )
0841 upgradeWFs['ticl_v5'].step2 = {'--procModifiers': 'ticl_v5'}
0842 upgradeWFs['ticl_v5'].step3 = {'--procModifiers': 'ticl_v5'}
0843 upgradeWFs['ticl_v5'].step4 = {'--procModifiers': 'ticl_v5'}
0844 
0845 class UpgradeWorkflow_ticl_v5_superclustering(UpgradeWorkflow):
0846     def setup_(self, step, stepName, stepDict, k, properties):
0847         if ('Digi' in step and 'NoHLT' not in step) or ('HLTOnly' in step):
0848             stepDict[stepName][k] = merge([self.step2, stepDict[step][k]])
0849         if 'RecoGlobal' in step:
0850             stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0851         if 'HARVESTGlobal' in step:
0852             stepDict[stepName][k] = merge([self.step4, stepDict[step][k]])
0853     def condition(self, fragment, stepList, key, hasHarvest):
0854         return (fragment=="ZEE_14" or 'Eta1p7_2p7' in fragment) and 'Run4' in key
0855 upgradeWFs['ticl_v5_superclustering_mustache_ticl'] = UpgradeWorkflow_ticl_v5_superclustering(
0856     steps = [
0857         'HLTOnly',
0858         'DigiTrigger',
0859         'RecoGlobal',
0860         'HARVESTGlobal'
0861     ],
0862     PU = [
0863         'HLTOnly',
0864         'DigiTrigger',
0865         'RecoGlobal',
0866         'HARVESTGlobal'
0867     ],
0868     suffix = '_ticl_v5_mustache',
0869     offset = 0.204,
0870 )
0871 upgradeWFs['ticl_v5_superclustering_mustache_ticl'].step2 = {'--procModifiers': 'ticl_v5,ticl_superclustering_mustache_ticl'}
0872 upgradeWFs['ticl_v5_superclustering_mustache_ticl'].step3 = {'--procModifiers': 'ticl_v5,ticl_superclustering_mustache_ticl'}
0873 upgradeWFs['ticl_v5_superclustering_mustache_ticl'].step4 = {'--procModifiers': 'ticl_v5,ticl_superclustering_mustache_ticl'}
0874 
0875 upgradeWFs['ticl_v5_superclustering_mustache_pf'] = UpgradeWorkflow_ticl_v5_superclustering(
0876     steps = [
0877         'RecoGlobal',
0878         'RecoGlobalFakeHLT',
0879         'HARVESTGlobal'
0880     ],
0881     PU = [
0882         'RecoGlobal',
0883         'RecoGlobalFakeHLT',
0884         'HARVESTGlobal'
0885     ],
0886     suffix = '_ticl_v5_mustache_pf',
0887     offset = 0.205,
0888 )
0889 upgradeWFs['ticl_v5_superclustering_mustache_pf'].step3 = {'--procModifiers': 'ticl_v5,ticl_superclustering_mustache_pf'}
0890 upgradeWFs['ticl_v5_superclustering_mustache_pf'].step4 = {'--procModifiers': 'ticl_v5,ticl_superclustering_mustache_pf'}
0891 
0892 class UpgradeWorkflow_TICLdumper(UpgradeWorkflow):
0893     def setup_(self, step, stepName, stepDict, k, properties):
0894         if 'RecoGlobal' in step:
0895             stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0896     def condition(self, fragment, stepList, key, hasHarvest):
0897         return (fragment=="TTbar_14TeV" or 'CloseByP' in fragment or 'Eta1p7_2p7' in fragment) and 'Run4' in key
0898 
0899 upgradeWFs['enableTICLdumper'] = UpgradeWorkflow_TICLdumper(
0900     steps = [
0901         'RecoGlobal',
0902     ],
0903     PU = [
0904         'RecoGlobal',
0905     ],
0906     suffix = '_enableTICLdumper',
0907     offset = 0.206,
0908 )
0909 upgradeWFs['enableTICLdumper'].step3 = {'--customise': 'RecoHGCal/TICL/customiseTICLFromReco.customiseTICLForDumper'}
0910 
0911 upgradeWFs['ticl_v5_withDumper'] = UpgradeWorkflow_ticl_v5(
0912     steps = [
0913         'HLTOnly',
0914         'DigiTrigger',
0915         'RecoGlobal',
0916         'HARVESTGlobal'
0917     ],
0918     PU = [
0919         'HLTOnly',
0920         'DigiTrigger',
0921         'RecoGlobal',
0922         'HARVESTGlobal'
0923     ],
0924     suffix = '_ticl_v5_withDumper',
0925     offset = 0.207,
0926 )
0927 upgradeWFs['ticl_v5_withDumper'].step2 = {'--procModifiers': 'ticl_v5'}
0928 upgradeWFs['ticl_v5_withDumper'].step3 = {'--procModifiers': 'ticl_v5',
0929                                           '--customise': 'RecoHGCal/TICL/customiseTICLFromReco.customiseTICLForDumper'}
0930 upgradeWFs['ticl_v5_withDumper'].step4 = {'--procModifiers': 'ticl_v5'}
0931 
0932 class UpgradeWorkflow_CPfromPU(UpgradeWorkflow):
0933     def setup_(self, step, stepName, stepDict, k, properties):
0934         if ('Digi' in step and 'NoHLT' not in step) or ('HLTOnly' in step):
0935             stepDict[stepName][k] = merge([self.step2, stepDict[step][k]])
0936         if 'RecoGlobal' in step:
0937             stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0938         if 'HARVESTGlobal' in step:
0939             stepDict[stepName][k] = merge([self.step4, stepDict[step][k]])
0940     def condition(self, fragment, stepList, key, hasHarvest):
0941         return (fragment=="TTbar_14TeV" or 'CloseByP' in fragment or 'Eta1p7_2p7' in fragment) and 'Run4' in key
0942 
0943 upgradeWFs['CPfromPU'] = UpgradeWorkflow_CPfromPU(
0944     steps = [
0945         'HLTOnly',
0946         'DigiTrigger',
0947         'RecoGlobal',
0948         'HARVESTGlobal'
0949     ],
0950     PU = [
0951         'HLTOnly',
0952         'DigiTrigger',
0953         'RecoGlobal',
0954         'HARVESTGlobal'
0955     ],
0956     suffix = '_withCPfromPU',
0957     offset = 0.208,
0958 )
0959 
0960 upgradeWFs['CPfromPU'].step2 = {'--procModifiers': 'enableCPfromPU'}
0961 upgradeWFs['CPfromPU'].step3 = {'--procModifiers': 'enableCPfromPU'}
0962 upgradeWFs['CPfromPU'].step4 = {'--procModifiers': 'enableCPfromPU'}
0963 
0964 # Improved L2 seeding from L1Tk Muons and L3 Tracker Muon Inside-Out reconstruction first (Phase-2 Muon default)
0965 class UpgradeWorkflow_phase2L2AndL3Muons(UpgradeWorkflow):
0966     def setup_(self, step, stepName, stepDict, k, properties):
0967         if ('Digi' in step and 'NoHLT' not in step) or ('HLTOnly' in step):
0968             stepDict[stepName][k] = merge([self.step2, stepDict[step][k]])
0969         if 'RecoGlobal' in step:
0970             stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
0971         if 'HARVESTGlobal' in step:
0972             stepDict[stepName][k] = merge([self.step4, stepDict[step][k]])
0973     def condition(self, fragment, stepList, key, hasHarvest):
0974         return (fragment=="ZMM_14" or 'SingleMu' in fragment or 'TTbar_14' in fragment) and 'Run4' in key
0975 
0976 upgradeWFs['phase2L2AndL3Muons'] = UpgradeWorkflow_phase2L2AndL3Muons(
0977     steps = [
0978         'HLTOnly',
0979         'DigiTrigger',
0980         'RecoGlobal',
0981         'HARVESTGlobal'
0982     ],
0983     PU = [
0984         'HLTOnly',
0985         'DigiTrigger',
0986         'RecoGlobal',
0987         'HARVESTGlobal'
0988     ],
0989     suffix = '_phase2L2AndL3MuonsIOFirst',
0990     offset = 0.777,
0991 )
0992 upgradeWFs['phase2L2AndL3Muons'].step2 = {'-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,L1P2GT,DIGI2RAW,HLT:@relvalRun4,NANO:@MUHLT',
0993                                           '--datatier':'GEN-SIM-DIGI-RAW,NANOAODSIM',
0994                                           '--eventcontent':'FEVTDEBUGHLT,NANOAODSIM',
0995                                           '--procModifiers':'phase2L2AndL3Muons'}
0996 upgradeWFs['phase2L2AndL3Muons'].step3 = {'--procModifiers':'phase2L2AndL3Muons'}
0997 upgradeWFs['phase2L2AndL3Muons'].step4 = {'--procModifiers':'phase2L2AndL3Muons'}
0998 
0999 # Improved L2 seeding from L1Tk Muons and L3 Tracker Muon Outside-In reconstruction first
1000 class UpgradeWorkflow_phase2L3MuonsOIFirst(UpgradeWorkflow):
1001     def setup_(self, step, stepName, stepDict, k, properties):
1002         if ('Digi' in step and 'NoHLT' not in step) or ('HLTOnly' in step):
1003             stepDict[stepName][k] = merge([self.step2, stepDict[step][k]])
1004         if 'RecoGlobal' in step:
1005             stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
1006         if 'HARVESTGlobal' in step:
1007             stepDict[stepName][k] = merge([self.step4, stepDict[step][k]])
1008     def condition(self, fragment, stepList, key, hasHarvest):
1009         return (fragment=="ZMM_14" or 'SingleMu' in fragment or 'TTbar_14' in fragment) and 'Run4' in key
1010 
1011 upgradeWFs['phase2L3MuonsOIFirst'] = UpgradeWorkflow_phase2L3MuonsOIFirst(
1012     steps = [
1013         'HLTOnly',
1014         'DigiTrigger',
1015         'RecoGlobal',
1016         'HARVESTGlobal'
1017     ],
1018     PU = [
1019         'HLTOnly',
1020         'DigiTrigger',
1021         'RecoGlobal',
1022         'HARVESTGlobal'
1023     ],
1024     suffix = '_phase2L2AndL3MuonsOIFirst',
1025     offset = 0.778,
1026 )
1027 upgradeWFs['phase2L3MuonsOIFirst'].step2 = {'-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,L1P2GT,DIGI2RAW,HLT:@relvalRun4,NANO:@MUHLT',
1028                                             '--datatier':'GEN-SIM-DIGI-RAW,NANOAODSIM',
1029                                             '--eventcontent':'FEVTDEBUGHLT,NANOAODSIM',
1030                                             '--procModifiers':'phase2L2AndL3Muons,phase2L3MuonsOIFirst'}
1031 upgradeWFs['phase2L3MuonsOIFirst'].step3 = {'--procModifiers':'phase2L2AndL3Muons,phase2L3MuonsOIFirst'}
1032 upgradeWFs['phase2L3MuonsOIFirst'].step4 = {'--procModifiers':'phase2L2AndL3Muons,phase2L3MuonsOIFirst'}
1033 
1034 # Track DNN workflows
1035 class UpgradeWorkflow_trackdnn(UpgradeWorkflow):
1036     def setup_(self, step, stepName, stepDict, k, properties):
1037         stepDict[stepName][k] = merge([{'--procModifiers': 'trackdnn'}, stepDict[step][k]])
1038 
1039     def condition(self, fragment, stepList, key, hasHarvest):
1040         return fragment=="TTbar_14TeV" and '2022' in key
1041 upgradeWFs['trackdnn'] = UpgradeWorkflow_trackdnn(
1042     steps = [
1043         'Reco',
1044         'RecoFakeHLT',
1045         'RecoNano',
1046         'RecoNanoFakeHLT',
1047     ],
1048     PU = [
1049         'Reco',
1050         'RecoFakeHLT',
1051         'RecoNano',
1052         'RecoNanoFakeHLT',
1053     ],
1054     suffix = '_trackdnn',
1055     offset = 0.91,
1056 )
1057 
1058 
1059 # MLPF workflows
1060 class UpgradeWorkflow_mlpf(UpgradeWorkflow):
1061     def setup_(self, step, stepName, stepDict, k, properties):
1062         if 'Reco' in step:
1063             stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
1064     def condition(self, fragment, stepList, key, hasHarvest):
1065         return (fragment=="TTbar_14TeV" or fragment=="QCD_FlatPt_15_3000HS_14") and '2022PU' in key
1066 
1067 upgradeWFs['mlpf'] = UpgradeWorkflow_mlpf(
1068     steps = [
1069         'Reco',
1070         'RecoFakeHLT',
1071         'RecoNano',
1072         'RecoNanoFakeHLT',
1073     ],
1074     PU = [
1075         'Reco',
1076         'RecoFakeHLT',
1077         'RecoNano',
1078         'RecoNanoFakeHLT',
1079     ],
1080     suffix = '_mlpf',
1081     offset = 0.13,
1082 )
1083 upgradeWFs['mlpf'].step3 = {
1084     '--datatier': 'GEN-SIM-RECO,RECOSIM,MINIAODSIM,NANOAODSIM,DQMIO',
1085     '--eventcontent': 'FEVTDEBUGHLT,RECOSIM,MINIAODSIM,NANOEDMAODSIM,DQM',
1086     '--procModifiers': 'mlpf'
1087 }
1088 
1089 
1090 # ECAL DeepSC clustering studies workflow
1091 class UpgradeWorkflow_ecalclustering(UpgradeWorkflow):
1092     def setup_(self, step, stepName, stepDict, k, properties):
1093         if 'Reco' in step:
1094             stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
1095     def condition(self, fragment, stepList, key, hasHarvest):
1096         return (fragment=="ZEE_14" or fragment=="TTbar_14TeV" or fragment=="WprimeTolNu_M3000_13TeV_pythia8"
1097             or fragment=="DisplacedSUSY_stopToBottom_M_300_1000mm_13" or fragment=="RunEGamma2018D" )
1098 
1099 upgradeWFs['ecalDeepSC'] = UpgradeWorkflow_ecalclustering(
1100     steps = [
1101         'Reco',
1102         'RecoFakeHLT',
1103         'RecoNano',
1104         'RecoNanoFakeHLT',
1105     ],
1106     PU = [
1107         'Reco',
1108         'RecoFakeHLT',
1109         'RecoNano',
1110         'RecoNanoFakeHLT',
1111     ],
1112     suffix = '_ecalDeepSC',
1113     offset = 0.19,
1114 )
1115 upgradeWFs['ecalDeepSC'].step3 = {
1116     '--datatier': 'RECOSIM,MINIAODSIM,NANOAODSIM,DQMIO',
1117     '--eventcontent': 'RECOSIM,MINIAODSIM,NANOEDMAODSIM,DQM',
1118     '--procModifiers': 'ecal_deepsc'
1119 }
1120 
1121 
1122 # photonDRN workflows
1123 class UpgradeWorkflow_photonDRN(UpgradeWorkflow):
1124     def setup_(self, step, stepName, stepDict, k, properties):
1125         if 'Reco' in step:
1126             stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
1127     def condition(self, fragment, stepList, key, hasHarvest):
1128         return '2018' in key and "SingleGamma" in fragment
1129 
1130 upgradeWFs['photonDRN'] = UpgradeWorkflow_photonDRN(
1131     steps = [
1132         'RecoFakeHLT',
1133         'RecoNanoFakeHLT',
1134     ],
1135     PU = [
1136         'RecoFakeHLT',
1137         'RecoNanoFakeHLT',
1138     ],
1139     suffix = '_photonDRN',
1140     offset = 0.31,
1141 )
1142 upgradeWFs['photonDRN'].step3 = {
1143     '--procModifiers': 'enableSonicTriton,photonDRN'
1144 }
1145 
1146 
1147 # Patatrack workflows (NoPU and PU):
1148 #   - TTbar_14, ZMM_14", ZEE_14, ZTT_14, NuGun, SingleMu, QCD_Pt15To7000_Flat for
1149 #       > 2022, 2023, 2024, 2025 and Run4 conditions, TTbar
1150 #   - Hydjet for HI conditions
1151 class PatatrackWorkflow(UpgradeWorkflow):
1152     def __init__(self, digi = {}, reco = {}, mini = {}, harvest = {}, **kwargs):
1153         # adapt the parameters for the UpgradeWorkflow init method
1154         super(PatatrackWorkflow, self).__init__(
1155             steps = [
1156                 'Digi',
1157                 'HLTOnly',
1158                 'DigiTrigger',
1159                 'Reco',
1160                 'RecoFakeHLT',
1161                 'HARVEST',
1162                 'HARVESTFakeHLT',
1163                 'RecoGlobal',
1164                 'RecoGlobalFakeHLT',
1165                 'HARVESTGlobal',
1166                 'HARVESTGlobalFakeHLT',
1167                 'RecoNano',
1168                 'RecoNanoFakeHLT',
1169                 'HARVESTNano',
1170                 'HARVESTNanoFakeHLT',
1171                 'MiniAOD',
1172                 'Nano',
1173                 'ALCA',
1174                 'ALCAPhase2'
1175             ],
1176             PU = [
1177                 'Digi',
1178                 'HLTOnly',
1179                 'DigiTrigger',
1180                 'Reco',
1181                 'RecoFakeHLT',
1182                 'HARVEST',
1183                 'HARVESTFakeHLT',
1184                 'RecoGlobal',
1185                 'RecoGlobalFakeHLT',
1186                 'HARVESTGlobal',
1187                 'HARVESTGlobalFakeHLT',
1188                 'RecoNano',
1189                 'RecoNanoFakeHLT',
1190                 'HARVESTNano',
1191                 'HARVESTNanoFakeHLT',
1192                 'MiniAOD',
1193                 'Nano',
1194                 'ALCA',
1195                 'ALCAPhase2'
1196             ],
1197             **kwargs)
1198         self.__digi = digi
1199         self.__reco = reco
1200         if 'DQM' in self.__reco:
1201             self.__reco.update({
1202                 '--datatier':     'GEN-SIM-RECO,DQMIO',
1203                 '--eventcontent': 'RECOSIM,DQM'
1204             })
1205         self.__mini = mini
1206         self.__harvest = harvest
1207 
1208     def condition(self, fragment, stepList, key, hasHarvest):
1209         # select only a subset of the workflows
1210         years = ['2022','2023','2024','2025','Run4']
1211         fragments = ["TTbar_14","ZMM_14","ZEE_14","ZTT_14","NuGun","SingleMu","QCD_Pt15To7000_Flat"]
1212         selected = [
1213             (any(y in key for y in years) and ('FS' not in key) and any( f in fragment for f in fragments)),
1214             (('HI' in key) and ('Hydjet' in fragment) and ("PixelOnly" in self.suffix) )
1215         ]
1216         result = any(selected) and hasHarvest
1217 
1218         return result
1219 
1220     def setup_(self, step, stepName, stepDict, k, properties):
1221         # skip ALCA and Nano steps (but not RecoNano or HARVESTNano for Run3)
1222         if 'ALCA' in step or 'Nano'==step:
1223             stepDict[stepName][k] = None
1224         elif ('Digi' in step and "NoHLT" not in step) or 'HLTOnly' in step:
1225             if self.__digi is None:
1226               stepDict[stepName][k] = None
1227             else:
1228               stepDict[stepName][k] = merge([self.__digi, stepDict[step][k]])
1229         elif 'Reco' in step:
1230             if self.__reco is None:
1231               stepDict[stepName][k] = None
1232             else:
1233               stepDict[stepName][k] = merge([self.__reco, stepDict[step][k]])
1234             if 'Phase2' in stepDict[stepName][k]['--era']:
1235                 if 'DQM:@standardDQM+@ExtraHLT' in stepDict[stepName][k]['-s']:
1236                     stepDict[stepName][k]['-s'] = stepDict[stepName][k]['-s'].replace('DQM:@standardDQM+@ExtraHLT','DQM:@phase2')
1237                 if 'VALIDATION:@standardValidation' in stepDict[stepName][k]['-s']:
1238                     stepDict[stepName][k]['-s'] = stepDict[stepName][k]['-s'].replace('VALIDATION:@standardValidation','VALIDATION:@phase2Validation')
1239 
1240 
1241         elif 'MiniAOD' in step:
1242             if self.__mini is None:
1243               stepDict[stepName][k] = None
1244             else:
1245               stepDict[stepName][k] = merge([self.__mini, stepDict[step][k]])
1246         elif 'HARVEST' in step:
1247             if self.__harvest is None:
1248               stepDict[stepName][k] = None
1249             else:
1250               stepDict[stepName][k] = merge([self.__harvest, stepDict[step][k]])
1251 
1252 ###############################################################################################################
1253 ### Calorimeter-only reco
1254 ### these are not technically Patarack workflows but for
1255 ### the moment we can still leverage on the PatatrackWorkflow
1256 ### constructor for simplicity
1257 
1258 # ECAL-only workflow running on CPU
1259 #  - HLT on CPU
1260 #  - ECAL-only reconstruction on CPU, with DQM and validation
1261 #  - harvesting
1262 upgradeWFs['ECALOnlyCPU'] = PatatrackWorkflow(
1263     digi = {
1264         # the HLT menu is already set up for using GPUs if available and if the "gpu" modifier is enabled
1265     },
1266     reco = {
1267         '-s': 'RAW2DIGI:RawToDigi_ecalOnly,RECO:reconstruction_ecalOnly,VALIDATION:@ecalOnlyValidation,DQM:@ecalOnly',
1268     },
1269     harvest = {
1270         '-s': 'HARVESTING:@ecalOnlyValidation+@ecal'
1271     },
1272     suffix = 'ECALOnlyCPU',
1273     offset = 0.511,
1274 )
1275 
1276 # HCAL-only workflow running on CPU
1277 #  - HLT on CPU
1278 #  - HCAL-only reconstruction on CPU, with DQM and validation
1279 #  - harvesting
1280 upgradeWFs['HCALOnlyCPU'] = PatatrackWorkflow(
1281     digi = {
1282         # the HLT menu is already set up for using GPUs if available and if the "gpu" modifier is enabled
1283     },
1284     reco = {
1285         '-s': 'RAW2DIGI:RawToDigi_hcalOnly,RECO:reconstruction_hcalOnly,VALIDATION:@hcalOnlyValidation,DQM:@hcalOnly+@hcal2Only',
1286     },
1287     harvest = {
1288         '-s': 'HARVESTING:@hcalOnlyValidation+@hcalOnly+@hcal2Only'
1289     },
1290     suffix = 'HCALOnlyCPU',
1291     offset = 0.521,
1292 )
1293 
1294 ###############################################################################################################
1295 ### Alpaka workflows
1296 ###
1297 
1298 # ECAL-only workflow running on CPU or GPU with Alpaka code
1299 #  - HLT with Alpaka
1300 #  - ECAL-only reconstruction with Alpaka, with DQM and validation
1301 #  - harvesting
1302 upgradeWFs['PatatrackECALOnlyAlpaka'] = PatatrackWorkflow(
1303     digi = {
1304         # customize the ECAL Local Reco part of the HLT menu for Alpaka
1305         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1306     },
1307     reco = {
1308         '-s': 'RAW2DIGI:RawToDigi_ecalOnly,RECO:reconstruction_ecalOnly,VALIDATION:@ecalOnlyValidation,DQM:@ecalOnly',
1309         '--procModifiers': 'alpaka',
1310         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1311     },
1312     harvest = {
1313         '-s': 'HARVESTING:@ecalOnlyValidation+@ecal'
1314     },
1315     suffix = 'Patatrack_ECALOnlyAlpaka',
1316     offset = 0.412,
1317 )
1318 
1319 # ECAL-only workflow running on CPU or GPU with Alpaka code
1320 #  - HLT with Alpaka
1321 #  - ECAL-only reconstruction with Alpaka on both CPU and GPU, with DQM and validation for GPU-vs-CPU comparisons
1322 #  - harvesting
1323 upgradeWFs['PatatrackECALOnlyAlpakaValidation'] = PatatrackWorkflow(
1324     digi = {
1325         # customize the ECAL Local Reco part of the HLT menu for Alpaka
1326         '--procModifiers': 'alpaka',
1327         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1328     },
1329     reco = {
1330         '-s': 'RAW2DIGI:RawToDigi_ecalOnly,RECO:reconstruction_ecalOnly,VALIDATION:@ecalOnlyValidation,DQM:@ecalOnly',
1331         '--procModifiers': 'alpakaValidation',
1332         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1333     },
1334     harvest = {
1335         '-s': 'HARVESTING:@ecalOnlyValidation+@ecal'
1336     },
1337     suffix = 'Patatrack_ECALOnlyAlpakaValidation',
1338     offset = 0.413,
1339 )
1340 
1341 # HCAL-PF Only workflow running HCAL local reco on GPU and PF with Alpaka with DQM and Validation
1342 # - HLT-alpaka
1343 # - HCAL-only reconstruction using Alpaka with DQM and Validation
1344 upgradeWFs['PatatrackHCALOnlyAlpakaValidation'] = PatatrackWorkflow(
1345     digi = { 
1346         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1347     },
1348     reco = {
1349         '-s': 'RAW2DIGI:RawToDigi_hcalOnly,RECO:reconstruction_hcalOnly,VALIDATION:@hcalOnlyValidation,DQM:@hcalOnly+@hcal2Only',
1350         '--procModifiers': 'alpaka',
1351         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1352     },
1353     harvest = {
1354         '-s': 'HARVESTING:@hcalOnlyValidation'
1355     },
1356     suffix = 'Patatrack_HCALOnlyAlpaka_Validation',
1357     offset = 0.422,
1358 )
1359 
1360 # HCAL-PF Only workflow running HCAL local reco and PF with Alpaka with cluster level-validation
1361 # - HLT-alpaka
1362 # - HCAL-only reconstruction using GPU and Alpaka with DQM and Validation for PF Alpaka vs CPU comparisons
1363 upgradeWFs['PatatrackHCALOnlyGPUandAlpakaValidation'] = PatatrackWorkflow(
1364     digi = {
1365         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1366     },
1367     reco = {
1368         '-s': 'RAW2DIGI:RawToDigi_hcalOnly,RECO:reconstruction_hcalOnlyLegacy+reconstruction_hcalOnly,VALIDATION:@hcalOnlyValidation+pfClusterHBHEOnlyAlpakaComparisonSequence,DQM:@hcalOnly+@hcal2Only+hcalOnlyOfflineSourceSequenceAlpaka',
1369         '--procModifiers': 'alpaka',
1370         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1371     },
1372     harvest = {
1373         '-s': 'HARVESTING:@hcalOnlyValidation'
1374     },
1375     suffix = 'Patatrack_HCALOnlyGPUandAlpaka_Validation',
1376     offset = 0.423,
1377 )
1378 
1379 # HCAL-PF Only workflow running HCAL local reco on CPU and PF with Alpaka slimmed for benchmarking
1380 # - HLT-alpaka
1381 # - HCAL-only reconstruction using Alpaka
1382 upgradeWFs['PatatrackHCALOnlyAlpakaProfiling'] = PatatrackWorkflow(
1383     digi = {
1384     },
1385     reco = {
1386         '-s': 'RAW2DIGI:RawToDigi_hcalOnly,RECO:reconstruction_hcalOnly',
1387         '--procModifiers': 'alpaka'
1388     },
1389     harvest = None,
1390     suffix = 'Patatrack_HCALOnlyAlpaka_Profiling',
1391     offset = 0.424,
1392 )
1393 
1394 # Workflow running the Pixel quadruplets, ECAL and HCAL reconstruction on GPU (optional), PF using Alpaka, together with the full offline reconstruction on CPU
1395 #  - HLT on GPU (optional)
1396 #  - reconstruction on Alpaka, with DQM and validation
1397 #  - harvesting
1398 upgradeWFs['PatatrackFullRecoAlpaka'] = PatatrackWorkflow(
1399     digi = {
1400         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1401     },
1402     reco = {
1403         # skip the @pixelTrackingOnlyValidation which cannot run together with the full reconstruction
1404         '-s': 'RAW2DIGI:RawToDigi+RawToDigi_pixelOnly,L1Reco,RECO:reconstruction+reconstruction_pixelTrackingOnly,RECOSIM,PAT,VALIDATION:@standardValidation+@miniAODValidation,DQM:@standardDQM+@ExtraHLT+@miniAODDQM+@pixelTrackingOnlyDQM',
1405         '--procModifiers': 'alpaka',
1406         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1407     },
1408     harvest = {
1409         # skip the @pixelTrackingOnlyDQM harvesting
1410     },
1411     suffix = 'Patatrack_FullRecoAlpaka',
1412     offset = 0.492,
1413 )
1414 
1415 # Workflow running the Pixel triplets, ECAL and HCAL reconstruction on GPU (optional), PF using Alpaka, together with the full offline reconstruction on CPU
1416 #  - HLT on GPU (optional)
1417 #  - reconstruction on Alpaka, with DQM and validation
1418 #  - harvesting
1419 
1420 upgradeWFs['PatatrackFullRecoAlpaka'] = PatatrackWorkflow(
1421     digi = {
1422         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1423     },
1424     reco = {
1425         # skip the @pixelTrackingOnlyValidation which cannot run together with the full reconstruction
1426         '-s': 'RAW2DIGI:RawToDigi+RawToDigi_pixelOnly,L1Reco,RECO:reconstruction+reconstruction_pixelTrackingOnly,RECOSIM,PAT,VALIDATION:@standardValidation+@miniAODValidation,DQM:@standardDQM+@ExtraHLT+@miniAODDQM+@pixelTrackingOnlyDQM',
1427         '--procModifiers': 'alpaka',
1428         '--customise' : 'RecoTracker/Configuration/customizePixelTracksForTriplets.customizePixelTracksForTriplets,HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1429     },
1430     harvest = {
1431         # skip the @pixelTrackingOnlyDQM harvesting
1432     },
1433     suffix = 'Patatrack_FullRecoAlpakaTriplets',
1434     offset = 0.496,
1435 )
1436 
1437 # Pixel-only quadruplets workflow running on GPU (optional)
1438 #  - Pixel-only reconstruction with Alpaka, with DQM and validation
1439 #  - harvesting
1440 
1441 upgradeWFs['PatatrackPixelOnlyAlpaka'] = PatatrackWorkflow(
1442     digi = {
1443         '--procModifiers': 'alpaka', 
1444         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1445     },
1446     reco = {
1447         '-s': 'RAW2DIGI:RawToDigi_pixelOnly,RECO:reconstruction_pixelTrackingOnly,VALIDATION:@pixelTrackingOnlyValidation,DQM:@pixelTrackingOnlyDQM',
1448         '--procModifiers': 'alpaka',
1449         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1450     },
1451     harvest = {
1452         '-s': 'HARVESTING:@trackingOnlyValidation+@pixelTrackingOnlyDQM'
1453     },
1454     suffix = 'Patatrack_PixelOnlyAlpaka',
1455     offset = 0.402,
1456 )
1457 
1458 # Pixel-only quadruplets workflow running on GPU (optional)
1459 #  - Pixel-only reconstruction with Alpaka, with standard and CPUvsGPU DQM and validation
1460 #  - harvesting for CPUvsGPU validation
1461 
1462 upgradeWFs['PatatrackPixelOnlyAlpakaValidation'] = PatatrackWorkflow(
1463     digi = {
1464         '--procModifiers': 'alpaka', 
1465         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1466     },
1467     reco = {
1468         '-s': 'RAW2DIGI:RawToDigi_pixelOnly,RECO:reconstruction_pixelTrackingOnly,VALIDATION:@pixelTrackingOnlyValidation,DQM:@pixelTrackingOnlyDQM',
1469         '--procModifiers': 'alpakaValidation',
1470         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1471     },
1472     harvest = {
1473         '-s': 'HARVESTING:@trackingOnlyValidation+@pixelTrackingOnlyDQM',
1474         '--procModifiers': 'alpakaValidation',
1475     },
1476     suffix = 'Patatrack_PixelOnlyAlpaka_Validation',
1477     offset = 0.403,
1478 )
1479 
1480 # Pixel-only quadruplets workflow running on CPU or GPU, trimmed down for benchmarking
1481 
1482 upgradeWFs['PatatrackPixelOnlyAlpakaProfiling'] = PatatrackWorkflow(
1483     digi = {
1484         '--procModifiers': 'alpaka', 
1485     },
1486     reco = {
1487         '-s': 'RAW2DIGI:RawToDigi_pixelOnly,RECO:reconstruction_pixelTrackingOnly',
1488         '--procModifiers': 'alpaka',
1489         '--customise' : 'RecoTracker/Configuration/customizePixelOnlyForProfiling.customizePixelOnlyForProfilingGPUOnly'
1490     },
1491     harvest = None,
1492     suffix = 'Patatrack_PixelOnlyAlpaka_Profiling',
1493     offset = 0.404,
1494 )
1495 
1496 
1497 # Pixel-only triplets workflow running on GPU (optional)
1498 #  - Pixel-only reconstruction with Alpaka, with standard and CPUvsGPU DQM and validation
1499 #  - harvesting for CPUvsGPU validation
1500 
1501 upgradeWFs['PatatrackPixelOnlyTripletsAlpaka'] = PatatrackWorkflow(
1502     digi = {
1503         '--procModifiers': 'alpaka',
1504         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1505     },
1506     reco = {
1507         '-s': 'RAW2DIGI:RawToDigi_pixelOnly,RECO:reconstruction_pixelTrackingOnly,VALIDATION:@pixelTrackingOnlyValidation,DQM:@pixelTrackingOnlyDQM',
1508         '--procModifiers': 'alpaka',
1509         '--customise' : 'RecoTracker/Configuration/customizePixelTracksForTriplets.customizePixelTracksForTriplets,HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling'
1510     },
1511     harvest = {
1512         '-s': 'HARVESTING:@trackingOnlyValidation+@pixelTrackingOnlyDQM'
1513     },
1514     suffix = 'Patatrack_PixelOnlyTripletsAlpaka',
1515     offset = 0.406,
1516 )
1517 
1518 # Pixel-only triplets workflow running on GPU (optional)
1519 #  - Pixel-only reconstruction with Alpaka, with standard and CPUvsGPU DQM and validation
1520 #  - harvesting for CPUvsGPU validation
1521 
1522 upgradeWFs['PatatrackPixelOnlyTripletsAlpakaValidation'] = PatatrackWorkflow(
1523     digi = { 
1524         '--procModifiers': 'alpaka',
1525         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling',
1526     },
1527     reco = {
1528         '-s': 'RAW2DIGI:RawToDigi_pixelOnly,RECO:reconstruction_pixelTrackingOnly,VALIDATION:@pixelTrackingOnlyValidation,DQM:@pixelTrackingOnlyDQM',
1529         '--procModifiers': 'alpakaValidation',
1530         '--customise' : 'RecoTracker/Configuration/customizePixelTracksForTriplets.customizePixelTracksForTriplets,HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling'
1531     },
1532     harvest = {
1533         '-s': 'HARVESTING:@trackingOnlyValidation+@pixelTrackingOnlyDQM'
1534     },
1535     suffix = 'Patatrack_PixelOnlyTripletsAlpaka_Validation',
1536     offset = 0.407,
1537 )
1538 
1539 upgradeWFs['PatatrackPixelOnlyTripletsAlpakaProfiling'] = PatatrackWorkflow(
1540     digi = { 
1541         '--procModifiers': 'alpaka',
1542     },
1543     reco = {
1544         '-s': 'RAW2DIGI:RawToDigi_pixelOnly,RECO:reconstruction_pixelTrackingOnly',
1545         '--procModifiers': 'alpaka',
1546         '--customise' : 'RecoTracker/Configuration/customizePixelTracksForTriplets.customizePixelTracksForTriplets,RecoTracker/Configuration/customizePixelOnlyForProfiling.customizePixelOnlyForProfilingGPUOnly'
1547     },
1548     harvest = None,
1549     suffix = 'Patatrack_PixelOnlyTripletsAlpaka_Profiling',
1550     offset = 0.408,
1551 )
1552 
1553 # end of Patatrack workflows
1554 ###############################################################################################################
1555 
1556 class UpgradeWorkflow_ProdLike(UpgradeWorkflow):
1557     def setup_(self, step, stepName, stepDict, k, properties):
1558         thisStep = stepDict[step][k]["-s"]
1559         if 'GenSimHLBeamSpot14' in step:
1560             stepDict[stepName][k] = merge([{'--eventcontent': 'RAWSIM', '--datatier': 'GEN-SIM'},stepDict[step][k]])
1561         elif 'Digi' in step and 'Trigger' not in step:
1562             stepDict[stepName][k] = merge([{'-s': thisStep.replace("DIGI:pdigi_valid","DIGI"),'--datatier':'GEN-SIM-RAW', '--eventcontent':'RAWSIM'}, stepDict[step][k]])
1563         elif 'DigiTrigger' in step: # for Phase-2
1564             stepDict[stepName][k] = merge([{'-s': thisStep.replace("DIGI:pdigi_valid","DIGI"), '--datatier':'GEN-SIM-RAW', '--eventcontent':'RAWSIM'}, stepDict[step][k]])
1565         elif 'Reco' in step:
1566             stepDict[stepName][k] = merge([{'-s': 'RAW2DIGI,L1Reco,RECO,RECOSIM', '--datatier':'AODSIM', '--eventcontent':'AODSIM'}, stepDict[step][k]])
1567         elif 'MiniAOD' in step:
1568             # the separate miniAOD step is used here
1569             stepDict[stepName][k] = deepcopy(stepDict[step][k])
1570         elif 'ALCA' in step or 'HARVEST' in step:
1571             # remove step
1572             stepDict[stepName][k] = None
1573         elif 'Nano'==step:
1574             stepDict[stepName][k] = merge([{'--filein':'file:step4.root','-s':'NANO','--datatier':'NANOAODSIM','--eventcontent':'NANOEDMAODSIM'}, stepDict[step][k]])
1575     def setupPU_(self, step, stepName, stepDict, k, properties):
1576         # No need for PU replay for ProdLike
1577         if "Digi" not in step and stepDict[stepName][k] is not None and '--pileup' in stepDict[stepName][k]:
1578             stepDict[stepName][k].pop('--pileup', None)
1579             stepDict[stepName][k].pop('--pileup_input', None)
1580     def condition(self, fragment, stepList, key, hasHarvest):
1581         years = ['2022','2023','2024','2025','Run4']
1582         return fragment=="TTbar_14TeV" and any(y in key for y in years)
1583 upgradeWFs['ProdLike'] = UpgradeWorkflow_ProdLike(
1584     steps = [
1585         'GenSimHLBeamSpot14',
1586         'Digi',
1587         'DigiTrigger',
1588         'Reco',
1589         'RecoFakeHLT',
1590         'RecoGlobal',
1591         'RecoGlobalFakeHLT',
1592         'RecoNano',
1593         'RecoNanoFakeHLT',
1594         'HARVEST',
1595         'HARVESTFakeHLT',
1596         'HARVESTGlobal',
1597         'HARVESTGlobalFakeHLT',
1598         'HARVESTNano',
1599         'HARVESTNanoFakeHLT',
1600         'MiniAOD',
1601         'ALCA',
1602         'ALCAPhase2',
1603         'Nano',
1604     ],
1605     PU = [
1606         'GenSimHLBeamSpot14',
1607         'Digi',
1608         'DigiTrigger',
1609         'Reco',
1610         'RecoFakeHLT',
1611         'RecoGlobal',
1612         'RecoGlobalFakeHLT',
1613         'RecoNano',
1614         'RecoNanoFakeHLT',
1615         'HARVEST',
1616         'HARVESTFakeHLT',
1617         'HARVESTGlobal',
1618         'HARVESTGlobalFakeHLT',
1619         'HARVESTNano',
1620         'HARVESTNanoFakeHLT',
1621         'MiniAOD',
1622         'ALCA',
1623         'ALCAPhase2',
1624         'Nano',
1625     ],
1626     suffix = '_ProdLike',
1627     offset = 0.21,
1628 )
1629 
1630 class UpgradeWorkflow_ProdLikeRunningPU(UpgradeWorkflow_ProdLike):
1631     def __init__(self, suffix, offset, fixedPU,
1632          steps = [],
1633         PU = [
1634             'GenSimHLBeamSpot14',
1635             'Digi',
1636             'DigiTrigger',
1637             'Reco',
1638             'RecoFakeHLT',
1639             'RecoGlobal',
1640             'RecoGlobalFakeHLT',
1641             'RecoNano',
1642             'RecoNanoFakeHLT',
1643             'HARVEST',
1644             'HARVESTFakeHLT',
1645             'HARVESTGlobal',
1646             'HARVESTGlobalFakeHLT',
1647             'HARVESTNano',
1648             'HARVESTNanoFakeHLT',
1649             'MiniAOD',
1650             'ALCA',
1651             'ALCAPhase2',
1652             'Nano',
1653         ]):
1654         super(UpgradeWorkflow_ProdLikeRunningPU, self).__init__(steps, PU, suffix, offset)
1655         self.__fixedPU = fixedPU
1656     def setupPU_(self, step, stepName, stepDict, k, properties):
1657         #  change PU skipping ALCA and HARVEST
1658         if stepDict[stepName][k] is not None and '--pileup' in stepDict[stepName][k] and "Digi" in step:
1659             stepDict[stepName][k]['--pileup'] = 'AVE_' + str(self.__fixedPU) + '_BX_25ns'
1660     def condition(self, fragment, stepList, key, hasHarvest):
1661         # lower PUs for Run3
1662         return (fragment=="TTbar_14TeV") and (('Run4' in key) or ('2022' in key and self.__fixedPU<=100))
1663 
1664 # The numbering below is following the 0.21 for ProdLike wfs
1665 # 0.21N would have been a more natural choice but the
1666 # trailing zeros are ignored. Thus 0.21N1 is used
1667 
1668 upgradeWFs['ProdLikePU10'] = UpgradeWorkflow_ProdLikeRunningPU(
1669     suffix = '_ProdLikePU10',
1670     offset = 0.21101,
1671     fixedPU = 10,
1672 )
1673 
1674 upgradeWFs['ProdLikePU20'] = UpgradeWorkflow_ProdLikeRunningPU(
1675     suffix = '_ProdLikePU20',
1676     offset = 0.21201,
1677     fixedPU = 20,
1678 )
1679 
1680 upgradeWFs['ProdLikePU30'] = UpgradeWorkflow_ProdLikeRunningPU(
1681     suffix = '_ProdLikePU30',
1682     offset = 0.21301,
1683     fixedPU = 30,
1684 )
1685 
1686 upgradeWFs['ProdLikePU40'] = UpgradeWorkflow_ProdLikeRunningPU(
1687     suffix = '_ProdLikePU40',
1688     offset = 0.21401,
1689     fixedPU = 40,
1690 )
1691 
1692 upgradeWFs['ProdLikePU50'] = UpgradeWorkflow_ProdLikeRunningPU(
1693     suffix = '_ProdLikePU50',
1694     offset = 0.21501,
1695     fixedPU = 50,
1696 )
1697 
1698 upgradeWFs['ProdLikePU55'] = UpgradeWorkflow_ProdLikeRunningPU(
1699     suffix = '_ProdLikePU55',
1700     offset = 0.21551,
1701     fixedPU = 55,
1702 )
1703 
1704 upgradeWFs['ProdLikePU60'] = UpgradeWorkflow_ProdLikeRunningPU(
1705     suffix = '_ProdLikePU60',
1706     offset = 0.21601,
1707     fixedPU = 60,
1708 )
1709 
1710 upgradeWFs['ProdLikePU65'] = UpgradeWorkflow_ProdLikeRunningPU(
1711     suffix = '_ProdLikePU65',
1712     offset = 0.21651,
1713     fixedPU = 65,
1714 )
1715 
1716 upgradeWFs['ProdLikePU70'] = UpgradeWorkflow_ProdLikeRunningPU(
1717     suffix = '_ProdLikePU70',
1718     offset = 0.21701,
1719     fixedPU = 70,
1720 )
1721 
1722 upgradeWFs['ProdLikePU80'] = UpgradeWorkflow_ProdLikeRunningPU(
1723     suffix = '_ProdLikePU80',
1724     offset = 0.21801,
1725     fixedPU = 80,
1726 )
1727 
1728 upgradeWFs['ProdLikePU90'] = UpgradeWorkflow_ProdLikeRunningPU(
1729     suffix = '_ProdLikePU90',
1730     offset = 0.21901,
1731     fixedPU = 90,
1732 )
1733 
1734 upgradeWFs['ProdLikePU100'] = UpgradeWorkflow_ProdLikeRunningPU(
1735     suffix = '_ProdLikePU100',
1736     offset = 0.211001,
1737     fixedPU = 100,
1738 )
1739 
1740 upgradeWFs['ProdLikePU120'] = UpgradeWorkflow_ProdLikeRunningPU(
1741     suffix = '_ProdLikePU120',
1742     offset = 0.211201,
1743     fixedPU = 120,
1744 )
1745 
1746 upgradeWFs['ProdLikePU140'] = UpgradeWorkflow_ProdLikeRunningPU(
1747     suffix = '_ProdLikePU140',
1748     offset = 0.211401,
1749     fixedPU = 140,
1750 )
1751 
1752 upgradeWFs['ProdLikePU160'] = UpgradeWorkflow_ProdLikeRunningPU(
1753     suffix = '_ProdLikePU160',
1754     offset = 0.211601,
1755     fixedPU = 160,
1756 )
1757 
1758 upgradeWFs['ProdLikePU180'] = UpgradeWorkflow_ProdLikeRunningPU(
1759     suffix = '_ProdLikePU180',
1760     offset = 0.211801,
1761     fixedPU = 180,
1762 )
1763 
1764 class UpgradeWorkflow_HLT75e33Timing(UpgradeWorkflow):
1765     def setup_(self, step, stepName, stepDict, k, properties):
1766         # skip RECO, ALCA and HLT
1767         if ('ALCA' in step) or ('Reco' in step) or ('HLT' in step):
1768             stepDict[stepName][k] = None
1769         elif 'DigiTrigger' in step:
1770             stepDict[stepName][k] = merge([self.step2, stepDict[step][k]])
1771         elif 'HARVEST' in step:
1772             stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
1773         else:
1774             stepDict[stepName][k] = merge([stepDict[step][k]])
1775     def condition(self, fragment, stepList, key, hasHarvest):
1776         return fragment=="TTbar_14TeV" and 'Run4' in key
1777 upgradeWFs['HLTTiming75e33'] = UpgradeWorkflow_HLT75e33Timing(
1778     steps = [
1779         'Reco',
1780         'RecoGlobal',
1781         'RecoNano',
1782         'DigiTrigger',
1783         'ALCA',
1784         'ALCAPhase2',
1785         'RecoGlobalFakeHLT',
1786         'HLT75e33',
1787         'HARVESTGlobal',
1788         'HARVESTGlobalFakeHLT',
1789     ],
1790     PU = [
1791         'Reco',
1792         'RecoGlobal',
1793         'RecoNano',
1794         'DigiTrigger',
1795         'ALCA',
1796         'ALCAPhase2',
1797         'HARVESTGlobal'
1798         'RecoGlobalFakeHLT',
1799         'HLT75e33',
1800         'HARVESTGlobal',
1801         'HARVESTGlobalFakeHLT',
1802     ],
1803     suffix = '_HLT75e33Timing',
1804     offset = 0.75,
1805 )
1806 upgradeWFs['HLTTiming75e33'].step2 = {
1807     '-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,L1P2GT,DIGI2RAW,HLT:75e33_timing,VALIDATION:@hltValidation',
1808     '--datatier':'GEN-SIM-DIGI-RAW,DQMIO',
1809     '--eventcontent':'FEVTDEBUGHLT,DQMIO'
1810 }
1811 upgradeWFs['HLTTiming75e33'].step3 = {
1812     '-s':'HARVESTING:@hltValidation'
1813 }
1814 
1815 upgradeWFs['HLTTiming75e33Alpaka'] = deepcopy(upgradeWFs['HLTTiming75e33'])
1816 upgradeWFs['HLTTiming75e33Alpaka'].suffix = '_HLT75e33TimingAlpaka'
1817 upgradeWFs['HLTTiming75e33Alpaka'].offset = 0.751
1818 upgradeWFs['HLTTiming75e33Alpaka'].step2 = {
1819     '-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,L1P2GT,DIGI2RAW,HLT:75e33_timing,VALIDATION:@hltValidation',
1820     '--procModifiers': 'alpaka',
1821     '--datatier':'GEN-SIM-DIGI-RAW,DQMIO',
1822     '--eventcontent':'FEVTDEBUGHLT,DQMIO'
1823 }
1824 upgradeWFs['HLTTiming75e33Alpaka'].step3 = {
1825     '-s':'HARVESTING:@hltValidation'
1826 }
1827 
1828 upgradeWFs['HLTTiming75e33TiclV5'] = deepcopy(upgradeWFs['HLTTiming75e33'])
1829 upgradeWFs['HLTTiming75e33TiclV5'].suffix = '_HLT75e33TimingTiclV5'
1830 upgradeWFs['HLTTiming75e33TiclV5'].offset = 0.752
1831 upgradeWFs['HLTTiming75e33TiclV5'].step2 = {
1832     '-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,L1P2GT,DIGI2RAW,HLT:75e33_timing,VALIDATION:@hltValidation',
1833     '--procModifiers': 'ticl_v5',
1834     '--datatier':'GEN-SIM-DIGI-RAW,DQMIO',
1835     '--eventcontent':'FEVTDEBUGHLT,DQMIO'
1836 }
1837 upgradeWFs['HLTTiming75e33TiclV5'].step3 = {
1838     '-s':'HARVESTING:@hltValidation'
1839 }
1840 
1841 upgradeWFs['HLTTiming75e33AlpakaSingleIter'] = deepcopy(upgradeWFs['HLTTiming75e33'])
1842 upgradeWFs['HLTTiming75e33AlpakaSingleIter'].suffix = '_HLT75e33TimingAlpakaSingleIter'
1843 upgradeWFs['HLTTiming75e33AlpakaSingleIter'].offset = 0.753
1844 upgradeWFs['HLTTiming75e33AlpakaSingleIter'].step2 = {
1845     '-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,L1P2GT,DIGI2RAW,HLT:75e33_timing,VALIDATION:@hltValidation',
1846     '--procModifiers': 'alpaka,singleIterPatatrack',
1847     '--datatier':'GEN-SIM-DIGI-RAW,DQMIO',
1848     '--eventcontent':'FEVTDEBUGHLT,DQMIO'
1849 }
1850 upgradeWFs['HLTTiming75e33AlpakaSingleIter'].step3 = {
1851     '-s':'HARVESTING:@hltValidation'
1852 }
1853 
1854 upgradeWFs['HLTTiming75e33AlpakaSingleIterLST'] = deepcopy(upgradeWFs['HLTTiming75e33'])
1855 upgradeWFs['HLTTiming75e33AlpakaSingleIterLST'].suffix = '_HLT75e33TimingAlpakaSingleIterLST'
1856 upgradeWFs['HLTTiming75e33AlpakaSingleIterLST'].offset = 0.754
1857 upgradeWFs['HLTTiming75e33AlpakaSingleIterLST'].step2 = {
1858     '-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,L1P2GT,DIGI2RAW,HLT:75e33_timing,VALIDATION:@hltValidation',
1859     '--procModifiers': 'alpaka,singleIterPatatrack,trackingLST',
1860     '--datatier':'GEN-SIM-DIGI-RAW,DQMIO',
1861     '--eventcontent':'FEVTDEBUGHLT,DQMIO'
1862 }
1863 upgradeWFs['HLTTiming75e33AlpakaSingleIterLST'].step3 = {
1864     '-s':'HARVESTING:@hltValidation'
1865 }
1866 
1867 upgradeWFs['HLTTiming75e33AlpakaLST'] = deepcopy(upgradeWFs['HLTTiming75e33'])
1868 upgradeWFs['HLTTiming75e33AlpakaLST'].suffix = '_HLT75e33TimingAlpakaLST'
1869 upgradeWFs['HLTTiming75e33AlpakaLST'].offset = 0.755
1870 upgradeWFs['HLTTiming75e33AlpakaLST'].step2 = {
1871     '-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,L1P2GT,DIGI2RAW,HLT:75e33_timing,VALIDATION:@hltValidation',
1872     '--procModifiers': 'alpaka,trackingLST',
1873     '--datatier':'GEN-SIM-DIGI-RAW,DQMIO',
1874     '--eventcontent':'FEVTDEBUGHLT,DQMIO'
1875 }
1876 upgradeWFs['HLTTiming75e33AlpakaLST'].step3 = {
1877     '-s':'HARVESTING:@hltValidation'
1878 }
1879 
1880 upgradeWFs['HLTTiming75e33TrimmedTracking'] = deepcopy(upgradeWFs['HLTTiming75e33'])
1881 upgradeWFs['HLTTiming75e33TrimmedTracking'].suffix = '_HLT75e33TimingTrimmedTracking'
1882 upgradeWFs['HLTTiming75e33TrimmedTracking'].offset = 0.756
1883 upgradeWFs['HLTTiming75e33TrimmedTracking'].step2 = {
1884     '-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,L1P2GT,DIGI2RAW,HLT:75e33_timing,VALIDATION:@hltValidation',
1885     '--procModifiers': 'phase2_hlt_vertexTrimming',
1886     '--datatier':'GEN-SIM-DIGI-RAW,DQMIO',
1887     '--eventcontent':'FEVTDEBUGHLT,DQMIO'
1888 }
1889 
1890 upgradeWFs['HLTTiming75e33AlpakaTrimmedTracking'] = deepcopy(upgradeWFs['HLTTiming75e33'])
1891 upgradeWFs['HLTTiming75e33AlpakaTrimmedTracking'].suffix = '_HLT75e33TimingAlpakaTrimmedTracking'
1892 upgradeWFs['HLTTiming75e33AlpakaTrimmedTracking'].offset = 0.7561
1893 upgradeWFs['HLTTiming75e33AlpakaTrimmedTracking'].step2 = {
1894     '-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,L1P2GT,DIGI2RAW,HLT:75e33_timing,VALIDATION:@hltValidation',
1895     '--procModifiers': 'alpaka,phase2_hlt_vertexTrimming',
1896     '--datatier':'GEN-SIM-DIGI-RAW,DQMIO',
1897     '--eventcontent':'FEVTDEBUGHLT,DQMIO'
1898 }
1899 
1900 upgradeWFs['HLTTiming75e33AlpakaTrimmedTrackingSingleIter'] = deepcopy(upgradeWFs['HLTTiming75e33'])
1901 upgradeWFs['HLTTiming75e33AlpakaTrimmedTrackingSingleIter'].suffix = '_HLT75e33TimingAlpakaTrimmedTrackingSingleIter'
1902 upgradeWFs['HLTTiming75e33AlpakaTrimmedTrackingSingleIter'].offset = 0.7562
1903 upgradeWFs['HLTTiming75e33AlpakaTrimmedTrackingSingleIter'].step2 = {
1904     '-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,L1P2GT,DIGI2RAW,HLT:75e33_timing,VALIDATION:@hltValidation',
1905     '--procModifiers': 'alpaka,phase2_hlt_vertexTrimming,singleIterPatatrack',
1906     '--datatier':'GEN-SIM-DIGI-RAW,DQMIO',
1907     '--eventcontent':'FEVTDEBUGHLT,DQMIO'
1908 }
1909 
1910 upgradeWFs['HLTTiming75e33AlpakaSingleIterLSTSeeding'] = deepcopy(upgradeWFs['HLTTiming75e33'])
1911 upgradeWFs['HLTTiming75e33AlpakaSingleIterLSTSeeding'].suffix = '_HLT75e33TimingAlpakaSingleIterLSTSeeding'
1912 upgradeWFs['HLTTiming75e33AlpakaSingleIterLSTSeeding'].offset = 0.757
1913 upgradeWFs['HLTTiming75e33AlpakaSingleIterLSTSeeding'].step2 = {
1914     '-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,L1P2GT,DIGI2RAW,HLT:75e33_timing,VALIDATION:@hltValidation',
1915     '--procModifiers': 'alpaka,singleIterPatatrack,trackingLST,seedingLST',
1916     '--datatier':'GEN-SIM-DIGI-RAW,DQMIO',
1917     '--eventcontent':'FEVTDEBUGHLT,DQMIO'
1918 }
1919 upgradeWFs['HLTTiming75e33AlpakaSingleIterLSTSeeding'].step3 = {
1920     '-s':'HARVESTING:@hltValidation'
1921 }
1922 
1923 class UpgradeWorkflow_HLTwDIGI75e33(UpgradeWorkflow):
1924     def setup_(self, step, stepName, stepDict, k, properties):
1925         if 'DigiTrigger' in step:
1926             stepDict[stepName][k] = merge([{'-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,DIGI2RAW,HLT:@relvalRun4'}, stepDict[step][k]])
1927     def condition(self, fragment, stepList, key, hasHarvest):
1928         return fragment=="TTbar_14TeV" and 'Run4' in key
1929 upgradeWFs['HLTwDIGI75e33'] = UpgradeWorkflow_HLTwDIGI75e33(
1930     steps = [
1931         'DigiTrigger',
1932     ],
1933     PU = [
1934         'DigiTrigger',
1935     ],
1936     suffix = '_HLTwDIGI75e33',
1937     offset = 0.76,
1938 )
1939 
1940 class UpgradeWorkflow_NGTScouting(UpgradeWorkflow):
1941     def setup_(self, step, stepName, stepDict, k, properties):
1942         # skip RECO, ALCA and HARVEST
1943         if ('ALCA' in step) or ('Reco' in step) or ('HLT' in step):
1944             stepDict[stepName][k] = None
1945         elif 'DigiTrigger' in step:
1946             stepDict[stepName][k] = merge([self.step2, stepDict[step][k]])
1947         elif 'HARVEST' in step:
1948             stepDict[stepName][k] = merge([self.step3, stepDict[step][k]])
1949         else:
1950             stepDict[stepName][k] = merge([stepDict[step][k]])
1951     def condition(self, fragment, stepList, key, hasHarvest):
1952         return fragment=="TTbar_14TeV" and 'Run4' in key
1953 upgradeWFs['NGTScouting'] = UpgradeWorkflow_NGTScouting(
1954     steps = [
1955         'Reco',
1956         'RecoGlobal',
1957         'RecoNano',
1958         'DigiTrigger',
1959         'ALCA',
1960         'ALCAPhase2',
1961         'HARVESTGlobal',
1962     ],
1963     PU = [
1964         'Reco',
1965         'RecoGlobal',
1966         'RecoNano',
1967         'DigiTrigger',
1968         'ALCA',
1969         'ALCAPhase2',
1970         'HARVESTGlobal'
1971     ],
1972     suffix = '_NGTScouting',
1973     offset = 0.77,
1974 )
1975 upgradeWFs['NGTScouting'].step2 = {
1976     '-s':'DIGI:pdigi_valid,L1TrackTrigger,L1,L1P2GT,DIGI2RAW,HLT:NGTScouting,VALIDATION:@hltValidation',
1977     '--datatier':'GEN-SIM-DIGI-RAW,DQMIO',
1978     '--eventcontent':'FEVTDEBUGHLT,DQMIO'
1979 }
1980 upgradeWFs['NGTScouting'].step3 = {
1981     '-s':'HARVESTING:@hltValidation'
1982 }
1983 
1984 class UpgradeWorkflow_L1Complete(UpgradeWorkflow):
1985     def setup_(self, step, stepName, stepDict, k, properties):
1986         if 'Digi' in step and 'NoHLT' not in step:
1987             stepDict[stepName][k] = merge([{'-s': 'DIGI:pdigi_valid,L1,L1TrackTrigger,L1P2GT,DIGI2RAW,HLT:@relvalRun4'}, stepDict[step][k]])
1988     def condition(self, fragment, stepList, key, hasHarvest):
1989         return 'Run4' in key
1990 
1991 upgradeWFs['L1Complete'] = UpgradeWorkflow_L1Complete(
1992     steps = [
1993         'DigiTrigger',
1994     ],
1995     PU = [
1996         'DigiTrigger',
1997     ],
1998     suffix = '_L1Complete',
1999     offset = 0.78
2000 )
2001 
2002 # use HLTTiming75e33 template as it skips the steps after DIGI
2003 upgradeWFs['L1CompleteWithNano'] = deepcopy(upgradeWFs['HLTTiming75e33'])
2004 upgradeWFs['L1CompleteWithNano'].suffix = '_L1CompleteWithNano'
2005 upgradeWFs['L1CompleteWithNano'].offset = 0.781
2006 upgradeWFs['L1CompleteWithNano'].step2 = {
2007     '-s': 'DIGI:pdigi_valid,L1,L1TrackTrigger,L1P2GT,DIGI2RAW,HLT:@relvalRun4,NANO:@Phase2L1DPG',
2008     '--datatier':'GEN-SIM-DIGI-RAW,NANOAODSIM',
2009     '--eventcontent':'FEVTDEBUGHLT,NANOAODSIM'
2010 }
2011 
2012 upgradeWFs['L1CompleteOnlyNano'] = deepcopy(upgradeWFs['L1CompleteWithNano'])
2013 upgradeWFs['L1CompleteOnlyNano'].suffix = '_L1CompleteOnlyNano'
2014 upgradeWFs['L1CompleteOnlyNano'].offset = 0.782
2015 upgradeWFs['L1CompleteOnlyNano'].step2 = {
2016     # '-s': 'NANO:@Phase2L1DPG',
2017     '-s': 'DIGI:pdigi_valid,L1,L1TrackTrigger,L1P2GT,DIGI2RAW,HLT:@relvalRun4,NANO:@Phase2L1DPG',
2018     '--datatier':'NANOAODSIM',
2019     '--eventcontent':'NANOAODSIM'
2020 }
2021 
2022 class UpgradeWorkflow_Neutron(UpgradeWorkflow):
2023     def setup_(self, step, stepName, stepDict, k, properties):
2024         if 'GenSim' in step:
2025             custNew = "SimG4Core/Application/NeutronBGforMuonsXS_cff.customise"
2026         else:
2027             custNew = "SLHCUpgradeSimulations/Configuration/customise_mixing.customise_Mix_LongLived_Neutrons"
2028         stepDict[stepName][k] = deepcopy(stepDict[step][k])
2029         if '--customise' in stepDict[stepName][k].keys():
2030             stepDict[stepName][k]['--customise'] += ","+custNew
2031         else:
2032             stepDict[stepName][k]['--customise'] = custNew
2033     def condition(self, fragment, stepList, key, hasHarvest):
2034         return any(fragment==nfrag for nfrag in self.neutronFrags) and any(nkey in key for nkey in self.neutronKeys)
2035 upgradeWFs['Neutron'] = UpgradeWorkflow_Neutron(
2036     steps = [
2037         'GenSim',
2038         'GenSimHLBeamSpot',
2039         'GenSimHLBeamSpot14',
2040         'Digi',
2041         'DigiTrigger',
2042     ],
2043     PU = [
2044         'Digi',
2045         'DigiTrigger',
2046     ],
2047     suffix = '_Neutron',
2048     offset = 0.12,
2049 )
2050 # add some extra info
2051 upgradeWFs['Neutron'].neutronKeys = [x for x in upgradeKeys['Run4'] if 'PU' not in x]
2052 upgradeWFs['Neutron'].neutronFrags = ['ZMM_14','MinBias_14TeV']
2053 
2054 class UpgradeWorkflow_heCollapse(UpgradeWorkflow):
2055     def setup_(self, step, stepName, stepDict, k, properties):
2056         stepDict[stepName][k] = merge([{'--procModifiers': 'run2_HECollapse_2018'}, stepDict[step][k]])
2057     def condition(self, fragment, stepList, key, hasHarvest):
2058         return fragment=="TTbar_13" and '2018' in key
2059 upgradeWFs['heCollapse'] = UpgradeWorkflow_heCollapse(
2060     steps = [
2061         'GenSim',
2062         'Digi',
2063         'Reco',
2064 #        'RecoFakeHLT',
2065         'HARVEST',
2066         'HARVESTFakeHLT',
2067         'ALCA',
2068     ],
2069     PU = [
2070         'Digi',
2071         'Reco',
2072 #        'RecoFakeHLT',
2073         'HARVEST',
2074         'HARVESTFakeHLT',
2075     ],
2076     suffix = '_heCollapse',
2077     offset = 0.6,
2078 )
2079 
2080 # ECAL Phase 2 development WF
2081 class UpgradeWorkflow_ecalDevel(UpgradeWorkflow):
2082     def __init__(self, digi = {}, reco = {}, harvest = {}, **kwargs):
2083         # adapt the parameters for the UpgradeWorkflow init method
2084         super(UpgradeWorkflow_ecalDevel, self).__init__(
2085             steps = [
2086                 'DigiTrigger',
2087                 'RecoGlobal',
2088                 'RecoGlobalFakeHLT',
2089                 'HARVESTGlobal',
2090                 'HARVESTGlobalFakeHLT',
2091                 'ALCAPhase2',
2092             ],
2093             PU = [
2094                 'DigiTrigger',
2095                 'RecoGlobal',
2096                 'RecoGlobalFakeHLT',
2097                 'HARVESTGlobal',
2098                 'HARVESTGlobalFakeHLT',
2099                 'ALCAPhase2',
2100             ],
2101             **kwargs)
2102         self.__digi = digi
2103         self.__reco = reco
2104         self.__harvest = harvest
2105 
2106     def setup_(self, step, stepName, stepDict, k, properties):
2107         # temporarily remove trigger & downstream steps
2108         mods = {'--era': stepDict[step][k]['--era']+',phase2_ecal_devel'}
2109         if 'Digi' in step:
2110             mods['-s'] = 'DIGI:pdigi_valid,DIGI2RAW'
2111             mods |= self.__digi
2112         elif 'Reco' in step:
2113             mods['-s'] = 'RAW2DIGI,RECO:reconstruction_ecalOnly,VALIDATION:@ecalOnlyValidation,DQM:@ecalOnly'
2114             mods['--datatier'] = 'GEN-SIM-RECO,DQMIO'
2115             mods['--eventcontent'] = 'FEVTDEBUGHLT,DQM'
2116             mods |= self.__reco
2117         elif 'HARVEST' in step:
2118             mods['-s'] = 'HARVESTING:@ecalOnlyValidation+@ecal'
2119             mods |= self.__harvest
2120         stepDict[stepName][k] = merge([mods, stepDict[step][k]])
2121         # skip ALCA step
2122         if 'ALCA' in step:
2123             stepDict[stepName][k] = None
2124 
2125     def condition(self, fragment, stepList, key, hasHarvest):
2126         return fragment=="TTbar_14TeV" and 'Run4' in key
2127 
2128 # ECAL Phase 2 workflow running on CPU
2129 upgradeWFs['ecalDevel'] = UpgradeWorkflow_ecalDevel(
2130     suffix = '_ecalDevel',
2131     offset = 0.61,
2132 )
2133 
2134 # ECAL Phase 2 workflow running on CPU or GPU with Alpaka code
2135 upgradeWFs['ecalDevelAlpaka'] = UpgradeWorkflow_ecalDevel(
2136     reco = {
2137         '--procModifiers': 'alpaka',
2138         '--customise' : 'HeterogeneousCore/AlpakaServices/customiseAlpakaServiceMemoryFilling.customiseAlpakaServiceMemoryFilling'
2139     },
2140     suffix = '_ecalDevelAlpaka',
2141     offset = 0.612,
2142 )
2143 
2144 # ECAL component
2145 class UpgradeWorkflow_ECalComponent(UpgradeWorkflow):
2146     def __init__(self, suffix, offset, ecalTPPh2, ecalMod,
2147                  steps = [
2148                      'GenSim',
2149                      'GenSimHLBeamSpot',
2150                      'GenSimHLBeamSpot14',
2151                      'GenSimHLBeamSpotHGCALCloseBy',
2152                      'Digi',
2153                      'DigiTrigger',
2154                      'RecoGlobal',
2155                      'HARVESTGlobal',
2156                      'ALCAPhase2',
2157                  ],
2158                  PU = [
2159                      'GenSim',
2160                      'GenSimHLBeamSpot',
2161                      'GenSimHLBeamSpot14',
2162                      'GenSimHLBeamSpotHGCALCloseBy',
2163                      'Digi',
2164                      'DigiTrigger',
2165                      'RecoGlobal',
2166                      'HARVESTGlobal',
2167                      'ALCAPhase2',
2168                  ]):
2169         super(UpgradeWorkflow_ECalComponent, self).__init__(steps, PU, suffix, offset)
2170         self.__ecalTPPh2 = ecalTPPh2
2171         self.__ecalMod = ecalMod
2172 
2173     def setup_(self, step, stepName, stepDict, k, properties):
2174         stepDict[stepName][k] = deepcopy(stepDict[step][k])
2175         if 'Sim' in step:
2176             if self.__ecalMod is not None:
2177                 stepDict[stepName][k] = merge([{'--procModifiers':self.__ecalMod},stepDict[step][k]])
2178         if 'Digi' in step and 'NoHLT' not in step:
2179             if self.__ecalMod is not None:
2180                 stepDict[stepName][k] = merge([{'--procModifiers':self.__ecalMod},stepDict[step][k]])
2181             if self.__ecalTPPh2 is not None:
2182                 mods = {'--era': stepDict[step][k]['--era']+',phase2_ecal_devel,phase2_ecalTP_devel'}
2183                 mods['-s'] = 'DIGI:pdigi_valid,DIGI2RAW,HLT:@fake2'
2184                 stepDict[stepName][k] = merge([mods, stepDict[step][k]])
2185         if 'RecoGlobal' in step:
2186             stepDict[stepName][k] = merge([{'-s': 'RAW2DIGI,RECO,RECOSIM,PAT',
2187                                             '--datatier':'GEN-SIM-RECO',
2188                                             '--eventcontent':'FEVTDEBUGHLT',
2189                                         }, stepDict[step][k]])
2190         if 'HARVESTGlobal' in step:
2191             stepDict[stepName][k] = None
2192         if 'ALCAPhase2' in step:
2193             stepDict[stepName][k] = None
2194 
2195     def condition(self, fragment, stepList, key, hasHarvest):
2196         return fragment=="TTbar_14TeV" and ('2022' in key or '2023' in key or 'Run4' in key)
2197 
2198 upgradeWFs['ECALComponent'] = UpgradeWorkflow_ECalComponent(
2199     suffix = '_ecalComponent',
2200     offset = 0.631,
2201     ecalTPPh2 = None,
2202     ecalMod = 'ecal_component',
2203 )
2204 
2205 upgradeWFs['ECALComponentFSW'] = UpgradeWorkflow_ECalComponent(
2206     suffix = '_ecalComponentFSW',
2207     offset = 0.632,
2208     ecalTPPh2 = None,
2209     ecalMod = 'ecal_component_finely_sampled_waveforms',
2210 )
2211 
2212 upgradeWFs['ECALTPPh2'] = UpgradeWorkflow_ECalComponent(
2213     suffix = '_ecalTPPh2',
2214     offset = 0.633,
2215     ecalTPPh2 = 'phase2_ecal_devel,phase2_ecalTP_devel',
2216     ecalMod = None,
2217 )
2218 
2219 upgradeWFs['ECALTPPh2Component'] = UpgradeWorkflow_ECalComponent(
2220     suffix = '_ecalTPPh2Component',
2221     offset = 0.634,
2222     ecalTPPh2 = 'phase2_ecal_devel,phase2_ecalTP_devel',
2223     ecalMod = 'ecal_component',
2224 )
2225 
2226 upgradeWFs['ECALTPPh2ComponentFSW'] = UpgradeWorkflow_ECalComponent(
2227     suffix = '_ecalTPPh2ComponentFSW',
2228     offset = 0.635,
2229     ecalTPPh2 = 'phase2_ecal_devel,phase2_ecalTP_devel',
2230     ecalMod = 'ecal_component_finely_sampled_waveforms',
2231 )
2232 
2233 class UpgradeWorkflow_0T(UpgradeWorkflow):
2234     def setup_(self, step, stepName, stepDict, k, properties):
2235         myGT=stepDict[step][k]['--conditions']
2236         myGT+="_0T"
2237         stepDict[stepName][k] = merge([{'-n':'1','--magField':'0T','--conditions':myGT}, stepDict[step][k]])
2238     def setupPU_(self, step, stepName, stepDict, k, properties):
2239         # override '-n' setting from PUDataSets in relval_steps.py
2240         stepDict[stepName][k] = merge([{'-n':'1'}, stepDict[step][k]])
2241     def condition(self, fragment, stepList, key, hasHarvest):
2242         return (fragment=="TTbar_13" or fragment=="TTbar_14TeV") and ('2017' in key or '2018' in key or '2022' in key or '2024' in key) and ('FS' not in key)
2243 upgradeWFs['0T'] = UpgradeWorkflow_0T(
2244     steps = [
2245         'GenSim',
2246         'Digi',
2247         'Reco',
2248         'RecoFakeHLT',
2249         'HARVEST',
2250         'HARVESTFakeHLT',
2251         'RecoNano',
2252         'RecoNanoFakeHLT',
2253         'HARVESTNano',
2254         'HARVESTNanoFakeHLT',
2255         'ALCA',
2256     ],
2257     PU = [
2258         'Digi',
2259         'Reco',
2260         'RecoFakeHLT',
2261         'HARVEST',
2262         'HARVESTFakeHLT',
2263         'RecoNano',
2264         'RecoNanoFakeHLT',
2265         'HARVESTNano',
2266         'HARVESTNanoFakeHLT',
2267     ],
2268     suffix = '_0T',
2269     offset = 0.24,
2270 )
2271 
2272 class UpgradeWorkflow_ParkingBPH(UpgradeWorkflow):
2273     def setup_(self, step, stepName, stepDict, k, properties):
2274         if 'Reco' in step and 'Run2_2018' in stepDict[step][k]['--era']:
2275             stepDict[stepName][k] = merge([{'--era': 'Run2_2018,bParking'}, stepDict[step][k]])
2276     def condition(self, fragment, stepList, key, hasHarvest):
2277         return fragment=="TTbar_13" and '2018' in key
2278 upgradeWFs['ParkingBPH'] = UpgradeWorkflow_ParkingBPH(
2279     steps = [
2280         'Reco',
2281         'RecoFakeHLT',
2282     ],
2283     PU = [],
2284     suffix = '_ParkingBPH',
2285     offset = 0.8,
2286 )
2287 
2288 ## Wf to add Heavy Flavor DQM to whichever DQM is already there
2289 class UpgradeWorkflow_HeavyFlavor(UpgradeWorkflow):
2290     def setup_(self, step, stepName, stepDict, k, properties):
2291         self.__frags = ["B0","Psi2S","Bu","Bd","Xi","Bs"]
2292         thisStep = stepDict[step][k]["-s"]
2293         if "Reco" in step:
2294             if "DQM:" in thisStep:
2295                 stepDict[stepName][k] = merge([{'-s': thisStep.replace("DQM:","DQM:@heavyFlavor+")}, stepDict[step][k]])
2296             elif "DQM" in thisStep:
2297                 stepDict[stepName][k] = merge([{'-s': thisStep.replace("DQM","DQM:@heavyFlavor")}, stepDict[step][k]])
2298             else:
2299                 stepDict[stepName][k] = merge([{'-s': thisStep + ",DQM:@heavyFlavor"}, stepDict[step][k]])
2300 
2301     def condition(self, fragment, stepList, key, hasHarvest):
2302         return any(frag in fragment for frag in self.__frags)
2303 
2304 upgradeWFs['HeavyFlavor'] = UpgradeWorkflow_HeavyFlavor(
2305     steps = [
2306         'Reco',
2307         'RecoFakeHLT',
2308         'RecoNano',
2309         'RecoNanoFakeHLT',
2310     ],
2311     PU = [],
2312     suffix = '_HeavyFlavor',
2313     offset = 0.81,
2314 )
2315 
2316 
2317 class UpgradeWorkflow_JMENano(UpgradeWorkflow):
2318     def setup_(self, step, stepName, stepDict, k, properties):
2319         if 'Nano' in step:
2320             stepDict[stepName][k] = merge([{'--customise': 'PhysicsTools/NanoAOD/custom_jme_cff.PrepJMECustomNanoAOD'}, stepDict[step][k]])
2321     def condition(self, fragment, stepList, key, hasHarvest):
2322         return (fragment=="TTbar_13" or fragment=="TTbar_14TeV") and ('2017' in key or '2018' in key or '2022' in key) and ('FS' not in key)
2323 upgradeWFs['JMENano'] = UpgradeWorkflow_JMENano(
2324     steps = [
2325         'Nano',
2326         'RecoNano',
2327         'RecoNanoFakeHLT',
2328     ],
2329     PU = [],
2330     suffix = '_JMENano',
2331     offset = 0.15,
2332 )
2333 
2334 
2335 # common operations for aging workflows
2336 class UpgradeWorkflowAging(UpgradeWorkflow):
2337     def setup_(self, step, stepName, stepDict, k, properties):
2338         if 'Digi' in step or 'Reco' in step:
2339             stepDict[stepName][k] = merge([{'--customise': 'SLHCUpgradeSimulations/Configuration/aging.customise_aging_'+self.lumi}, stepDict[step][k]])
2340     def condition(self, fragment, stepList, key, hasHarvest):
2341         return 'Run4' in key
2342 # define several of them
2343 upgradeWFs['Aging1000'] = UpgradeWorkflowAging(
2344     steps =  [
2345         'Digi',
2346         'DigiTrigger',
2347         'RecoLocal',
2348         'Reco',
2349         'RecoFakeHLT',
2350         'RecoGlobal',
2351         'RecoGlobalFakeHLT',
2352     ],
2353     PU =  [
2354         'Digi',
2355         'DigiTrigger',
2356         'RecoLocal',
2357         'Reco',
2358         'RecoFakeHLT',
2359         'RecoGlobal',
2360         'RecoGlobalFakeHLT',
2361     ],
2362     suffix = 'Aging1000',
2363     offset = 0.101,
2364 )
2365 upgradeWFs['Aging1000'].lumi = '1000'
2366 upgradeWFs['Aging3000'] = deepcopy(upgradeWFs['Aging1000'])
2367 upgradeWFs['Aging3000'].suffix = 'Aging3000'
2368 upgradeWFs['Aging3000'].offset = 0.103
2369 upgradeWFs['Aging3000'].lumi = '3000'
2370 
2371 class UpgradeWorkflow_PixelClusterSplitting(UpgradeWorkflow):
2372     def setup_(self, step, stepName, stepDict, k, properties):
2373         stepDict[stepName][k] = merge([{'--procModifiers': 'splitClustersInPhase2Pixel'}, stepDict[step][k]])
2374     def condition(self, fragment, stepList, key, hasHarvest):
2375         return 'Run4' in key
2376 
2377 upgradeWFs['PixelClusterSplitting'] = UpgradeWorkflow_PixelClusterSplitting(
2378     steps = [
2379         'RecoLocal',
2380         'Reco',
2381         'RecoFakeHLT',
2382         'RecoGlobal',
2383     ],
2384     PU = [
2385         'RecoLocal',
2386         'Reco',
2387         'RecoFakeHLT',
2388         'RecoGlobal',
2389     ],
2390     suffix = '_ClusterSplittingInPixel',
2391     offset = 0.19001,
2392 )
2393 
2394 class UpgradeWorkflow_JetCore(UpgradeWorkflow):
2395     def setup_(self, step, stepName, stepDict, k, properties):
2396         stepDict[stepName][k] = merge([{'--procModifiers': 'splitClustersInPhase2Pixel,jetCoreInPhase2'}, stepDict[step][k]])
2397     def condition(self, fragment, stepList, key, hasHarvest):
2398         return 'Run4' in key
2399 
2400 upgradeWFs['JetCore'] = UpgradeWorkflow_JetCore(
2401     steps = [
2402         'RecoLocal',
2403         'Reco',
2404         'RecoFakeHLT',
2405         'RecoGlobal',
2406     ],
2407     PU = [
2408         'RecoLocal',
2409         'Reco',
2410         'RecoFakeHLT',
2411         'RecoGlobal',
2412     ],
2413     suffix = '_JetCore',
2414     offset = 0.19002,
2415 )
2416 
2417 class UpgradeWorkflow_SplittingFromHLT(UpgradeWorkflow):
2418     def setup_(self, step, stepName, stepDict, k, properties):
2419         stepDict[stepName][k] = merge([{'--procModifiers': 'hltClusterSplitting'}, stepDict[step][k]])
2420     def condition(self, fragment, stepList, key, hasHarvest):
2421         return '2025' in key and fragment=="TTbar_14TeV"
2422 
2423 upgradeWFs['SplittingFromHLT'] = UpgradeWorkflow_SplittingFromHLT(
2424     steps = [
2425         'DigiTrigger',
2426         'Digi',
2427         'HLTOnly',
2428         'RecoLocal',
2429         'Reco',
2430         'RecoFakeHLT',
2431         'RecoGlobal',
2432     ],
2433     PU = [
2434         'DigiTrigger',
2435         'Digi',
2436         'HLTOnly',
2437         'RecoLocal',
2438         'Reco',
2439         'RecoFakeHLT',
2440         'RecoGlobal',
2441     ],
2442     suffix = '_SplittingFromHLT',
2443     offset = 0.19003,
2444 )
2445 
2446 class UpgradeWorkflow_SplittingProdLike(UpgradeWorkflow_ProdLike):
2447     def __init__(self, suffix, offset,steps, PU):
2448         super(UpgradeWorkflow_SplittingProdLike, self).__init__(steps, PU, suffix, offset)
2449 
2450     def setup_(self, step, stepName, stepDict, k, properties):
2451         # copy steps, then apply specializations
2452         stepDict[stepName][k] = merge([{'--procModifiers': 'hltClusterSplitting'}, stepDict[step][k]])
2453 
2454     def condition(self, fragment, stepList, key, hasHarvest):
2455         return '2025' in key and fragment=="TTbar_14TeV"
2456 
2457 upgradeWFs['SplittingFromHLTProdLike'] = UpgradeWorkflow_SplittingProdLike(
2458     steps = [
2459     ],
2460     PU = [
2461         'GenSimHLBeamSpot14',
2462         'Digi',
2463         'DigiTrigger',
2464         'HLTOnly',
2465         'Reco',
2466         'RecoFakeHLT',
2467         'RecoGlobal',
2468         'RecoNano',
2469         'RecoNanoFakeHLT',
2470         'HARVEST',
2471         'HARVESTFakeHLT',
2472         'HARVESTGlobal',
2473         'HARVESTNano',
2474         'HARVESTNanoFakeHLT',
2475         'MiniAOD',
2476         'ALCA',
2477         'Nano',
2478     ],
2479     suffix = '_SplittingFromHLTProdLike',
2480     offset = 0.1900321,
2481 )
2482 
2483 #
2484 # Simulates Bias Rail in Phase-2 OT PS modules and X% random bad Strips
2485 # in PS-s and SS sensors
2486 #
2487 class UpgradeWorkflow_OTInefficiency(UpgradeWorkflow):
2488     def setup_(self, step, stepName, stepDict, k, properties):
2489         if 'Digi' in step:
2490             stepDict[stepName][k] = merge([{'--customise': 'SimTracker/SiPhase2Digitizer/customizeForOTInefficiency.customizeSiPhase2OTInefficiency'+self.percent+'Percent'}, stepDict[step][k]])
2491     def condition(self, fragment, stepList, key, hasHarvest):
2492         return fragment=="TTbar_14TeV" and 'Run4' in key
2493 # define several of them
2494 upgradeWFs['OTInefficiency'] = UpgradeWorkflow_OTInefficiency(
2495     steps =  [
2496         'Digi',
2497         'DigiTrigger',
2498     ],
2499     PU =  [
2500         'Digi',
2501         'DigiTrigger',
2502     ],
2503     suffix = '_OTInefficiency',
2504     offset = 0.111,
2505 )
2506 upgradeWFs['OTInefficiency'].percent = 'Zero'
2507 
2508 # 1% bad strips
2509 upgradeWFs['OTInefficiency1PC'] = deepcopy(upgradeWFs['OTInefficiency'])
2510 upgradeWFs['OTInefficiency1PC'].suffix = '_OTInefficiency1PC'
2511 upgradeWFs['OTInefficiency1PC'].offset = 0.112
2512 upgradeWFs['OTInefficiency1PC'].percent = 'One'
2513 
2514 # 5% bad strips
2515 upgradeWFs['OTInefficiency5PC'] = deepcopy(upgradeWFs['OTInefficiency'])
2516 upgradeWFs['OTInefficiency5PC'].suffix = '_OTInefficiency5PC'
2517 upgradeWFs['OTInefficiency5PC'].offset = 0.113
2518 upgradeWFs['OTInefficiency5PC'].percent = 'Five'
2519 
2520 # 10% bad strips
2521 upgradeWFs['OTInefficiency10PC'] = deepcopy(upgradeWFs['OTInefficiency'])
2522 upgradeWFs['OTInefficiency10PC'].suffix = '_OTInefficiency10PC'
2523 upgradeWFs['OTInefficiency10PC'].offset = 0.114
2524 upgradeWFs['OTInefficiency10PC'].percent = 'Ten'
2525 
2526 #
2527 # Simulates CROC signal shape in IT modules
2528 #
2529 class UpgradeWorkflow_ITSignalShape(UpgradeWorkflow):
2530     def setup_(self, step, stepName, stepDict, k, properties):
2531         if 'Digi' in step:
2532             stepDict[stepName][k] = merge([{'--customise': 'SimTracker/SiPhase2Digitizer/customizeForPhase2TrackerSignalShape.customizeSiPhase2ITSignalShape'}, stepDict[step][k]])
2533     def condition(self, fragment, stepList, key, hasHarvest):
2534         return 'Run4' in key
2535 # define several of them
2536 upgradeWFs['ITSignalShape'] = UpgradeWorkflow_ITSignalShape(
2537     steps =  [
2538         'Digi',
2539         'DigiTrigger',
2540     ],
2541     PU =  [
2542         'Digi',
2543         'DigiTrigger',
2544     ],
2545     suffix = '_ITSignalShape',
2546     offset = 0.141
2547 )
2548 
2549 # Specifying explicitly the --filein is not nice but that was the
2550 # easiest way to "skip" the output of step2 (=premixing stage1) for
2551 # filein (as it goes to pileup_input). It works (a bit accidentally
2552 # though) also for "-i all" because in that case the --filein for DAS
2553 # input is after this one in the list of command line arguments to
2554 # cmsDriver, and gets then used in practice.
2555 digiPremixLocalPileup = {
2556     "--filein": "file:step1.root",
2557     "--pileup_input": "file:step2.root"
2558 }
2559 
2560 # for premix
2561 class UpgradeWorkflowPremix(UpgradeWorkflow):
2562     def setup_(self, step, stepName, stepDict, k, properties):
2563         # just copy steps
2564         stepDict[stepName][k] = merge([stepDict[step][k]])
2565     def setupPU_(self, step, stepName, stepDict, k, properties):
2566         # fastsim version
2567         if 'FS' in k:
2568             # setup for stage 1 fastsim
2569             if "Gen" in stepName:
2570                 stepNamePmx = stepName.replace('Gen','Premix')
2571                 if not stepNamePmx in stepDict: stepDict[stepNamePmx] = {}
2572                 stepDict[stepNamePmx][k] = merge([
2573                     {
2574                         '-s': 'GEN,SIM,RECOBEFMIX,DIGI:pdigi_valid',
2575                         '--fast':'',
2576                         '--datatier': 'PREMIX',
2577                         '--eventcontent': 'PREMIX',
2578                         '--procModifiers': 'premix_stage1'
2579                     },
2580                     stepDict[stepName][k]
2581                 ])
2582                 if "ProdLike" in self.suffix:
2583                     # todo
2584                     pass
2585             # setup for stage 2 fastsim
2586             elif "FastSimRun3" in step:
2587                 # go back to non-PU step version
2588                 d = merge([stepDict[self.getStepName(step)][k]])
2589                 if d is None: return
2590                 tmpsteps = []
2591                 for s in d["-s"].split(","):
2592                     if s == "DIGI" or "DIGI:" in s:
2593                         tmpsteps.extend([s, "DATAMIX"])
2594                     else:
2595                         tmpsteps.append(s)
2596                 d = merge([{"-s"             : ",".join(tmpsteps),
2597                             "--datamix"      : "PreMix"},
2598                            d])
2599                 if "--procModifiers" in d:
2600                     d["--procModifiers"] += ",premix_stage2"
2601                 else:
2602                     d["--procModifiers"] = "premix_stage2"
2603                 # for combined stage1+stage2
2604                 if "_PMXS1S2" in self.suffix:
2605                     d = merge([digiPremixLocalPileup, d])
2606                 stepDict[stepName][k] = d
2607             elif "HARVESTFastRun3" in step:
2608                 # increment input step number
2609                 stepDict[stepName][k] = merge([{'--filein':'file:step3_inDQM.root'},stepDict[stepName][k]])
2610         else:
2611             # setup for stage 1
2612             if "GenSim" in stepName:
2613                 stepNamePmx = stepName.replace('GenSim','Premix')
2614                 if not stepNamePmx in stepDict: stepDict[stepNamePmx] = {}
2615                 stepDict[stepNamePmx][k] = merge([
2616                     {
2617                         '-s': 'GEN,SIM,DIGI:pdigi_valid',
2618                         '--datatier': 'PREMIX',
2619                         '--eventcontent': 'PREMIX',
2620                         '--procModifiers': 'premix_stage1'
2621                     },
2622                     stepDict[stepName][k]
2623                 ])
2624                 if "ProdLike" in self.suffix:
2625                     stepDict[stepNamePmx][k] = merge([{'-s': 'GEN,SIM,DIGI'},stepDict[stepNamePmx][k]])
2626             # setup for stage 2
2627             elif "Digi" in step or "Reco" in step:
2628                 # go back to non-PU step version
2629                 d = merge([stepDict[self.getStepName(step)][k]])
2630                 if d is None: return
2631                 if "Digi" in step:
2632                     tmpsteps = []
2633                     for s in d["-s"].split(","):
2634                         if s == "DIGI" or "DIGI:" in s:
2635                             tmpsteps.extend([s, "DATAMIX"])
2636                         else:
2637                             tmpsteps.append(s)
2638                     d = merge([{"-s"             : ",".join(tmpsteps),
2639                                 "--datamix"      : "PreMix",
2640                                 "--procModifiers": "premix_stage2"},
2641                                d])
2642                     # for combined stage1+stage2
2643                     if "_PMXS1S2" in self.suffix:
2644                         d = merge([digiPremixLocalPileup, d])
2645                 elif "Reco" in step:
2646                     if "--procModifiers" in d:
2647                         d["--procModifiers"] += ",premix_stage2"
2648                     else:
2649                         d["--procModifiers"] = "premix_stage2"
2650                 stepDict[stepName][k] = d
2651             # separate nano step now only used in ProdLike workflows for Run3/Phase2
2652             elif "Nano"==step:
2653                 # go back to non-PU step version
2654                 d = merge([stepDict[self.getStepName(step)][k]])
2655                 if "_PMXS1S2" in self.suffix and "--filein" in d:
2656                     filein = d["--filein"]
2657                     m = re.search("step(?P<ind>\\d+)", filein)
2658                     if m:
2659                         d["--filein"] = filein.replace(m.group(), "step%d"%(int(m.group("ind"))+1))
2660                 stepDict[stepName][k] = d
2661                 # run2/3 WFs use Nano (not NanoPU) in PU WF
2662                 stepDict[self.getStepName(step)][k] = merge([d])
2663     def condition(self, fragment, stepList, key, hasHarvest):
2664         if not 'PU' in key:
2665             return False
2666         if not any(y in key for y in ['2022', '2023', '2024', '2025', 'Run4']):
2667             return False
2668         if self.suffix.endswith("S1"):
2669             return "NuGun" in fragment
2670         return True
2671     def workflow_(self, workflows, num, fragment, stepList, key):
2672         fragmentTmp = fragment
2673         if self.suffix.endswith("S1"):
2674             fragmentTmp = 'PREMIXUP' + key[2:].replace("PU", "").replace("Design", "") + '_PU25'
2675         super(UpgradeWorkflowPremix,self).workflow_(workflows, num, fragmentTmp, stepList, key)
2676 # Premix stage1
2677 upgradeWFs['PMXS1'] = UpgradeWorkflowPremix(
2678     steps = [
2679     ],
2680     PU = [
2681         'Gen',
2682         'GenSim',
2683         'GenSimHLBeamSpot',
2684         'GenSimHLBeamSpot14',
2685     ],
2686     suffix = '_PMXS1',
2687     offset = 0.97,
2688 )
2689 # Premix stage2
2690 upgradeWFs['PMXS2'] = UpgradeWorkflowPremix(
2691     steps = [],
2692     PU = [
2693         'Digi',
2694         'DigiTrigger',
2695         'RecoLocal',
2696         'Reco',
2697         'RecoFakeHLT',
2698         'RecoGlobal',
2699         'RecoGlobalFakeHLT',
2700         'RecoNano',
2701         'RecoNanoFakeHLT',
2702         'Nano',
2703         'FastSimRun3',
2704         'HARVESTFastRun3',
2705     ],
2706     suffix = '_PMXS2',
2707     offset = 0.98,
2708 )
2709 # Premix combined stage1+stage2
2710 upgradeWFs['PMXS1S2'] = UpgradeWorkflowPremix(
2711     steps = [],
2712     PU = [
2713         'Gen',
2714         'GenSim',
2715         'GenSimHLBeamSpot',
2716         'GenSimHLBeamSpot14',
2717         'Digi',
2718         'DigiTrigger',
2719         'RecoLocal',
2720         'Reco',
2721         'RecoFakeHLT',
2722         'RecoGlobal',
2723         'RecoGlobalFakeHLT',
2724         'RecoNano',
2725         'RecoNanoFakeHLT',
2726         'Nano',
2727         'FastSimRun3',
2728         'HARVESTFastRun3',
2729     ],
2730     suffix = '_PMXS1S2',
2731     offset = 0.99,
2732 )
2733 # Alternative version of above w/ less PU for PR tests
2734 class UpgradeWorkflowAdjustPU(UpgradeWorkflowPremix):
2735     def setupPU_(self, step, stepName, stepDict, k, properties):
2736         # adjust first, so it gets copied into new Premix step
2737         if '--pileup' in stepDict[stepName][k]:
2738             stepDict[stepName][k]['--pileup'] = 'AVE_50_BX_25ns_m3p3'
2739         super(UpgradeWorkflowAdjustPU,self).setupPU_(step, stepName, stepDict, k, properties)
2740     def condition(self, fragment, stepList, key, hasHarvest):
2741         # restrict to phase2
2742         return super(UpgradeWorkflowAdjustPU,self).condition(fragment, stepList, key, hasHarvest) and 'Run4' in key
2743 upgradeWFs['PMXS1S2PR'] = UpgradeWorkflowAdjustPU(
2744     steps = [],
2745     PU = [
2746         'GenSim',
2747         'GenSimHLBeamSpot',
2748         'GenSimHLBeamSpot14',
2749         'Digi',
2750         'DigiTrigger',
2751         'RecoLocal',
2752         'Reco',
2753         'RecoFakeHLT',
2754         'RecoGlobal',
2755         'RecoGlobalFakeHLT',
2756         'Nano',
2757         'HARVEST',
2758         'HARVESTFakeHLT',
2759         'HARVESTGlobal',
2760         'HARVESTGlobalFakeHLT',
2761     ],
2762     suffix = '_PMXS1S2PR',
2763     offset = 0.999,
2764 )
2765 
2766 class UpgradeWorkflowPremixProdLike(UpgradeWorkflowPremix,UpgradeWorkflow_ProdLike):
2767     def setup_(self, step, stepName, stepDict, k, properties):
2768         # copy steps, then apply specializations
2769         UpgradeWorkflowPremix.setup_(self, step, stepName, stepDict, k, properties)
2770         UpgradeWorkflow_ProdLike.setup_(self, step, stepName, stepDict, k, properties)
2771         #
2772         if 'Digi' in step:
2773             d = merge([stepDict[self.getStepName(step)][k]])
2774             tmpsteps = []
2775             for s in d["-s"].split(","):
2776                 if "DIGI:pdigi_valid" in s:
2777                     tmpsteps.append("DIGI")
2778                 else:
2779                     tmpsteps.append(s)
2780             d = merge([{"-s" : ",".join(tmpsteps),
2781                         "--eventcontent": "PREMIXRAW"},
2782                        d])
2783             stepDict[stepName][k] = d
2784     def condition(self, fragment, stepList, key, hasHarvest):
2785         # use both conditions
2786         return UpgradeWorkflowPremix.condition(self, fragment, stepList, key, hasHarvest) and UpgradeWorkflow_ProdLike.condition(self, fragment, stepList, key, hasHarvest)
2787 # premix stage2
2788 upgradeWFs['PMXS2ProdLike'] = UpgradeWorkflowPremixProdLike(
2789     steps = [],
2790     PU = [
2791         'Digi',
2792         'DigiTrigger',
2793         'RecoLocal',
2794         'Reco',
2795         'RecoFakeHLT',
2796         'RecoGlobal',
2797         'RecoGlobalFakeHLT',
2798         'RecoNano',
2799         'RecoNanoFakeHLT',
2800         'Nano',
2801         'HARVEST',
2802         'HARVESTFakeHLT',
2803         'HARVESTGlobal',
2804         'HARVESTGlobalFakeHLT',
2805         'HARVESTNano',
2806         'HARVESTNanoFakeHLT',
2807         'MiniAOD',
2808         'ALCA',
2809     ],
2810     suffix = '_PMXS2ProdLike',
2811     offset = 0.9821,
2812 )
2813 # premix combined stage1+stage2
2814 upgradeWFs['PMXS1S2ProdLike'] = UpgradeWorkflowPremixProdLike(
2815     steps = [],
2816     PU = [
2817         'GenSim',
2818         'GenSimHLBeamSpot',
2819         'GenSimHLBeamSpot14',
2820         'Digi',
2821         'DigiTrigger',
2822         'RecoLocal',
2823         'Reco',
2824         'RecoFakeHLT',
2825         'RecoGlobal',
2826         'RecoGlobalFakeHLT',
2827         'RecoNano',
2828         'RecoNanoFakeHLT',
2829         'Nano',
2830         'HARVEST',
2831         'HARVESTFakeHLT',
2832         'HARVESTGlobal',
2833         'HARVESTGlobalFakeHLT',
2834         'HARVESTNano',
2835         'HARVESTNanoFakeHLT',
2836         'MiniAOD',
2837         'ALCA',
2838     ],
2839     suffix = '_PMXS1S2ProdLike',
2840     offset = 0.9921,
2841 )
2842 
2843 class UpgradeWorkflow_Run3FStrackingOnly(UpgradeWorkflow):
2844     def setup_(self, step, stepName, stepDict, k, properties):
2845         if 'HARVESTFastRun3' in step:
2846             stepDict[stepName][k] = merge([{'-s':'HARVESTING:@trackingOnlyValidation+@trackingOnlyDQM',
2847                                             '--fast':'',
2848                                             '--era':'Run3_FastSim',
2849                                             '--filein':'file:step1_inDQM.root'}, stepDict[step][k]])
2850         else:
2851             stepDict[stepName][k] = merge([stepDict[step][k]])
2852     def condition(self, fragment, stepList, key, hasHarvest):
2853         return fragment=="TTbar_14TeV" and ('FS' in key)
2854 upgradeWFs['Run3FStrackingOnly'] = UpgradeWorkflow_Run3FStrackingOnly(
2855     steps = [
2856         'Gen',
2857         'FastSimRun3',
2858         'HARVESTFastRun3'
2859     ],
2860     PU = [
2861         'FastSimRun3',
2862         'HARVESTFastRun3'
2863     ],
2864     suffix = '_Run3FSTrackingOnly',
2865     offset = 0.302,
2866 )
2867 
2868 class UpgradeWorkflow_Run3FSMBMixing(UpgradeWorkflow):
2869     def setup_(self, step, stepName, stepDict, k, properties):
2870         if 'Gen' in step and 'GenOnly' not in step:
2871             stepDict[stepName][k] = merge([{'-s':'GEN,SIM,RECOBEFMIX',
2872                                             '--fast':'',
2873                                             '--era':'Run3_FastSim',
2874                                             '--eventcontent':'FASTPU',
2875                                             '--datatier':'GEN-SIM-RECO',
2876                                             '--relval':'27000,3000'}, stepDict[step][k]])
2877         else:
2878             stepDict[stepName][k] = None
2879     def condition(self, fragment, stepList, key, hasHarvest):
2880         return ('FS' in key) and fragment=="MinBias_14TeV"
2881 upgradeWFs['Run3FSMBMixing'] = UpgradeWorkflow_Run3FSMBMixing(
2882     steps = [
2883         'Gen',
2884         'FastSimRun3',
2885         'HARVESTFastRun3'
2886     ],
2887     PU = [],
2888     suffix = '_Run3FSMBMixing',
2889     offset = 0.303,
2890 )
2891 
2892 
2893 class UpgradeWorkflow_DD4hep(UpgradeWorkflow):
2894     def setup_(self, step, stepName, stepDict, k, properties):
2895         if 'Phase2' in stepDict[step][k]['--era']:
2896             dd4hepGeom="DD4hep"
2897             dd4hepGeom+=stepDict[step][k]['--geometry']
2898             stepDict[stepName][k] = merge([{'--geometry' : dd4hepGeom, '--procModifiers': 'dd4hep'}, stepDict[step][k]])
2899     def condition(self, fragment, stepList, key, hasHarvest):
2900         return ('Run4' in key) and ('FS' not in key)
2901 upgradeWFs['DD4hep'] = UpgradeWorkflow_DD4hep(
2902     steps = [
2903         'GenSim',
2904         'GenSimHLBeamSpot',
2905         'GenSimHLBeamSpot14',
2906         'Digi',
2907         'DigiTrigger',
2908         'Reco',
2909         'RecoFakeHLT',
2910         'RecoGlobal',
2911         'RecoGlobalFakeHLT',
2912         'RecoNano',
2913         'RecoNanoFakeHLT',
2914         'HARVEST',
2915         'HARVESTFakeHLT',
2916         'HARVESTGlobal',
2917         'HARVESTGlobalFakeHLT',
2918         'HARVESTNano',
2919         'HARVESTNanoFakeHLT',
2920         'ALCA',
2921     ],
2922     PU = [],
2923     suffix = '_DD4hep',
2924     offset = 0.911,
2925 )
2926 upgradeWFs['DD4hep'].allowReuse = False
2927 
2928 #This workflow is now obsolete, it becomes default for Run-3.
2929 #Keep it for future use in Phase-2, then delete
2930 class UpgradeWorkflow_DD4hepDB(UpgradeWorkflow):
2931     def setup_(self, step, stepName, stepDict, k, properties):
2932         if 'Run3' in stepDict[step][k]['--era'] and 'Fast' not in stepDict[step][k]['--era']:
2933             stepDict[stepName][k] = merge([{'--conditions': 'auto:phase1_2022_realistic', '--geometry': 'DB:Extended'}, stepDict[step][k]])
2934     def condition(self, fragment, stepList, key, hasHarvest):
2935         return fragment=="TTbar_14TeV" and '2022' in key and 'FS' not in key
2936 upgradeWFs['DD4hepDB'] = UpgradeWorkflow_DD4hepDB(
2937     steps = [
2938         'GenSim',
2939         'GenSimHLBeamSpot',
2940         'GenSimHLBeamSpot14',
2941         'Digi',
2942         'DigiTrigger',
2943         'Reco',
2944         'RecoFakeHLT',
2945         'RecoGlobal',
2946         'RecoGlobalFakeHLT',
2947         'RecoNano',
2948         'RecoNanoFakeHLT',
2949         'HARVEST',
2950         'HARVESTFakeHLT',
2951         'HARVESTGlobal',
2952         'HARVESTGlobalFakeHLT',
2953         'HARVESTNano',
2954         'HARVESTNanoFakeHLT',
2955         'ALCA',
2956     ],
2957     PU = [],
2958     suffix = '_DD4hepDB',
2959     offset = 0.912,
2960 )
2961 upgradeWFs['DD4hepDB'].allowReuse = False
2962 
2963 class UpgradeWorkflow_DDDDB(UpgradeWorkflow):
2964     def setup_(self, step, stepName, stepDict, k, properties):
2965         the_era = stepDict[step][k]['--era']
2966         exclude = ['2025','2024','2023','Fast','Pb']
2967         if 'Run3' in the_era and not any(e in the_era for e in exclude):
2968             # retain any other eras
2969             tmp_eras = the_era.split(',')
2970             tmp_eras[tmp_eras.index("Run3")] = 'Run3_DDD'
2971             tmp_eras = ','.join(tmp_eras)
2972             stepDict[stepName][k] = merge([{'--conditions': 'auto:phase1_2022_realistic_ddd', '--geometry': 'DB:Extended', '--era': tmp_eras}, stepDict[step][k]])
2973     def condition(self, fragment, stepList, key, hasHarvest):
2974         return fragment=="TTbar_14TeV" and '2022' in key and 'FS' not in key and "HI" not in key
2975 upgradeWFs['DDDDB'] = UpgradeWorkflow_DDDDB(
2976     steps = [
2977         'GenSim',
2978         'GenSimHLBeamSpot',
2979         'GenSimHLBeamSpot14',
2980         'Digi',
2981         'DigiTrigger',
2982         'Reco',
2983         'RecoFakeHLT',
2984         'RecoGlobal',
2985         'RecoGlobalFakeHLT',
2986         'RecoNano',
2987         'RecoNanoFakeHLT',
2988         'HARVEST',
2989         'HARVESTFakeHLT',
2990         'HARVESTGlobal',
2991         'HARVESTGlobalFakeHLT',
2992         'HARVESTNano',
2993         'HARVESTNanoFakeHLT',
2994         'ALCA',
2995     ],
2996     PU = [],
2997     suffix = '_DDDDB',
2998     offset = 0.914,
2999 )
3000 upgradeWFs['DDDDB'].allowReuse = False
3001 
3002 class UpgradeWorkflow_SonicTriton(UpgradeWorkflow):
3003     def setup_(self, step, stepName, stepDict, k, properties):
3004         stepDict[stepName][k] = merge([{'--procModifiers': 'allSonicTriton'}, stepDict[step][k]])
3005     def condition(self, fragment, stepList, key, hasHarvest):
3006         return ((fragment=='TTbar_13' or fragment=='TTbar_14TeV') and key.startswith('202')) \
3007             or (fragment=='TTbar_14TeV' and 'Run4' in key)
3008 upgradeWFs['SonicTriton'] = UpgradeWorkflow_SonicTriton(
3009     steps = [
3010         'GenSim',
3011         'GenSimHLBeamSpot',
3012         'GenSimHLBeamSpot14',
3013         'Digi',
3014         'DigiTrigger',
3015         'Reco',
3016         'RecoFakeHLT',
3017         'RecoGlobal',
3018         'RecoGlobalFakeHLT',
3019         'RecoNano',
3020         'RecoNanoFakeHLT',
3021         'HARVEST',
3022         'HARVESTFakeHLT',
3023         'HARVESTGlobal',
3024         'HARVESTGlobalFakeHLT',
3025         'HARVESTNano',
3026         'HARVESTNanoFakeHLT',
3027         'ALCA',
3028     ],
3029     PU = [
3030         'GenSim',
3031         'GenSimHLBeamSpot',
3032         'GenSimHLBeamSpot14',
3033         'Digi',
3034         'DigiTrigger',
3035         'Reco',
3036         'RecoFakeHLT',
3037         'RecoGlobal',
3038         'RecoGlobalFakeHLT',
3039         'RecoNano',
3040         'RecoNanoFakeHLT',
3041         'HARVEST',
3042         'HARVESTFakeHLT',
3043         'HARVESTGlobal',
3044         'HARVESTGlobalFakeHLT',
3045         'HARVESTNano',
3046         'HARVESTNanoFakeHLT',
3047         'ALCA',
3048     ],
3049     suffix = '_SonicTriton',
3050     offset = 0.9001,
3051 )
3052 
3053 class UpgradeWorkflow_Phase2_HeavyIon(UpgradeWorkflow):
3054     def setup_(self, step, stepName, stepDict, k, properties):
3055         stepDict[stepName][k] = merge([{'--procModifiers': 'phase2_pp_on_AA'}, stepDict[step][k]])
3056         if 'GenSim' in step:
3057             stepDict[stepName][k] = merge([{'--conditions': stepDict[step][k]["--conditions"].replace('_13TeV',''), '-n': 1}, stepDict[stepName][k]])
3058         elif 'Digi' in step:
3059             stepDict[stepName][k] = merge([{'-s': stepDict[step][k]["-s"].replace("DIGI:pdigi_valid","DIGI:pdigi_hi"), '--pileup': 'HiMixNoPU'}, stepDict[stepName][k]])
3060     def condition(self, fragment, stepList, key, hasHarvest):
3061         return fragment=='HydjetQMinBias_5519GeV' and 'Run4' in key and 'PU' not in key
3062 
3063 upgradeWFs['Phase2_HeavyIon'] = UpgradeWorkflow_Phase2_HeavyIon(
3064     steps = [
3065         'GenSimHLBeamSpot',
3066         'DigiTrigger',
3067         'RecoGlobal',
3068         'HARVESTGlobal',
3069         'ALCAPhase2'
3070     ],
3071     PU = [],
3072     suffix = '_hi',
3073     offset = 0.85,
3074 )
3075 
3076 # check for duplicates in offsets or suffixes
3077 offsets  = [specialWF.offset for specialType,specialWF in upgradeWFs.items()]
3078 suffixes = [specialWF.suffix for specialType,specialWF in upgradeWFs.items()]
3079 
3080 dups = check_dups(offsets)
3081 if len(dups)>0:
3082     raise ValueError("Duplicate special workflow offsets not allowed: "+','.join([str(x) for x in dups]))
3083 
3084 dups = check_dups(suffixes)
3085 if len(dups)>0:
3086     raise ValueError("Duplicate special workflow suffixes not allowed: "+','.join([str(x) for x in dups]))
3087 
3088 upgradeProperties = {}
3089 
3090 upgradeProperties[2017] = {
3091     '2017' : {
3092         'Geom' : 'DB:Extended',
3093         'GT' : 'auto:phase1_2017_realistic',
3094         'HLTmenu': '@relval2017',
3095         'Era' : 'Run2_2017',
3096         'ScenToRun' : ['GenSim','Digi','RecoFakeHLT','HARVESTFakeHLT','ALCA','Nano'],
3097     },
3098     '2017Design' : {
3099         'Geom' : 'DB:Extended',
3100         'GT' : 'auto:phase1_2017_design',
3101         'HLTmenu': '@relval2017',
3102         'Era' : 'Run2_2017',
3103         'BeamSpot': 'DBdesign',
3104         'ScenToRun' : ['GenSim','Digi','RecoFakeHLT','HARVESTFakeHLT'],
3105     },
3106     '2018' : {
3107         'Geom' : 'DB:Extended',
3108         'GT' : 'auto:phase1_2018_realistic',
3109         'HLTmenu': '@relval2018',
3110         'Era' : 'Run2_2018',
3111         'BeamSpot': 'DBrealistic',
3112         'ScenToRun' : ['GenSim','Digi','RecoFakeHLT','HARVESTFakeHLT','ALCA','Nano'],
3113     },
3114     '2018Design' : {
3115         'Geom' : 'DB:Extended',
3116         'GT' : 'auto:phase1_2018_design',
3117         'HLTmenu': '@relval2018',
3118         'Era' : 'Run2_2018',
3119         'BeamSpot': 'DBdesign',
3120         'ScenToRun' : ['GenSim','Digi','RecoFakeHLT','HARVESTFakeHLT'],
3121     },
3122     '2022' : {
3123         'Geom' : 'DB:Extended',
3124         'GT' : 'auto:phase1_2022_realistic',
3125         'HLTmenu': '@relval2022',
3126         'Era' : 'Run3',
3127         'BeamSpot': 'DBrealistic',
3128         'ScenToRun' : ['GenSim','Digi','RecoNanoFakeHLT','HARVESTNanoFakeHLT','ALCA'],
3129     },
3130     '2022Design' : {
3131         'Geom' : 'DB:Extended',
3132         'GT' : 'auto:phase1_2022_design',
3133         'HLTmenu': '@relval2022',
3134         'Era' : 'Run3',
3135         'BeamSpot': 'DBdesign',
3136         'ScenToRun' : ['GenSim','Digi','RecoNanoFakeHLT','HARVESTNanoFakeHLT'],
3137     },
3138     '2023' : {
3139         'Geom' : 'DB:Extended',
3140         'GT' : 'auto:phase1_2023_realistic',
3141         'HLTmenu': '@relval2023',
3142         'Era' : 'Run3_2023',
3143         'BeamSpot': 'DBrealistic',
3144         'ScenToRun' : ['GenSim','Digi','RecoNanoFakeHLT','HARVESTNanoFakeHLT','ALCA'],
3145     },
3146     '2024' : {
3147         'Geom' : 'DB:Extended',
3148         'GT' : 'auto:phase1_2024_realistic',
3149         'HLTmenu': '@relval2024',
3150         'Era' : 'Run3_2024',
3151         'BeamSpot': 'DBrealistic',
3152         'ScenToRun' : ['GenSim','Digi','RecoNanoFakeHLT','HARVESTNanoFakeHLT','ALCA'],
3153     },
3154     '2024HLTOnDigi' : {
3155         'Geom' : 'DB:Extended',
3156         'GT' : 'auto:phase1_2024_realistic',
3157         'HLTmenu': '@relval2024',
3158         'Era' : 'Run3',
3159         'BeamSpot': 'DBrealistic',
3160         'ScenToRun' : ['GenSim','DigiNoHLT','HLTOnly','RecoNanoFakeHLT','HARVESTNanoFakeHLT','ALCA'],
3161     },
3162     '2022FS' : {
3163         'Geom' : 'DB:Extended',
3164         'GT' : 'auto:phase1_2022_realistic',
3165         'HLTmenu': '@relval2022',
3166         'Era' : 'Run3_FastSim',
3167         'BeamSpot': 'DBrealistic',
3168         'ScenToRun' : ['Gen','FastSimRun3','HARVESTFastRun3'],
3169     },
3170     '2022postEE' : {
3171         'Geom' : 'DB:Extended',
3172         'GT' : 'auto:phase1_2022_realistic_postEE',
3173         'HLTmenu': '@relval2022',
3174         'Era' : 'Run3',
3175         'BeamSpot': 'DBrealistic',
3176         'ScenToRun' : ['GenSim','Digi','RecoNanoFakeHLT','HARVESTNanoFakeHLT','ALCA'],
3177     },
3178     '2023FS' : {
3179         'Geom' : 'DB:Extended',
3180         'GT' : 'auto:phase1_2023_realistic',
3181         'HLTmenu': '@relval2023',
3182         'Era' : 'Run3_2023_FastSim',
3183         'BeamSpot': 'DBrealistic',
3184         'ScenToRun' : ['Gen','FastSimRun3','HARVESTFastRun3'],
3185     },
3186     '2022HI' : {
3187         'Geom' : 'DB:Extended',
3188         'GT':'auto:phase1_2022_realistic_hi',
3189         'HLTmenu': '@fake2',
3190         'Era':'Run3_pp_on_PbPb',
3191         'BeamSpot': 'DBrealistic',
3192         'ScenToRun' : ['GenSim','Digi','RecoNano','HARVESTNano','ALCA'],
3193     },
3194     '2022HIRP' : {
3195         'Geom' : 'DB:Extended',
3196         'GT':'auto:phase1_2022_realistic_hi',
3197         'HLTmenu': '@fake2',
3198         'Era':'Run3_pp_on_PbPb_approxSiStripClusters',
3199         'BeamSpot': 'DBrealistic',
3200         'ScenToRun' : ['GenSim','Digi','RecoNano','HARVESTNano','ALCA'],
3201     },
3202     '2023HI' : {
3203         'Geom' : 'DB:Extended',
3204         'GT':'auto:phase1_2023_realistic_hi',
3205         'HLTmenu': '@fake2',
3206         'Era':'Run3_pp_on_PbPb',
3207         'BeamSpot': 'DBrealistic',
3208         'ScenToRun' : ['GenSim','Digi','RecoNano','HARVESTNano','ALCA'],
3209     },
3210     '2023HIRP' : {
3211         'Geom' : 'DB:Extended',
3212         'GT':'auto:phase1_2023_realistic_hi',
3213         'HLTmenu': '@fake2',
3214         'Era':'Run3_pp_on_PbPb_approxSiStripClusters',
3215         'BeamSpot': 'DBrealistic',
3216         'ScenToRun' : ['GenSim','Digi','RecoNano','HARVESTNano','ALCA'],
3217     },
3218     '2024GenOnly' : {
3219         'Geom' : 'DB:Extended',
3220         'GT' : 'auto:phase1_2024_realistic',
3221         'Era' : 'Run3',
3222         'BeamSpot': 'DBrealistic',
3223         'ScenToRun' : ['Gen'],
3224     },
3225     '2024SimOnGen' : {
3226         'Geom' : 'DB:Extended',
3227         'GT' : 'auto:phase1_2024_realistic',
3228         'HLTmenu': '@relval2024',
3229         'Era' : 'Run3',
3230         'BeamSpot': 'DBrealistic',
3231         'ScenToRun' : ['Gen','Sim','Digi','RecoNanoFakeHLT','HARVESTNanoFakeHLT','ALCA'],
3232     },
3233     '2024FS' : {
3234         'Geom' : 'DB:Extended',
3235         'GT' : 'auto:phase1_2024_realistic',
3236         'HLTmenu': '@relval2024',
3237         'Era' : 'Run3_FastSim',
3238         'BeamSpot': 'DBrealistic',
3239         'ScenToRun' : ['Gen','FastSimRun3','HARVESTFastRun3'],
3240     },
3241     '2025' : {
3242         'Geom' : 'DB:Extended',
3243         'GT' : 'auto:phase1_2025_realistic',
3244         'HLTmenu': '@relval2025',
3245         'Era' : 'Run3_2025',
3246         'BeamSpot': 'DBrealistic',
3247         'ScenToRun' : ['GenSim','Digi','RecoNano','HARVESTNano','ALCA'],
3248     },
3249     '2025HLTOnDigi' : {
3250         'Geom' : 'DB:Extended',
3251         'GT' : 'auto:phase1_2025_realistic',
3252         'HLTmenu': '@relval2025',
3253         'Era' : 'Run3_2025',
3254         'BeamSpot': 'DBrealistic',
3255         'ScenToRun' : ['GenSim','DigiNoHLT','HLTOnly','RecoNano','HARVESTNano','ALCA'],
3256     },
3257     '2025GenOnly' : {
3258         'Geom' : 'DB:Extended',
3259         'GT' : 'auto:phase1_2025_realistic',
3260         'HLTmenu': '@relval2025',
3261         'Era' : 'Run3_2025',
3262         'BeamSpot': 'DBrealistic',
3263         'ScenToRun' : ['Gen'],
3264     },
3265     '2025SimOnGen' : {
3266         'Geom' : 'DB:Extended',
3267         'GT' : 'auto:phase1_2025_realistic',
3268         'HLTmenu': '@relval2025',
3269         'Era' : 'Run3_2025',
3270         'BeamSpot': 'DBrealistic',
3271         'ScenToRun' : ['Gen','Sim','Digi','RecoNano','HARVESTNano','ALCA'],
3272     },
3273     
3274 }
3275 
3276 # standard PU sequences
3277 for key in list(upgradeProperties[2017].keys()):
3278     if "GenOnly" in key:
3279         continue
3280     upgradeProperties[2017][key+'PU'] = deepcopy(upgradeProperties[2017][key])
3281     if 'FS' not in key:
3282         # update ScenToRun list
3283         scenToRun = upgradeProperties[2017][key+'PU']['ScenToRun']
3284         for idx,val in enumerate(scenToRun):
3285             # Digi -> DigiPU, Reco* -> Reco*PU, HARVEST* -> HARVEST*PU
3286             scenToRun[idx] += 'PU'*(val.startswith('Digi') or val.startswith('Reco') or val.startswith('HARVEST'))
3287         # remove ALCA
3288         upgradeProperties[2017][key+'PU']['ScenToRun'] = [foo for foo in scenToRun if foo != 'ALCA']
3289     else:
3290         upgradeProperties[2017][key+'PU']['ScenToRun'] = ['Gen','FastSimRun3PU','HARVESTFastRun3PU']
3291 
3292 upgradeProperties['Run4'] = {
3293     'Run4D86' : {
3294         'Geom' : 'ExtendedRun4D86',
3295         'HLTmenu': '@fake2',
3296         'GT' : 'auto:phase2_realistic_T21',
3297         'Era' : 'Phase2C17I13M9',
3298         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobalFakeHLT', 'HARVESTGlobalFakeHLT', 'ALCAPhase2'],
3299     },
3300     'Run4D88' : {
3301         'Geom' : 'ExtendedRun4D88',
3302         'HLTmenu': '@relvalRun4',
3303         'GT' : 'auto:phase2_realistic_T21',
3304         'Era' : 'Phase2C17I13M9',
3305         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3306     },
3307     'Run4D91' : {
3308         'Geom' : 'ExtendedRun4D91',
3309         'HLTmenu': '@fake2',
3310         'GT' : 'auto:phase2_realistic_T30',
3311         'Era' : 'Phase2C17I13M9',
3312         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobalFakeHLT', 'HARVESTGlobalFakeHLT', 'ALCAPhase2'],
3313     },
3314     'Run4D92' : {
3315         'Geom' : 'ExtendedRun4D92',
3316         'HLTmenu': '@fake2',
3317         'GT' : 'auto:phase2_realistic_T21',
3318         'Era' : 'Phase2C17I13M9',
3319         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobalFakeHLT', 'HARVESTGlobalFakeHLT', 'ALCAPhase2'],
3320     },
3321     'Run4D93' : {
3322         'Geom' : 'ExtendedRun4D93',
3323         'HLTmenu': '@fake2',
3324         'GT' : 'auto:phase2_realistic_T21',
3325         'Era' : 'Phase2C17I13M9',
3326         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobalFakeHLT', 'HARVESTGlobalFakeHLT', 'ALCAPhase2'],
3327     },
3328     'Run4D94' : {
3329         'Geom' : 'ExtendedRun4D94',
3330         'HLTmenu': '@fake2',
3331         'GT' : 'auto:phase2_realistic_T21',
3332         'Era' : 'Phase2C20I13M9',
3333         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobalFakeHLT', 'HARVESTGlobalFakeHLT', 'ALCAPhase2'],
3334     },
3335     'Run4D95' : {
3336         'Geom' : 'ExtendedRun4D95',
3337         'HLTmenu': '@relvalRun4',
3338         'GT' : 'auto:phase2_realistic_T21',
3339         'Era' : 'Phase2C17I13M9',
3340         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3341     },
3342     'Run4D96' : {
3343         'Geom' : 'ExtendedRun4D96',
3344         'HLTmenu': '@fake2',
3345         'GT' : 'auto:phase2_realistic_T21',
3346         'Era' : 'Phase2C17I13M9',
3347         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobalFakeHLT', 'HARVESTGlobalFakeHLT', 'ALCAPhase2'],
3348     },
3349     'Run4D97' : {
3350         'Geom' : 'ExtendedRun4D97',
3351         'HLTmenu': '@fake2',
3352         'GT' : 'auto:phase2_realistic_T25',
3353         'Era' : 'Phase2C17I13M9',
3354         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobalFakeHLT', 'HARVESTGlobalFakeHLT', 'ALCAPhase2'],
3355     },
3356     'Run4D98' : {
3357         'Geom' : 'ExtendedRun4D98',
3358         'HLTmenu': '@relvalRun4',
3359         'GT' : 'auto:phase2_realistic_T25',
3360         'Era' : 'Phase2C17I13M9',
3361         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3362     },
3363     'Run4D99' : {
3364         'Geom' : 'ExtendedRun4D99',
3365         'HLTmenu': '@relvalRun4',
3366         'GT' : 'auto:phase2_realistic_T25',
3367         'Era' : 'Phase2C17I13M9',
3368         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3369     },
3370     'Run4D100' : {
3371         'Geom' : 'ExtendedRun4D100',
3372         'HLTmenu': '@relvalRun4',
3373         'GT' : 'auto:phase2_realistic_T25',
3374         'Era' : 'Phase2C17I13M9',
3375         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3376     },
3377     'Run4D101' : {
3378         'Geom' : 'ExtendedRun4D101',
3379         'HLTmenu': '@relvalRun4',
3380         'GT' : 'auto:phase2_realistic_T25',
3381         'Era' : 'Phase2C17I13M9',
3382         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3383     },
3384     'Run4D102' : {
3385         'Geom' : 'ExtendedRun4D102',
3386         'HLTmenu': '@relvalRun4',
3387         'GT' : 'auto:phase2_realistic_T33',
3388         'Era' : 'Phase2C17I13M9',
3389         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3390     },
3391     'Run4D103' : {
3392         'Geom' : 'ExtendedRun4D103',
3393         'HLTmenu': '@relvalRun4',
3394         'GT' : 'auto:phase2_realistic_T25',
3395         'Era' : 'Phase2C17I13M9',
3396         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3397     },
3398     'Run4D104' : {
3399         'Geom' : 'ExtendedRun4D104',
3400         'HLTmenu': '@relvalRun4',
3401         'GT' : 'auto:phase2_realistic_T33',
3402         'Era' : 'Phase2C22I13M9',
3403         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3404     },
3405     'Run4D105' : {
3406         'Geom' : 'ExtendedRun4D105',
3407         'HLTmenu': '@relvalRun4',
3408         'GT' : 'auto:phase2_realistic_T33',
3409         'Era' : 'Phase2C17I13M9',
3410         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3411     },
3412     'Run4D106' : {
3413         'Geom' : 'ExtendedRun4D106',
3414         'HLTmenu': '@relvalRun4',
3415         'GT' : 'auto:phase2_realistic_T33',
3416         'Era' : 'Phase2C22I13M9',
3417         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3418     },
3419     'Run4D107' : {
3420         'Geom' : 'ExtendedRun4D107',
3421         'HLTmenu': '@relvalRun4',
3422         'GT' : 'auto:phase2_realistic_T25',
3423         'Era' : 'Phase2C17I13M9',
3424         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3425     },
3426     'Run4D108' : {
3427         'Geom' : 'ExtendedRun4D108',
3428         'HLTmenu': '@relvalRun4',
3429         'GT' : 'auto:phase2_realistic_T33',
3430         'Era' : 'Phase2C17I13M9',
3431         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3432     },
3433     'Run4D109' : {
3434         'Geom' : 'ExtendedRun4D109',
3435         'HLTmenu': '@relvalRun4',
3436         'GT' : 'auto:phase2_realistic_T33',
3437         'Era' : 'Phase2C22I13M9',
3438         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3439     },
3440     'Run4D110' : {
3441         'Geom' : 'ExtendedRun4D110',
3442         'HLTmenu': '@relvalRun4',
3443         'GT' : 'auto:phase2_realistic_T33',
3444         'Era' : 'Phase2C17I13M9',
3445         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3446     },
3447    'Run4D111' : {
3448         'Geom' : 'ExtendedRun4D111',
3449         'HLTmenu': '@relvalRun4',
3450         'GT' : 'auto:phase2_realistic_T36',
3451         'Era' : 'Phase2C22I13M9',
3452         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3453     },
3454     'Run4D112' : {
3455         'Geom' : 'ExtendedRun4D112',
3456         'HLTmenu': '@relvalRun4',
3457         'GT' : 'auto:phase2_realistic_T37',
3458         'Era' : 'Phase2C22I13M9',
3459         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3460     },
3461     'Run4D113' : {
3462         'Geom' : 'ExtendedRun4D113',
3463         'HLTmenu': '@relvalRun4',
3464         'GT' : 'auto:phase2_realistic_T38',
3465         'Era' : 'Phase2C22I13M9',
3466         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3467     },
3468     'Run4D114' : {
3469         'Geom' : 'ExtendedRun4D114',
3470         'HLTmenu': '@relvalRun4',
3471         'GT' : 'auto:phase2_realistic_T33',
3472         'Era' : 'Phase2C17I13M9',
3473         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3474     },
3475     'Run4D110GenOnly' : {
3476         'Geom' : 'ExtendedRun4D110',
3477         'BeamSpot' : 'DBrealisticHLLHC',
3478         'GT' : 'auto:phase2_realistic_T33',
3479         'Era' : 'Phase2C17I13M9',
3480         'ScenToRun' : ['GenHLBeamSpot'],
3481     },
3482     'Run4D110SimOnGen' : {
3483         'Geom' : 'ExtendedRun4D110',
3484         'HLTmenu': '@relvalRun4',
3485         'BeamSpot' : 'DBrealisticHLLHC',
3486         'GT' : 'auto:phase2_realistic_T33',
3487         'Era' : 'Phase2C17I13M9',
3488         'ScenToRun' : ['GenHLBeamSpot','Sim','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3489     },
3490     'Run4D115' : {
3491         'Geom' : 'ExtendedRun4D115',
3492         'HLTmenu': '@relvalRun4',
3493         'GT' : 'auto:phase2_realistic_T33',
3494         'Era' : 'Phase2C20I13M9',
3495         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3496     },
3497     'Run4D116' : {
3498         'Geom' : 'ExtendedRun4D116',
3499         'HLTmenu': '@relvalRun4',
3500         'GT' : 'auto:phase2_realistic_T33',
3501         'Era' : 'Phase2C22I13M9',
3502         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3503     },
3504     'Run4D117' : {
3505         'Geom' : 'ExtendedRun4D117',
3506         'HLTmenu': '@relvalRun4',
3507         'GT' : 'auto:phase2_realistic_T33',
3508         'Era' : 'Phase2C22I13M9',
3509         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3510     },
3511     'Run4D118' : {
3512         'Geom' : 'ExtendedRun4D118',
3513         'HLTmenu': '@relvalRun4',
3514         'GT' : 'auto:phase2_realistic_T33',
3515         'Era' : 'Phase2C22I13M9',
3516         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3517     },
3518     'Run4D119' : {
3519         'Geom' : 'ExtendedRun4D119',
3520         'HLTmenu': '@relvalRun4',
3521         'GT' : 'auto:phase2_realistic_T33',
3522         'Era' : 'Phase2C22I13M9',
3523         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3524     },
3525     'Run4D120' : {
3526         'Geom' : 'ExtendedRun4D120',
3527         'HLTmenu': '@relvalRun4',
3528         'GT' : 'auto:phase2_realistic_T33',
3529         'Era' : 'Phase2C22I13M9',
3530         'ScenToRun' : ['GenSimHLBeamSpot','DigiTrigger','RecoGlobal', 'HARVESTGlobal', 'ALCAPhase2'],
3531     },
3532 }
3533 
3534 # standard PU sequences
3535 for key in list(upgradeProperties['Run4'].keys()):
3536     if "GenOnly" in key:
3537         continue
3538     upgradeProperties['Run4'][key+'PU'] = deepcopy(upgradeProperties['Run4'][key])
3539     upgradeProperties['Run4'][key+'PU']['ScenToRun'] = ['GenSimHLBeamSpot','DigiTriggerPU','RecoGlobalPU', 'HARVESTGlobalPU']
3540 
3541 # for relvals
3542 defaultDataSets = {}
3543 for year in upgradeKeys:
3544     for key in upgradeKeys[year]:
3545         if 'PU' in key: continue
3546         defaultDataSets[key] = ''
3547 
3548 
3549 class UpgradeFragment(object):
3550     def __init__(self, howMuch, dataset):
3551         self.howMuch = howMuch
3552         self.dataset = dataset
3553 
3554 upgradeFragments = OrderedDict([
3555     ('FourMuPt_1_200_pythia8_cfi', UpgradeFragment(Kby(10,100),'FourMuPt1_200')),
3556     ('SingleElectronPt10_pythia8_cfi', UpgradeFragment(Kby(9,100),'SingleElectronPt10')),
3557     ('SingleElectronPt35_pythia8_cfi', UpgradeFragment(Kby(9,100),'SingleElectronPt35')),
3558     ('SingleElectronPt1000_pythia8_cfi', UpgradeFragment(Kby(9,50),'SingleElectronPt1000')),
3559     ('SingleGammaPt10_pythia8_cfi', UpgradeFragment(Kby(9,100),'SingleGammaPt10')),
3560     ('SingleGammaPt35_pythia8_cfi', UpgradeFragment(Kby(9,50),'SingleGammaPt35')),
3561     ('SingleMuPt1_pythia8_cfi', UpgradeFragment(Kby(25,100),'SingleMuPt1')),
3562     ('SingleMuPt10_Eta2p85_cfi', UpgradeFragment(Kby(9,100),'SingleMuPt10')),
3563     ('SingleMuPt100_Eta2p85_cfi', UpgradeFragment(Kby(9,100),'SingleMuPt100')),
3564     ('SingleMuPt1000_Eta2p85_cfi', UpgradeFragment(Kby(9,100),'SingleMuPt1000')),
3565     ('FourMuExtendedPt_1_200_pythia8_cfi', UpgradeFragment(Kby(10,100),'FourMuExtendedPt1_200')),
3566     ('TenMuExtendedE_0_200_pythia8_cfi', UpgradeFragment(Kby(10,100),'TenMuExtendedE_0_200')),
3567     ('DoubleElectronPt10Extended_pythia8_cfi', UpgradeFragment(Kby(9,100),'SingleElPt10Extended')),
3568     ('DoubleElectronPt35Extended_pythia8_cfi', UpgradeFragment(Kby(9,100),'SingleElPt35Extended')),
3569     ('DoubleElectronPt1000Extended_pythia8_cfi', UpgradeFragment(Kby(9,50),'SingleElPt1000Extended')),
3570     ('DoubleGammaPt10Extended_pythia8_cfi', UpgradeFragment(Kby(9,100),'SingleGammaPt10Extended')),
3571     ('DoubleGammaPt35Extended_pythia8_cfi', UpgradeFragment(Kby(9,50),'SingleGammaPt35Extended')),
3572     ('DoubleMuPt1Extended_pythia8_cfi', UpgradeFragment(Kby(25,100),'SingleMuPt1Extended')),
3573     ('DoubleMuPt10Extended_pythia8_cfi', UpgradeFragment(Kby(25,100),'SingleMuPt10Extended')),
3574     ('DoubleMuPt100Extended_pythia8_cfi', UpgradeFragment(Kby(9,100),'SingleMuPt100Extended')),
3575     ('DoubleMuPt1000Extended_pythia8_cfi', UpgradeFragment(Kby(9,100),'SingleMuPt1000Extended')),
3576     ('TenMuE_0_200_pythia8_cfi', UpgradeFragment(Kby(10,100),'TenMuE_0_200')),
3577     ('SinglePiE50HCAL_pythia8_cfi', UpgradeFragment(Kby(50,500),'SinglePiE50HCAL')),
3578     ('MinBias_13TeV_pythia8_TuneCUETP8M1_cfi', UpgradeFragment(Kby(90,100),'MinBias_13')),
3579     ('TTbar_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'TTbar_13')),
3580     ('ZEE_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,100),'ZEE_13')),
3581     ('QCD_Pt_600_800_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'QCD_Pt_600_800_13')),
3582     ('Wjet_Pt_80_120_14TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,100),'Wjet_Pt_80_120_14TeV')),
3583     ('Wjet_Pt_3000_3500_14TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'Wjet_Pt_3000_3500_14TeV')),
3584     ('LM1_sfts_14TeV_cfi', UpgradeFragment(Kby(9,100),'LM1_sfts_14TeV')),
3585     ('QCD_Pt_3000_3500_14TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'QCD_Pt_3000_3500_14TeV')),
3586     ('QCD_Pt_80_120_14TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,100),'QCD_Pt_80_120_14TeV')),
3587     ('H200ChargedTaus_Tauola_14TeV_cfi', UpgradeFragment(Kby(9,100),'Higgs200ChargedTaus_14TeV')),
3588     ('JpsiMM_14TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(66,100),'JpsiMM_14TeV')),
3589     ('TTbar_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(9,100),'TTbar_14TeV')),
3590     ('WE_14TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,100),'WE_14TeV')),
3591     ('ZTT_Tauola_All_hadronic_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(9,100),'ZTT_14TeV')),
3592     ('H130GGgluonfusion_14TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,100),'H130GGgluonfusion_14TeV')),
3593     ('PhotonJet_Pt_10_14TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,100),'PhotonJets_Pt_10_14TeV')),
3594     ('QQH1352T_Tauola_14TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,100),'QQH1352T_Tauola_14TeV')),
3595     ('MinBias_14TeV_pythia8_TuneCP5_cfi', UpgradeFragment(Kby(90,100),'MinBias_14TeV')),
3596     ('WToMuNu_14TeV_TuneCP5_pythia8_cfi', UpgradeFragment(Kby(9,100),'WToMuNu_14TeV')),
3597     ('ZMM_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(18,100),'ZMM_13')),
3598     ('QCDForPF_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(50,100),'QCD_FlatPt_15_3000HS_14')),
3599     ('DYToLL_M-50_14TeV_pythia8_cff', UpgradeFragment(Kby(9,100),'DYToLL_M_50_14TeV')),
3600     ('DYToTauTau_M-50_14TeV_pythia8_tauola_cff', UpgradeFragment(Kby(9,100),'DYtoTauTau_M_50_14TeV')),
3601     ('ZEE_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(9,100),'ZEE_14')),
3602     ('QCD_Pt_80_120_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,100),'QCD_Pt_80_120_13')),
3603     ('H125GGgluonfusion_13TeV_TuneCP5_cfi', UpgradeFragment(Kby(9,50),'H125GGgluonfusion_13')),
3604     ('QCD_Pt20toInf_MuEnrichedPt15_14TeV_TuneCP5_cff', UpgradeFragment(Kby(19565, 217391),'QCD_Pt20toInfMuEnrichPt15_14')), # effi = 4.6e-4,  local=8.000e-04
3605     ('ZMM_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(18,100),'ZMM_14')),
3606     ('QCD_Pt15To7000_Flat_14TeV_TuneCP5_cff', UpgradeFragment(Kby(9,50),'QCD_Pt15To7000_Flat_14')),
3607     ('H125GGgluonfusion_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(9,50),'H125GGgluonfusion_14')),
3608     ('QCD_Pt_600_800_14TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'QCD_Pt_600_800_14')),
3609     ('UndergroundCosmicSPLooseMu_cfi', UpgradeFragment(Kby(9,50),'CosmicsSPLoose')),
3610     ('BeamHalo_13TeV_cfi', UpgradeFragment(Kby(9,50),'BeamHalo_13')),
3611     ('H200ChargedTaus_Tauola_13TeV_cfi', UpgradeFragment(Kby(9,50),'Higgs200ChargedTaus_13')),
3612     ('ADDMonoJet_13TeV_d3MD3_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'ADDMonoJet_d3MD3_13')),
3613     ('ZpMM_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'ZpMM_13')),
3614     ('QCD_Pt_3000_3500_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'QCD_Pt_3000_3500_13')),
3615     ('WpM_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'WpM_13')),
3616     ('SingleNuE10_cfi', UpgradeFragment(Kby(9,50),'NuGun')),
3617     ('TTbarLepton_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'TTbarLepton_13')),
3618     ('WE_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'WE_13')),
3619     ('WM_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'WM_13')),
3620     ('ZTT_All_hadronic_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'ZTT_13')),
3621     ('PhotonJet_Pt_10_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'PhotonJets_Pt_10_13')),
3622     ('QQH1352T_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'QQH1352T_13')),
3623     ('Wjet_Pt_80_120_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'Wjet_Pt_80_120_13')),
3624     ('Wjet_Pt_3000_3500_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'Wjet_Pt_3000_3500_13')),
3625     ('SMS-T1tttt_mGl-1500_mLSP-100_13TeV-pythia8_cfi', UpgradeFragment(Kby(9,50),'SMS-T1tttt_mGl-1500_mLSP-100_13')),
3626     ('QCDForPF_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(50,100),'QCD_FlatPt_15_3000HS_13')),
3627     ('PYTHIA8_PhiToMuMu_TuneCUETP8M1_13TeV_cff', UpgradeFragment(Kby(9,50),'PhiToMuMu_13')),
3628     ('RSKKGluon_m3000GeV_13TeV_TuneCUETP8M1_cff', UpgradeFragment(Kby(9,50),'RSKKGluon_m3000GeV_13')),
3629     ('ZpMM_2250_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'ZpMM_2250_13')),
3630     ('ZpEE_2250_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'ZpEE_2250_13')),
3631     ('ZpTT_1500_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'ZpTT_1500_13')),
3632     ('Upsilon1SToMuMu_forSTEAM_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(9,50),'Upsilon1SToMuMu_13')),
3633     ('EtaBToJpsiJpsi_forSTEAM_TuneCUEP8M1_13TeV_cfi', UpgradeFragment(Kby(9,50),'EtaBToJpsiJpsi_13')),
3634     ('JpsiMuMu_Pt-8_forSTEAM_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(3100,100000),'JpsiMuMu_Pt-8')),
3635     ('BuMixing_BMuonFilter_forSTEAM_13TeV_TuneCUETP8M1_cfi', UpgradeFragment(Kby(900,10000),'BuMixing_13')),
3636     ('HSCPstop_M_200_TuneCUETP8M1_13TeV_pythia8_cff', UpgradeFragment(Kby(9,50),'HSCPstop_M_200_13')),
3637     ('RSGravitonToGammaGamma_kMpl01_M_3000_TuneCUETP8M1_13TeV_pythia8_cfi', UpgradeFragment(Kby(9,50),'RSGravitonToGaGa_13')),
3638     ('WprimeToENu_M-2000_TuneCUETP8M1_13TeV-pythia8_cff', UpgradeFragment(Kby(9,50),'WpToENu_M-2000_13')),
3639     ('DisplacedSUSY_stopToBottom_M_800_500mm_TuneCP5_13TeV_pythia8_cff', UpgradeFragment(Kby(9,50),'DisplacedSUSY_stopToB_M_800_500mm_13')),
3640     ('TenE_E_0_200_pythia8_cfi', UpgradeFragment(Kby(9,100),'TenE_0_200')),
3641     ('FlatRandomPtAndDxyGunProducer_cfi', UpgradeFragment(Kby(9,100),'DisplacedMuonsDxy_0_500')),
3642     ('TenTau_E_15_500_pythia8_cfi', UpgradeFragment(Kby(9,100),'TenTau_15_500')),
3643     ('SinglePiPt25Eta1p7_2p7_cfi', UpgradeFragment(Kby(9,100),'SinglePiPt25Eta1p7_2p7')),
3644     ('SingleMuPt15Eta1p7_2p7_cfi', UpgradeFragment(Kby(9,100),'SingleMuPt15Eta1p7_2p7')),
3645     ('SingleGammaPt25Eta1p7_2p7_cfi', UpgradeFragment(Kby(9,100),'SingleGammaPt25Eta1p7_2p7')),
3646     ('SingleElectronPt15Eta1p7_2p7_cfi', UpgradeFragment(Kby(9,100),'SingleElectronPt15Eta1p7_2p7')),
3647     ('ZTT_All_hadronic_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(9,50),'ZTT_14')),
3648     ('CloseByParticle_Photon_ERZRanges_cfi', UpgradeFragment(Kby(9,100),'CloseByParticleGun')),
3649     ('CE_E_Front_300um_cfi', UpgradeFragment(Kby(9,100),'CloseByPGun_CE_E_Front_300um')),
3650     ('CE_E_Front_200um_cfi', UpgradeFragment(Kby(9,100),'CloseByPGun_CE_E_Front_200um')),
3651     ('CE_E_Front_120um_cfi', UpgradeFragment(Kby(9,100),'CloseByPGun_CE_E_Front_120um')),
3652     ('CE_H_Fine_300um_cfi', UpgradeFragment(Kby(9,100),'CloseByPGun_CE_H_Fine_300um')),
3653     ('CE_H_Fine_200um_cfi', UpgradeFragment(Kby(9,100),'CloseByPGun_CE_H_Fine_200um')),
3654     ('CE_H_Fine_120um_cfi', UpgradeFragment(Kby(9,100),'CloseByPGun_CE_H_Fine_120um')),
3655     ('CE_H_Coarse_Scint_cfi', UpgradeFragment(Kby(9,100),'CloseByPGun_CE_H_Coarse_Scint')),
3656     ('CE_H_Coarse_300um_cfi', UpgradeFragment(Kby(9,100),'CloseByPGun_CE_H_Coarse_300um')),
3657     ('SingleElectronFlatPt2To100_cfi', UpgradeFragment(Kby(9,100),'SingleEFlatPt2To100')),
3658     ('SingleMuFlatPt0p7To10_cfi', UpgradeFragment(Kby(9,100),'SingleMuFlatPt0p7To10')),
3659     ('SingleMuFlatPt2To100_cfi', UpgradeFragment(Kby(9,100),'SingleMuFlatPt2To100')),
3660     ('SingleGammaFlatPt8To150_cfi', UpgradeFragment(Kby(9,100),'SingleGammaFlatPt8To150')),
3661     ('SinglePiFlatPt0p7To10_cfi', UpgradeFragment(Kby(9,100),'SinglePiFlatPt0p7To10')),
3662     ('SingleTauFlatPt2To150_cfi', UpgradeFragment(Kby(9,100),'SingleTauFlatPt2To150')),
3663     ('FlatRandomPtAndDxyGunProducer_MuPt2To10_cfi', UpgradeFragment(Kby(9,100),'DisplacedMuPt2To10')),
3664     ('FlatRandomPtAndDxyGunProducer_MuPt10To30_cfi', UpgradeFragment(Kby(9,100),'DisplacedMuPt10To30')),
3665     ('FlatRandomPtAndDxyGunProducer_MuPt30To100_cfi', UpgradeFragment(Kby(9,100),'DisplacedMuPt30To100')),
3666     ('B0ToKstarMuMu_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(304,3030),'B0ToKstarMuMu_14TeV')), # 3.3%
3667     ('BsToEleEle_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(223,2222),'BsToEleEle_14TeV')), # 4.5%
3668     ('BsToJpsiGamma_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(2500,25000),'BsToJpsiGamma_14TeV')), # 0.4%
3669     ('BsToJpsiPhi_mumuKK_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(910,9090),'BsToJpsiPhi_mumuKK_14TeV')), # 1.1%
3670     ('BsToMuMu_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(313,3125),'BsToMuMu_14TeV')), # 3.2%
3671     ('BsToPhiPhi_KKKK_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(556,5555),'BsToPhiPhi_KKKK_14TeV')), # 1.8%
3672     ('TauToMuMuMu_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(18939,189393),'TauToMuMuMu_14TeV')), # effi = 5.280e-04
3673     ('BdToKstarEleEle_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(206,2061),'BdToKstarEleEle_14TeV')), #effi = 4.850e-02
3674     ('ZpTT_1500_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(9,50),'ZpTT_1500_14')),
3675     ('BuMixing_BMuonFilter_forSTEAM_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(900,10000),'BuMixing_14')),
3676     ('Upsilon1SToMuMu_forSTEAM_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(9,50),'Upsilon1SToMuMu_14')),
3677     ('TenTau_E_15_500_Eta3p1_pythia8_cfi', UpgradeFragment(Kby(9,100),'TenTau_15_500_Eta3p1')),
3678     ('QCD_Pt_1800_2400_14TeV_TuneCP5_cfi', UpgradeFragment(Kby(9,50), 'QCD_Pt_1800_2400_14')),
3679     ('DisplacedSUSY_stopToBottom_M_800_500mm_TuneCP5_14TeV_pythia8_cff', UpgradeFragment(Kby(9,50),'DisplacedSUSY_14TeV')),
3680     ('GluGluTo2Jets_M_300_2000_14TeV_Exhume_cff',UpgradeFragment(Kby(9,100),'GluGluTo2Jets_14TeV')),
3681     ('TTbarToDilepton_mt172p5_TuneCP5_14TeV_pythia8_cfi',UpgradeFragment(Kby(9,50),'TTbarToDilepton_14TeV')),
3682     ('QQToHToTauTau_mh125_TuneCP5_14TeV_pythia8_cfi',UpgradeFragment(Kby(9,50),'QQToHToTauTau_14TeV')),
3683     ('ZpToEE_m6000_TuneCP5_14TeV_pythia8_cfi',UpgradeFragment(Kby(9,50),'ZpToEE_m6000_14TeV')),
3684     ('ZpToMM_m6000_TuneCP5_14TeV_pythia8_cfi',UpgradeFragment(Kby(9,50),'ZpToMM_m6000_14TeV')),
3685     ('SMS-T1tttt_mGl-1500_mLSP-100_TuneCP5_14TeV_pythia8_cfi',UpgradeFragment(Kby(9,50),'SMS-T1tttt_14TeV')),
3686     ('VBFHZZ4Nu_TuneCP5_14TeV_pythia8_cfi',UpgradeFragment(Kby(9,50),'VBFHZZ4Nu_14TeV')),
3687     ('EtaBToJpsiJpsi_14TeV_TuneCP5_pythia8_cfi',UpgradeFragment(Kby(9,50),'EtaBToJpsiJpsi_14TeV')),
3688     ('WToLNu_14TeV_TuneCP5_pythia8_cfi',UpgradeFragment(Kby(21,50),'WToLNu_14TeV')),
3689     ('WprimeToLNu_M2000_14TeV_TuneCP5_pythia8_cfi',UpgradeFragment(Kby(21,50),'WprimeToLNu_M2000_14TeV')),
3690     ('DoubleMuFlatPt1p5To8_cfi', UpgradeFragment(Kby(9,100),'SingleMuFlatPt1p5To8')),
3691     ('DoubleElectronFlatPt1p5To8_cfi', UpgradeFragment(Kby(9,100),'SingleElectronFlatPt1p5To8')),
3692     ('DoubleMuFlatPt1p5To8Dxy100GunProducer_cfi', UpgradeFragment(Kby(9,100),'DisplacedMuPt1p5To8Dxy100')),
3693     ('DoubleMuFlatPt2To100Dxy100GunProducer_cfi', UpgradeFragment(Kby(9,100),'DisplacedMuPt2To100Dxy100')),
3694     ('BuToJPsiPrimeKToJPsiPiPiK_14TeV_TuneCP5_pythia8_cfi', UpgradeFragment(Kby(223,2222),'BuToJPsiPrimeKToJPsiPiPiK_14TeV')), # 5.7%
3695     ('Psi2SToJPsiPiPi_14TeV_TuneCP5_pythia8_cfi', UpgradeFragment(Kby(45,500),'Psi2SToJPsiPiPi_14TeV')), # 24.6%
3696     ('XiMinus_13p6TeV_SoftQCDInel_TuneCP5_cfi', UpgradeFragment(Kby(8000,90000),'XiMinus_13p6TeV')), #2.8%
3697     ('Chib1PToUpsilon1SGamma_MuFilter_TuneCP5_14TeV-pythia8_evtgen_cfi', UpgradeFragment(Kby(3600,36000),'Chib1PToUpsilon1SGamma_14TeV')), #2.8%
3698     ('ChicToJpsiGamma_MuFilter_TuneCP5_14TeV_pythia8_evtgen_cfi', UpgradeFragment(Kby(2000,20000),'ChicToJpsiGamma_14TeV')), #5%
3699     ('B0ToJpsiK0s_JMM_Filter_DGamma0_TuneCP5_13p6TeV-pythia8-evtgen_cfi',UpgradeFragment(Kby(18000,18000),'B0ToJpsiK0s_DGamma0_13p6TeV')), #2.7%
3700     ('DStarToD0Pi_D0ToKsPiPi_inclusive_SoftQCD_TuneCP5_13p6TeV-pythia8-evtgen',UpgradeFragment(Kby(38000,38000),'DStarToD0Pi_D0ToKsPiPi_13p6TeV')), #1.3%
3701     ('LbToJpsiLambda_JMM_Filter_DGamma0_TuneCP5_13p6TeV-pythia8-evtgen_cfi',UpgradeFragment(Mby(66,660000),'LbToJpsiLambda_DGamma0_13p6TeV')), #0.3%
3702     ('LbToJpsiXiK0sPi_JMM_Filter_DGamma0_TuneCP5_13p6TeV-pythia8-evtgen_cfi',UpgradeFragment(Mby(50,500000),'LbToJpsiXiK0sPr_DGamma0_13p6TeV')), #0.6%
3703     ('OmegaMinus_13p6TeV_SoftQCDInel_TuneCP5_cfi',UpgradeFragment(Mby(100,1000000),'OmegaMinus_13p6TeV')), #0.1%
3704     ('Hydjet_Quenched_MinBias_5020GeV_cfi', UpgradeFragment(U2000by1,'HydjetQMinBias_5020GeV')),
3705     ('Hydjet_Quenched_MinBias_5362GeV_cfi', UpgradeFragment(U2000by1,'HydjetQMinBias_5362GeV')),
3706     ('Hydjet_Quenched_MinBias_5519GeV_cfi', UpgradeFragment(U2000by1,'HydjetQMinBias_5519GeV')),
3707     ('SingleMuPt15Eta0_0p4_cfi', UpgradeFragment(Kby(9,100),'SingleMuPt15Eta0p_0p4')),
3708 ])