-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.py
144 lines (110 loc) · 4.1 KB
/
main.py
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
import os
import sys
import h5py
import click
import json
try:
import cupy as np
except ImportError:
import numpy as np
from hipgisaxs import Unitcell
from hipgisaxs.fresnel import propagation_coeffs
from hipgisaxs.structure_factor import structure_factor
from hipgisaxs.detector import Detector
def build_instrument(instrument_file):
with open(instrument_file, 'r') as fp:
instrument_dict = json.load(instrument_file)
instrument = Instrument(**instrument_dict) # TODO: implement Instrument as a NamedTuple or similar
return instrument
def build_sample(sample_file):
with open(sample_file, 'r') as fp:
sample_dict = json.load(sample_file)
sample = Sample(**sample_dict) # TODO: implement Sample as a NamedTuple or similar
return sample
def build_output(output_file):
with open(output_file, 'r') as fp:
output_dict = json.load(output_file)
output = Output(**output_dict) # TODO: implement Output as a NamedTuple or similar
return output
def setup_experiment(instrument, sample, output):
# pass in either instrument object or instrument file
if isinstance(instrument, str):
instrument = build_instrument(instrument)
... # same for sample, output
experiment = Experiment(instrument, sample, output)
return experiment
# TODO: consider adding a console_scripts entrypoint to setup.py
@click.command()
@click.argument('instrument')
@click.argument('sample')
@click.argument('output')
def run_experiment(instrument, sample, output):
# pass in either instrument object or instrument file
experiment = setup_experiment(instrument, sample, output)
data = experiment.run(...)
return data
if __name__ == '__main__':
# load instrumentation specs
if len(sys.argv) == 2:
if os.path.isdir(sys.argv[1]):
input_sdir = sys.argv[1]
elif len(sys.argv):
if os.path.isdir('json'):
input_sdir = 'json'
# read configurations
instrument_config = os.path.join(input_sdir, 'instrument.json')
if not os.path.isfile(instrument_config):
raise OSError('experiment config. not found.')
with open(instrument_config) as fp:
cfg = json.load(fp)
# load sample description
sample_config = os.path.join(input_sdir, 'sample.json')
if not os.path.isfile(sample_config):
raise OSError('sample file not found')
with open(sample_config) as fp:
sample = json.load(fp)
# output
output_config = os.path.join(input_sdir, 'output.json')
if not os.path.isfile(output_config):
raise OSError('outout config not found')
with open(output_config) as fp:
output = json.load(fp)
alphai = cfg['incident_angle'] * np.pi / 180
sdd = cfg['sdd']
energy = cfg['energy']
detector = Detector.from_dict(cfg['detector'])
beam_center = cfg['beam_center']
# substrate
substrate = sample['substrate']
reflectivity_index = complex(substrate['delta'], substrate['beta'])
# sample
unitcell = Unitcell(sample['unitcell'])
theta, alpha = detector.angles(sdd, beam_center)
qx, qy, qz = detector.dwba_qvectors(sdd, beam_center, energy, alphai)
propagation = propagation_coeffs(alphai, alpha.ravel(), reflectivity_index)
# struture factor
dspacing = np.array([[200, 0, 0], [0, 200, 0], [0, 0, 1]])
repeats = np.array([500, 500, 1])
# DWBA
scat = np.zeros_like(qx, dtype=complex)
for j in range(4):
ff = unitcell.ff(qx, qy, qz[j])
sf = structure_factor(qx, qy, qz[j], dspacing, repeats)
scat += propagation[j] * sf * ff
# compute intensity
img = np.abs(scat.reshape(detector.shape)) ** 2
# if we have cupy, transfer to numpy
if np.__name__ == 'cupy':
img = img.get()
# write to hdf5
fname = output['filename']
fp = h5py.File(fname, 'w')
dsetname = output['dataset']
dset = fp.create_dataset(dsetname, data=img)
qp = np.sign(qy) * np.sqrt(qx ** 2 + qy ** 2)
qv = qz[0]
if np.__name__ == 'cupy':
qp = qp.get()
qv = qv.get()
dset.attrs['qlims'] = [qp.min(), qp.max(), qv.min(), qv.max()]
fp.close()