Separate Scripts for the Snakemake Workflow
Separate Scripts for the Snakemake Workflow#
For completeness, we here provide the separate analysis scripts called by the snakemake workflow. Existing scripts can be implemented with the script: directive in the snakefile with minimal adaptations. The input and output file paths, as well as the parameters for the corresponding rule can be retrieved in the scripts with snakemake.input, snakemake.output and snakemake.params.
1# @cond
2import uproot
3import matplotlib.pyplot as plt
4
5output_file = {"Mbc": snakemake.output.mbc_plot, "deltaE": snakemake.output.deltaE_plot}
6BBdata = snakemake.input.data_BB
7QQdata = snakemake.input.data_QQ
8
9treeName = 'BtoPiDtoKPiPi'
10some_variables = ["Mbc", "deltaE"]
11BBtuple = uproot.open(f"{BBdata}:{treeName}")
12QQtuple = uproot.open(f"{QQdata}:{treeName}")
13
14for var in some_variables:
15 plt.hist([QQtuple[var].array(), BBtuple[var].array()], label=["uudd Continuum", "mixed B mesons"], stacked=True)
16 plt.legend(loc='best')
17 plt.xlabel(f"{var} [GeV]")
18 plt.savefig(output_file[var], dpi=100)
19 plt.close()
20# @endcond
1# @cond
2import json
3import basf2 as b2
4import modularAnalysis as ma
5import vertex as vx
6
7runningOnMC = snakemake.params.runningOnMC
8
9inputjson = snakemake.input.inputfileList
10outname = snakemake.output[0]
11
12mypath = b2.create_path()
13with open(inputjson) as f:
14 inputMdstList = json.load(f)
15
16ma.inputMdstList(filelist=inputMdstList, path=mypath)
17
18ma.fillParticleList(decayString='K+:my', cut="dr < 0.5 and abs(dz) < 3 and thetaInCDCAcceptance and kaonID > 0.01", path=mypath)
19ma.fillParticleList(decayString='pi+:my', cut="dr < 0.5 and abs(dz) < 3 and thetaInCDCAcceptance", path=mypath)
20
21ma.reconstructDecay(decayString="D-:K2Pi -> K+:my pi-:my pi-:my", cut="1.844 < M < 1.894", path=mypath)
22
23ma.reconstructDecay(decayString='B0:PiD-toK2Pi -> D-:K2Pi pi+:my', cut='5.0 < Mbc and abs(deltaE) < 1.0', path=mypath)
24vx.treeFit('B0:PiD-toK2Pi', 0, path=mypath, updateAllDaughters=False, ipConstraint=True, massConstraint=[411])
25
26if(runningOnMC):
27 ma.matchMCTruth(list_name='B0:PiD-toK2Pi', path=mypath)
28
29some_variables = ['Mbc', 'deltaE']
30ma.variablesToNtuple(decayString='B0:PiD-toK2Pi', variables=some_variables,
31 filename=outname, path=mypath, treename='BtoPiDtoKPiPi')
32
33b2.process(mypath)
34# @endcond
1# @cond
2import json
3skimfiles = json.loads(open(snakemake.input.skim_dirs, "r").read())
4outputfiles = snakemake.output
5BatchesPerSkim = snakemake.params.BatchesPerSkim
6
7binwidth = int(len(skimfiles)/BatchesPerSkim)
8if(binwidth < 1.):
9 raise ValueError("Attempting to batching with binwidth smaller 1. Decrease the number of batches!")
10
11batches = {}
12for batch in range(BatchesPerSkim):
13 if(batch == BatchesPerSkim - 1):
14 batches.update({outputfiles[batch]: list(skimfiles[binwidth*batch:])})
15 else:
16 batches.update({outputfiles[batch]: list(skimfiles[binwidth*batch:binwidth*(batch+1)])})
17
18for key, file_list in batches.items():
19 with open(key, "w") as f:
20 f.write(json.dumps(file_list))
21# @endcond
When using our provided wrapper: for submitting gbasf2 jobs to the grid, the steering file does not need any specific adaptations.
1# @cond
2import basf2 as b2
3import modularAnalysis as ma
4import vertex as vx
5from extravariables import runningOnMC, outputfile
6import udst
7
8gbasf2_dataset = [] # gbasf2 will figure this out
9
10mypath = b2.create_path()
11ma.inputMdstList(filelist=gbasf2_dataset, path=mypath, entrySequences=['0:10'])
12
13ma.fillParticleList(decayString='K+:my', cut="dr < 0.5 and abs(dz) < 3 and thetaInCDCAcceptance and kaonID > 0.01", path=mypath)
14ma.fillParticleList(decayString='pi+:my', cut="dr < 0.5 and abs(dz) < 3 and thetaInCDCAcceptance", path=mypath)
15
16ma.reconstructDecay(decayString="D-:K2Pi -> K+:my pi-:my pi-:my", cut="1.5 < M < 2.2", path=mypath)
17
18ma.reconstructDecay(decayString='B0:PiD-toK2Pi -> D-:K2Pi pi+:my', cut='5.0 < Mbc and abs(deltaE) < 1.0', path=mypath)
19vx.treeFit('B0:PiD-toK2Pi', 0, path=mypath, updateAllDaughters=False, ipConstraint=True, massConstraint=[411])
20ma.applyCuts('B0:PiD-toK2Pi', '5.2 < Mbc and abs(deltaE) < 0.5', path=mypath)
21
22# dump in UDST format
23udst.add_skimmed_udst_output(
24 mypath,
25 skimDecayMode='BtoPiD',
26 skimParticleLists=['B0:PiD-toK2Pi'],
27 mc=runningOnMC,
28 outputFile=outputfile)
29b2.process(mypath)
30print(b2.statistics)
31# @endcond