Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-12-07 02:27:31

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