1
|
"""
|
2
|
Simulation with rectangular detector. Pilatus3-1M detector is used as an example.
|
3
|
Results will be compared against simulation with spherical detector.
|
4
|
"""
|
5
|
import numpy
|
6
|
import bornagain as ba
|
7
|
from bornagain import deg, angstrom, nm
|
8
|
import matplotlib
|
9
|
from matplotlib import pyplot as plt
|
10
|
|
11
|
detector_distance = 1000.0
|
12
|
pilatus_pixel_size = 0.172
|
13
|
pilatus_npx, pilatus_npy = 981, 1043
|
14
|
|
15
|
|
16
|
def get_sample():
|
17
|
"""
|
18
|
Returns a sample with cylindrical particles on a substrate.
|
19
|
"""
|
20
|
|
21
|
m_ambience = ba.HomogeneousMaterial("Air", 0.0, 0.0)
|
22
|
m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8)
|
23
|
m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8)
|
24
|
|
25
|
|
26
|
edge = 40*nm
|
27
|
ff = ba.FormFactorBox(edge, edge, edge)
|
28
|
cylinder = ba.Particle(m_particle, ff)
|
29
|
particle_layout = ba.ParticleLayout()
|
30
|
particle_layout.addParticle(cylinder, 1.0)
|
31
|
|
32
|
air_layer = ba.Layer(m_ambience)
|
33
|
air_layer.addLayout(particle_layout)
|
34
|
substrate_layer = ba.Layer(m_substrate)
|
35
|
|
36
|
multi_layer = ba.MultiLayer()
|
37
|
multi_layer.addLayer(air_layer)
|
38
|
multi_layer.addLayer(substrate_layer)
|
39
|
return multi_layer
|
40
|
|
41
|
|
42
|
def get_spherical_detector():
|
43
|
"""
|
44
|
Returns a spherical detector roughly approximating our PILATUS detector
|
45
|
"""
|
46
|
n_phi = pilatus_npx
|
47
|
n_alpha = pilatus_npy
|
48
|
width = pilatus_npx*pilatus_pixel_size
|
49
|
height = pilatus_npy*pilatus_pixel_size
|
50
|
phi_min = numpy.arctan(-width/2./detector_distance)
|
51
|
phi_max = numpy.arctan(width/2./detector_distance)
|
52
|
alpha_min = 0.0
|
53
|
alpha_max = numpy.arctan(height/detector_distance)
|
54
|
return ba.SphericalDetector(
|
55
|
n_phi, phi_min, phi_max, n_alpha, alpha_min, alpha_max)
|
56
|
|
57
|
|
58
|
def get_rectangular_detector():
|
59
|
"""
|
60
|
Returns a rectangular detector representing our PILATUS detector
|
61
|
"""
|
62
|
width = pilatus_npx*pilatus_pixel_size
|
63
|
height = pilatus_npy*pilatus_pixel_size
|
64
|
detector = ba.RectangularDetector(pilatus_npx, width, pilatus_npy, height)
|
65
|
detector.setPerpendicularToSampleX(detector_distance, width/2., 0.0)
|
66
|
return detector
|
67
|
|
68
|
|
69
|
def get_simulation():
|
70
|
"""
|
71
|
Return a GISAXS simulation with defined beam
|
72
|
"""
|
73
|
simulation = ba.GISASSimulation()
|
74
|
simulation.setBeamParameters(10*angstrom, 0.2*deg, 0.0*deg)
|
75
|
return simulation
|
76
|
|
77
|
|
78
|
def plot(results):
|
79
|
"""
|
80
|
Plots results of two simulations and their relative difference on one canvas
|
81
|
"""
|
82
|
from matplotlib import colors
|
83
|
fig = plt.figure(figsize=(13.6, 10.6))
|
84
|
|
85
|
|
86
|
plt.subplot(2, 3, 1)
|
87
|
ba.plot_colormap(results['spherical'], title="SphDet",
|
88
|
zlabel="")
|
89
|
|
90
|
|
91
|
plt.subplot(2, 3, 2)
|
92
|
ba.plot_colormap(results['rectangular'], title="RectDect",
|
93
|
zlabel="")
|
94
|
|
95
|
|
96
|
plt.subplot(2, 3, 3)
|
97
|
ba.plot_colormap(results['rectangular'], units=ba.AxesUnits.DEGREES, title="RectDect in DEGREES",
|
98
|
zlabel="")
|
99
|
|
100
|
|
101
|
plt.subplot(2, 3, 4)
|
102
|
ba.plot_colormap(results['rec_roi'], title="RectDet + ROI",
|
103
|
zlabel="")
|
104
|
|
105
|
plt.subplot(2, 3, 5)
|
106
|
ba.plot_colormap(results['rec_roi'], units=ba.AxesUnits.DEGREES, title="RectDet + ROI in DEGREES",
|
107
|
zlabel="")
|
108
|
|
109
|
plt.subplots_adjust(left=0.05, right=0.92, top=0.88, bottom=0.12)
|
110
|
plt.tight_layout()
|
111
|
|
112
|
plt.show()
|
113
|
|
114
|
|
115
|
def run_simulation():
|
116
|
"""
|
117
|
Run two simulations for two different detectors and plot results
|
118
|
"""
|
119
|
results = {}
|
120
|
|
121
|
sample = get_sample()
|
122
|
simulation = get_simulation()
|
123
|
simulation.setSample(sample)
|
124
|
|
125
|
|
126
|
simulation.setDetector(get_spherical_detector())
|
127
|
simulation.runSimulation()
|
128
|
results['spherical'] = simulation.result()
|
129
|
|
130
|
|
131
|
simulation.setDetector(get_rectangular_detector())
|
132
|
simulation.runSimulation()
|
133
|
results['rectangular'] = simulation.result()
|
134
|
|
135
|
|
136
|
simulation.setRegionOfInterest(80.0, 10.0, 120.0, 30.0)
|
137
|
simulation.runSimulation()
|
138
|
results['rec_roi'] = simulation.result()
|
139
|
|
140
|
|
141
|
return results
|
142
|
|
143
|
|
144
|
if __name__ == '__main__':
|
145
|
results = run_simulation()
|
146
|
plot(results)
|