Skip to content

Commit 9c493c8

Browse files
committed
added a soft drop multiplicity plotting script, and added option for different y-axis on the lund images
1 parent 3b26f45 commit 9c493c8

File tree

8 files changed

+221
-43
lines changed

8 files changed

+221
-43
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# This file is part of gLund by S. Carrazza and F. A. Dreyer
2+
import matplotlib.pyplot as plt
3+
from glund.read_data import Jets
4+
from glund.JetTree import JetTree, LundImage, SoftDropMult
5+
from mpl_toolkits.axes_grid1 import make_axes_locatable
6+
from scipy.interpolate import interp2d
7+
import numpy as np
8+
import argparse,math
9+
10+
def n_sd(image, xbins, ybins, beta, zcut, thetacut, R0=1.0):
11+
"""The soft drop multiplicity of an image. Assumes y-axis=kappa"""
12+
nsd=0
13+
dx=xbins[1]-xbins[0]
14+
dy=ybins[1]-ybins[0]
15+
for ix in range(image.shape[0]):
16+
for iy in range(image.shape[1]):
17+
if (image[ix,iy]>0.0):
18+
delta = np.exp(xbins[ix]+np.random.uniform(-dx/2,dx/2))
19+
z = np.exp(ybins[iy]+np.random.uniform(-dy/2,dy/2))/delta
20+
if (delta > thetacut and z > zcut * ((delta/R0)**beta)):
21+
nsd+=1
22+
return nsd
23+
24+
#----------------------------------------------------------------------
25+
def plot_sdmult(filedic, imgs_ref, figname, nsd_ref, npx=24, zcut=0.007, beta=-1, thetacut=0.0):
26+
"""Plot a slice in kt of the lund image for different models and a reference sample."""
27+
xvals=np.linspace(LundImage.xval[0], LundImage.xval[1], npx+1)
28+
yvals=np.linspace(LundImage.yval[0], LundImage.yval[1], npx+1)
29+
xbins=np.array([0.5*(xvals[i]+xvals[i+1]) for i in range(len(xvals)-1)])
30+
ybins=np.array([0.5*(yvals[i]+yvals[i+1]) for i in range(len(yvals)-1)])
31+
32+
yy=np.linspace(LundImage.yval[0], LundImage.yval[1], 10000)
33+
xx=np.linspace(LundImage.xval[0], LundImage.xval[1], 10000)
34+
35+
fct= {}
36+
nsd= {}
37+
for lab in filedic.keys():
38+
ims = np.load(filedic[lab])
39+
im = np.average(ims, axis=0)
40+
f = interp2d(xbins, ybins, im, kind='linear') #linear, cubic, quintic
41+
fct[lab] = f
42+
nsd[lab]=[]
43+
for i in range(ims.shape[0]):
44+
nsd[lab].append(n_sd(ims[i], xbins, ybins, beta, zcut, thetacut))
45+
46+
nsd_ref_im = []
47+
for i in range(len(imgs_ref)):
48+
nsd_ref_im.append(n_sd(imgs_ref[i], xbins, ybins, beta, zcut, thetacut))
49+
50+
fig, ax = plt.subplots(figsize=(5,3.5))
51+
bins = np.arange(0, 25, 1)
52+
for lab in nsd.keys():
53+
plt.hist(nsd[lab], bins=bins, histtype='step', density=True, label=lab)
54+
plt.hist(nsd_ref_im, bins=bins, histtype='step', density=True, label='Pythia 8')
55+
plt.hist(nsd_ref, bins=bins, histtype='step', color='C3', ls=':', density=True)
56+
plt.text(0.4,0.275,'$z_\mathrm{cut}=%.3f,\, \\beta=%i,\, \\theta_\mathrm{cut}=%.1f$' % (zcut,beta,thetacut))
57+
ax.set_xlim((0,12))
58+
ax.set_ylim((0.0,0.30))
59+
ax.set_xlabel('$n_\mathrm{SD}$')
60+
plt.legend()
61+
ax.grid(linestyle=':')
62+
plt.savefig(figname, bbox_inches='tight')
63+
plt.close()
64+
65+
#----------------------------------------------------------------------
66+
def main(args):
67+
zcut=0.007
68+
beta=-1
69+
thetacut=0.0009
70+
if args.data:
71+
sdmult=SoftDropMult(zcut=zcut, beta=beta, thetacut=thetacut)
72+
reader=Jets(args.data, args.nev)
73+
events=reader.values()
74+
imgs_ref=np.zeros((len(events), args.npx, args.npx))
75+
li_gen=LundImage(npxlx = args.npx, y_axis=args.yaxis)
76+
nsd_ref=[]
77+
for i, jet in enumerate(events):
78+
tree = JetTree(jet)
79+
nsd_ref.append(sdmult(tree))
80+
imgs_ref[i]=li_gen(tree)
81+
imgref=np.average(imgs_ref,axis=0)
82+
else:
83+
imgref=None
84+
folder = args.output.strip('/')+'/' if args.output else ''
85+
86+
assert(len(args.label_data_pairs)%2==0)
87+
filedic={}
88+
for i in range(0,len(args.label_data_pairs),2):
89+
lab=args.label_data_pairs[i]
90+
filedic[lab] = args.label_data_pairs[i+1]
91+
92+
print('Plotting soft drop multiplicity')
93+
plot_sdmult(filedic, imgs_ref, folder+'softdropmult.pdf', nsd_ref, npx=args.npx,
94+
zcut=zcut, beta=beta, thetacut=thetacut)
95+
96+
#----------------------------------------------------------------------
97+
if __name__ == "__main__":
98+
parser = argparse.ArgumentParser(description='Plot a kt and delta slice.')
99+
parser.add_argument('--data', type=str, help='The reference data file')
100+
parser.add_argument('--output', type=str, default='', help='Output folder')
101+
parser.add_argument('--npx',type=int, default=24, help='Pixel number')
102+
parser.add_argument('--nev',type=int, default=-1, help='Pixel number')
103+
parser.add_argument('label_data_pairs', type=str, nargs='+',
104+
help='List of label and generated data files.')
105+
parser.add_argument('--y-axis', type=str, dest='yaxis', help='Type of y axis')
106+
args = parser.parse_args()
107+
main(args)

