Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:03:40

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