-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGenesisOut.py
More file actions
157 lines (130 loc) · 5.49 KB
/
GenesisOut.py
File metadata and controls
157 lines (130 loc) · 5.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import h5py
import numpy as np
from IPython.display import HTML, display
import tabulate
class GenesisOut:
"""
Read output file of Genesis 1.3 Verison4. This is the main class used for postprocessing. Check result-*.ipynb for example use cases.
"""
def __init__(self, path):
#load file
self.filepath = path
self.filename = self.filepath.split('/')[-1]
self.file = h5py.File(self.filepath, 'r')
self.dict = {group:list(self.file[group].keys()) for group in self.file}
#constants
speed_of_light = 299792458.0 #m/s
h_eV_s = 4.135667516e-15 #eV s
#generate attributes
self.name_douplicate = ['xsize', 'ysize', 'xposition', 'yposition']
self.group_douplicate = ['Field', 'Beam']
self.generate_attributes()
#central frequency of the radiation
self.lambda_rad = self.lambda_rad()
#axis
self.s = self.s()
self.t = self.s/speed_of_light #time
self.dt = self('sample') * self('lambdaref')/ speed_of_light
#photon energy/spectrum
self.spec_i_near = self.spec_i('nearfield') #spectrum intensity
self.spec_p_near = self.spec_i_near**2 #spectrum power (magnitude squared)
self.spec_i_far = self.spec_i('farfield') #spectrum intensity
self.spec_p_far = self.spec_i_far**2 #spectrum power (magnitude squared)
#axis for spectrum
self.e0 = h_eV_s * speed_of_light / self.lambda_rad #resonant [eV]
self.freq_ev = np.fft.fftshift(h_eV_s * np.fft.fftfreq(len(self.s), self.dt) + self.e0, axes=0)
self.freq_lamd = h_eV_s * speed_of_light * 1e9 / self.freq_ev
#maximum power along z
self.power_z = np.max(self.power, 1)
#energy of the field
self.Field_energy = np.trapz(self.power, dx=self.dt)
#display
self.show_contents()
def __call__(self, *name):
"""
Able to call self(name)
(parent, child), or just (child), or (parent_child)
"""
#when only one input argument
if len(name)==1:
'''Find the parent name'''
#reject the douplicate names
if name[0] in self.name_douplicate:
print('Please put (group, parameter)')
return None
for group in self.file:
for param in self.file[group]:
if name[0] == param:
(parent, child) = (group, name[0])
#two input arguments
elif len(name)==2:
(parent, child) = name
if child == 'Version':
return {key:self.file['Meta']['Version'][key][()] for key in self.file['Meta']['Version'].keys()}
else:
parameter = self.file[parent][child][()]
if parameter.shape[0] == 1:
return parameter[0]
elif parameter.shape ==(1,1):
return parameter[0][0]
else:
return parameter
def generate_attributes(self):
"""
generate attributes in initial setting
"""
for group in self.dict:
for param in self.dict[group]:
if group in self.group_douplicate and param in self.name_douplicate:
setattr(self, group+'_'+param, self(group, param))
else:
setattr(self, param, self(group, param))
def s(self):
"""
get s axis
"""
(dim_z, dim_s) = self('power').shape
ds = self('sample')
sref = self('lambdaref')
return np.arange(dim_s) * ds *sref
def lambda_rad(self):
"""
returns central frequency of the radiation mode, which is lambda in the field section of the input file if specified, or lambda0(lambdaref) if not specified.
"""
InputFile = self('Meta','InputFile').decode("utf-8")
d_InputFile = dict([item.replace(' ','').split('=') for item in InputFile.splitlines() if '=' in item])
if 'lambda' in d_InputFile:
return float(d_InputFile['lambda'])
else:
return self.lambdaref
def spec_i(self, near_or_far = 'nearfield'):
"""
get spectrum intensity
"""
intensity = self('intensity-'+near_or_far)
phase = self('phase-'+near_or_far)
spec_i = abs(np.fft.fft(np.sqrt(np.array(intensity)) * np.exp(1.j * np.array(phase)), axis=1))
return np.fft.fftshift(spec_i, axes=1)
def show_info(self, group):
"""
Show the size of all the keys, and the value if the size is 1
"""
print(group)
for child in self.dict[group]:
if child=='Version':
print(child, ':', self(group, child))
elif not self(group, child).shape:
print(child, ':',self(group, child))
else:
print(child,': size', self(group, child).shape)
def show_contents(self):
"""
Show all the contents
"""
print(self.filename, 'loaded')
table = [['group', 'parameter']]
for group in self.file:
table.append([group, self.dict[group]])
display(HTML(tabulate.tabulate(table, tablefmt='html')))
print('Call directly as an attribute or call (parameter) or (group, parameter) to retrieve data')
print('Use .show_info(group) to show parameter shapes')