scripts/plotting/plot_slices.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ def plot_slice_kt(filedic, imgref, figname, npx=24):
3737
img = {}
3838
for lab in filedic.keys():
3939
img[lab] = np.average(np.load(filedic[lab]), axis=0)
40-
yvals=np.linspace(-3, 7, npx+1)
41-
xvals=np.linspace(0, 7, npx+1)
40+
yvals=np.linspace(LundImage.yval[0], LundImage.yval[1], npx+1)
41+
xvals=np.linspace(LundImage.xval[0], LundImage.xval[1], npx+1)
4242

4343
# get kt slice. This is tuned for 24 pixel images
4444
kt_min = math.exp(yvals[12])
@@ -84,8 +84,8 @@ def plot_slice_delta(filedic, imgref, figname, npx=24):
8484
img = {}
8585
for lab in filedic.keys():
8686
img[lab] = np.average(np.load(filedic[lab]), axis=0)
87-
xvals=np.linspace(0, 7, npx+1)
88-
yvals=np.linspace(-3, 7, npx+1)
87+
xvals=np.linspace(LundImage.xval[0], LundImage.xval[1], npx+1)
88+
yvals=np.linspace(LundImage.yval[0], LundImage.yval[1], npx+1)
8989

9090
# get delta R slice. This is tuned for 24 pixel images
9191
delta_max = math.exp(-xvals[4])
@@ -131,8 +131,8 @@ def plot_slice_kt_noratio(filedic, figname, npx=24):
131131
img = {}
132132
for lab in filedic.keys():
133133
img[lab] = np.average(np.load(filedic[lab]), axis=0)
134-
yvals=np.linspace(-3, 7, npx+1)
135-
xvals=np.linspace(0, 7, npx+1)
134+
xvals=np.linspace(LundImage.xval[0], LundImage.xval[1], npx+1)
135+
yvals=np.linspace(LundImage.yval[0], LundImage.yval[1], npx+1)
136136

137137
# get kt slice. This is tuned for 24 pixel images
138138
kt_min = math.exp(yvals[12])
@@ -160,8 +160,8 @@ def plot_slice_delta_noratio(filedic, figname, npx=24):
160160
img = {}
161161
for lab in filedic.keys():
162162
img[lab] = np.average(np.load(filedic[lab]), axis=0)
163-
xvals=np.linspace(0, 7, npx+1)
164-
yvals=np.linspace(-3, 7, npx+1)
163+
xvals=np.linspace(LundImage.xval[0], LundImage.xval[1], npx+1)
164+
yvals=np.linspace(LundImage.yval[0], LundImage.yval[1], npx+1)
165165

