Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-07-09 05:00:03

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