166166
# get delta R slice. This is tuned for 24 pixel images
167167
delta_max = math.exp(-xvals[4])
@@ -189,7 +189,7 @@ def main(args):
189189
reader=Jets(args.data, args.nev)
190190
events=reader.values()
191191
imgs_ref=np.zeros((len(events), args.npx, args.npx))
192-
li_gen=LundImage(npxlx = args.npx)
192+
li_gen=LundImage(npxlx = args.npx, y_axis=args.yaxis)
193193
for i, jet in enumerate(events):
194194
tree = JetTree(jet)
195195
imgs_ref[i]=li_gen(tree)
@@ -223,5 +223,6 @@ def main(args):
223223
parser.add_argument('--nev',type=int, default=-1, help='Pixel number')
224224
parser.add_argument('label_data_pairs', type=str, nargs='+',
225225
help='List of label and generated data files.')
226+
parser.add_argument('--y-axis', type=str, dest='yaxis', help='Type of y axis')
226227
args = parser.parse_args()
227228
main(args)

scripts/testing/glund_plot_samples.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
def main(args):
1111
if args.reference:
1212
figname=args.data.split(os.extsep)[0]+'.pdf'
13-
plot_lund_with_ref(args.data, args.reference, figname)
13+
plot_lund_with_ref(args.data, args.reference, figname, y_axis=args.yaxis)
1414
else:
1515
figname=args.data.split(os.extsep)[0]+'.pdf'
1616
plot_lund(args.data, figname)
@@ -22,6 +22,7 @@ def main(args):
2222
parser = argparse.ArgumentParser(description='Plot a model.')
2323
parser.add_argument('--data', type=str, required=True, help='Generated images')
2424
parser.add_argument('--reference', type=str, default=None, help='Pythia reference')
25+
parser.add_argument('--y-axis', type=str, dest='yaxis', help='Type of y axis')
2526
args = parser.parse_args()
2627

2728

scripts/testing/glund_test_encoding.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def main(args):
2929
reader=Jets(args.data, args.nev)
3030
events=reader.values()
3131
img_train=np.zeros((len(events), args.npx, args.npx, 1))
32-
li_gen=LundImage(npxlx = args.npx)
32+
li_gen=LundImage(npxlx = args.npx, y_axis=args.yaxis)
3333
for i, jet in enumerate(events):
3434
tree = JetTree(jet)
3535
img_train[i]=li_gen(tree).reshape(args.npx, args.npx, 1)
@@ -118,6 +118,7 @@ def main(args):
118118
parser.add_argument('--zca', action='store_true', help='Perform ZCA.')
119119
parser.add_argument('--autoencoder', action='store',const=200, default=None,
120120
nargs='?', type=int, help='Perform autoencoding')
121+
parser.add_argument('--y-axis', type=str, dest='yaxis', help='Type of y axis')
121122
args = parser.parse_args()
122123

123124
main(args)

src/glund/JetTree.py

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ def __init__(self, j1, j2):
1818
self.lnKt = math.log(j2.pt()*delta)
1919
self.lnDelta = math.log(delta)
2020
# self.lnm = 0.5*math.log(abs((j1 + j2).m2()))
21-
# self.lnz = math.log(z)
22-
# self.lnKappa = math.log(z * delta)
21+
self.lnz = math.log(z)
22+
self.lnKappa = math.log(z * delta)
2323
# self.psi = math.atan((j1.rap() - j2.rap())/(j1.phi() - j2.phi()))
2424

2525

@@ -63,9 +63,15 @@ def jet(self, pseudojet=False):
6363
class LundImage:
6464
"""Class to create Lund images from a jet tree."""
6565

66+
xval = [0.0, 7.0]
67+
yval = [-3.0, 7.0]
68+
69+
__yval_kt = [-3.0, 7.0]
70+
__yval_z = [-8.0, 0.0]
71+
6672
#----------------------------------------------------------------------
67-
def __init__(self, xval = [0.0, 7.0], yval = [-3.0, 7.0],
68-
npxlx = 50, npxly = None, norm_to_one = True):
73+
def __init__(self, xval = None, yval = None, npxlx = 50, npxly = None,
74+
norm_to_one = True, y_axis = 'kt'):
6975
"""Set up the LundImage instance."""
7076
# set up the pixel numbers
7177
self.npxlx = npxlx
@@ -76,10 +82,24 @@ def __init__(self, xval = [0.0, 7.0], yval = [-3.0, 7.0],
7682
# set a flag which determines if pixels are normalized to one or not
7783
self.norm_to_one = norm_to_one
7884
# set up the bin edge and width
79-
self.xmin = xval[0]
80-
self.ymin = yval[0]
81-
self.x_pxl_wdth = (xval[1] - xval[0])/self.npxlx
82-
self.y_pxl_wdth = (yval[1] - yval[0])/self.npxly
85+
LundImage.change_ybox(y_axis)
86+
xv = xval if xval else LundImage.xval
87+
yv = yval if yval else LundImage.yval
88+
self.xmin = xv[0]
89+
self.ymin = yv[0]
90+
self.x_pxl_wdth = (xv[1] - xv[0])/self.npxlx
91+
self.y_pxl_wdth = (yv[1] - yv[0])/self.npxly
92+
self.y_axis = y_axis
93+
94+
#----------------------------------------------------------------------
95+
@staticmethod
96+
def change_ybox(y_axis):
97+
if y_axis=='kt':
98+
LundImage.yval = LundImage.__yval_kt
99+
elif y_axis=='z' or y_axis=='kappa':
100+
LundImage.yval = LundImage.__yval_z
101+
else:
102+
raise ValueError("LundImage: invalid y_axis.")
83103

84104
#----------------------------------------------------------------------
85105
def __call__(self, tree):
@@ -93,7 +113,14 @@ def fill(self, tree, res):
93113
"""Fill the res array recursively with the tree declusterings of the hard branch."""
94114
if(tree and tree.lundCoord):
95115
x = -tree.lundCoord.lnDelta
96-
y = tree.lundCoord.lnKt
116+
if self.y_axis=='kt':
117+
y = tree.lundCoord.lnKt
118+
if self.y_axis=='z':
119+
y = tree.lundCoord.lnz
120+
elif self.y_axis=='kappa':
121+
y = tree.lundCoord.lnKappa
122+
else:
123+
raise ValueError("LundImage: invalid y_axis.")
97124
xind = math.ceil((x - self.xmin)/self.x_pxl_wdth - 1.0)
98125
yind = math.ceil((y - self.ymin)/self.y_pxl_wdth - 1.0)
99126
if (xind < self.npxlx and yind < self.npxly and min(xind,yind) >= 0):
@@ -102,3 +129,35 @@ def fill(self, tree, res):
102129
self.fill(tree.harder, res)
103130
#self.fill(tree.softer, res)
104131

132+
133+
#======================================================================
134+
class SoftDropMult:
135+
"""Class to compute the soft drop multiplicity of a jet."""
136+
137+
#----------------------------------------------------------------------
138+
def __init__(self, zcut = 0.007, beta=-1, thetacut=0, R0=1):
139+
"""Set up the LundImage instance."""
140+
self.zcut=zcut
141+
self.beta=beta
142+
self.thetacut=thetacut
143+
self.R0=R0
144+
145+
#----------------------------------------------------------------------
146+
def __call__(self, tree):
147+
"""Process a jet tree and return the soft drop multiplicity."""
148+
nsd = 0
149+
return self.fill(tree, nsd)
150+
151+
#----------------------------------------------------------------------
152+
def fill(self, tree, nsd):
153+
"""Fill the res array recursively with the tree declusterings of the hard branch."""
154+
if(tree and tree.lundCoord):
155+
delta = math.exp(tree.lundCoord.lnDelta)
156+
#z = math.exp(tree.lundCoord.lnz)
157+
z = np.exp(tree.lundCoord.lnKappa)/delta
158+
if (delta > self.thetacut and z > self.zcut * ((delta/self.R0)**self.beta)):
159+
return self.fill(tree.harder, nsd+1)
160+
else:
161+
return self.fill(tree.harder, nsd)
162+
return nsd
163+

src/glund/plotting.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@
66
import numpy as np
77
from matplotlib.backends.backend_pdf import PdfPages
88

9-
10-
xval = [0.0, 7.0]
11-
yval = [-3.0, 7.0]
12-
139
#----------------------------------------------------------------------
1410
def plot_lund(filename, figname):
1511
"""Plot a few samples of lund images as well as the average density."""
@@ -34,7 +30,7 @@ def plot_lund(filename, figname):
3430

3531

3632
#----------------------------------------------------------------------
37-
def plot_lund_with_ref(filename, reference, figname):
33+
def plot_lund_with_ref(filename, reference, figname, y_axis='kt'):
3834
"""Plot a samples of lund images and the average density along with reference data."""
3935
r, c = 5, 5
4036
imgs = np.load(filename)
@@ -51,7 +47,8 @@ def plot_lund_with_ref(filename, reference, figname):
5147
reader=Jets(reference, imgs.shape[0])
5248
events=reader.values()
5349
imgs_ref=np.zeros((len(events), imgs.shape[1], imgs.shape[2]))
54-
li_gen=LundImage(npxlx = imgs.shape[1], npxly = imgs.shape[2])
50+
li_gen=LundImage(npxlx = imgs.shape[1], npxly = imgs.shape[2],
51+
y_axis = y_axis)
5552
for i, jet in enumerate(events):
5653
tree = JetTree(jet)
5754
imgs_ref[i]=li_gen(tree).reshape(imgs.shape[1], imgs.shape[2])
@@ -81,7 +78,8 @@ def plot_lund_with_ref(filename, reference, figname):
8178
cbartics = [0, 0.05, 0.1, 0.15, 0.2, 0.25]
8279
plt.title('generated')
8380
plt.imshow(np.average(imgs,axis=0).transpose(), origin='lower',vmin=0.0,vmax=0.2,
84-
aspect='auto', extent=[xval[0], xval[1], yval[0], yval[1]])
81+
aspect='auto', extent=[LundImage.xval[0], LundImage.xval[1],
82+
LundImage.yval[0], LundImage.yval[1]])
8583
plt.colorbar(orientation='vertical', label=r'$\rho$', ticks=cbartics)
8684
plt.xlabel('$\ln(1 / \Delta_{ab})$')
8785
plt.ylabel('$\ln(k_{t} / \mathrm{GeV})$')
@@ -90,7 +88,8 @@ def plot_lund_with_ref(filename, reference, figname):
9088
fig=plt.figure(figsize=(6,6))
9189
plt.title('reference')
9290
plt.imshow(np.average(imgs_ref,axis=0).transpose(), origin='lower',vmin=0.0, vmax=0.2,
93-
aspect='auto', extent=[xval[0], xval[1], yval[0], yval[1]])
91+
aspect='auto', extent=[LundImage.xval[0], LundImage.xval[1],
92+
LundImage.yval[0], LundImage.yval[1]])
9493
plt.colorbar(orientation='vertical', label=r'$\rho$', ticks=cbartics)
9594
plt.xlabel('$\ln(1 / \Delta_{ab})$')
9695
plt.ylabel('$\ln(k_{t} / \mathrm{GeV})$')
@@ -100,7 +99,8 @@ def plot_lund_with_ref(filename, reference, figname):
10099
plt.title('generated/reference')
101100
plt.imshow(np.divide(np.average(imgs,axis=0).transpose(), np.average(imgs_ref,axis=0).transpose()),
102101
origin='lower', vmin=0.5, vmax=1.5, cmap=cm.seismic,
103-
aspect='auto', extent=[xval[0], xval[1], yval[0], yval[1]])
102+
aspect='auto', extent=[LundImage.xval[0], LundImage.xval[1],
103+
LundImage.yval[0], LundImage.yval[1]])
104104
plt.colorbar(orientation='vertical')
105105
plt.xlabel('$\ln(1 / \Delta_{ab})$')
106106
plt.ylabel('$\ln(k_{t} / \mathrm{GeV})$')

src/glund/scripts/glund.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def run_hyperparameter_scan(search_space, max_evals, cluster, folder):
4242
def load_yaml(runcard_file):
4343
"""Loads yaml runcard"""
4444
with open(runcard_file, 'r') as stream:
45-
runcard = yaml.load(stream)
45+
runcard = yaml.load(stream, Loader=yaml.FullLoader)
4646
for key, value in runcard.items():
4747
if 'hp.' in str(value):
4848
runcard[key] = eval(value)
@@ -77,7 +77,8 @@ def build_and_train_model(setup):
7777
reader=Jets(setup['data'], setup['nev'])
7878
events=reader.values()
7979
img_data=np.zeros((len(events), setup['npx'], setup['npx'], 1))
80-
li_gen=LundImage(npxlx = setup['npx'])
80+
li_gen=LundImage(npxlx = setup['npx'],
81+
y_axis = setup['y_axis'] if 'y_axis' in setup else 'kt')
8182
for i, jet in enumerate(events):
8283
tree = JetTree(jet)
8384
img_data[i]=li_gen(tree).reshape(setup['npx'], setup['npx'], 1)
@@ -197,4 +198,5 @@ def main():
197198
np.save(genfn, gen_sample)
198199

199200
if args.plot_samples:
200-
plot_lund_with_ref(f'{genfn}.npy', setup['data'], f'{genfn}.pdf')
201+
plot_lund_with_ref(f'{genfn}.npy', setup['data'], f'{genfn}.pdf',
202+
y_axis = setup['y_axis'] if 'y_axis' in setup else 'kt')

0 commit comments

Comments
 (0)