Skip to content

Commit eca4561

Browse files
jokasimrnvaytet
andauthored
Add illustration of inhomogeneity from absorption (#113)
* add illustration of inhomogeneity from absorption * fix: move visualization to separate notebook * fix: text in notebook * docs: add to index * docs: change title and add disk section * fix * Update docs/user-guide/dream/dream-visualize-absorption.ipynb Co-authored-by: Neil Vaytet <[email protected]> * Update docs/user-guide/dream/dream-visualize-absorption.ipynb Co-authored-by: Neil Vaytet <[email protected]> * Update docs/user-guide/dream/dream-visualize-absorption.ipynb Co-authored-by: Neil Vaytet <[email protected]> * Update docs/user-guide/dream/dream-visualize-absorption.ipynb Co-authored-by: Neil Vaytet <[email protected]> * fix: add missing module to docs * fix: remove camera import --------- Co-authored-by: Neil Vaytet <[email protected]>
1 parent 646574e commit eca4561

File tree

3 files changed

+227
-0
lines changed

3 files changed

+227
-0
lines changed

docs/api-reference/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
filtering
2727
grouping
2828
smoothing
29+
transform
2930
types
3031
```
3132

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "0",
6+
"metadata": {},
7+
"source": [
8+
"# Visualize effect of absorption\n",
9+
"\n",
10+
"This notebook is an example of how to use the `compute_transmission_map` function to visualize the effect of (sample) absorption on the intensity in the detector.\n",
11+
"\n",
12+
"Note that the `compute_transmission_map` function only accounts for the effect of absorption. The measured intensity in the detector can also be impacted by other effects, such as the effect of the solid angle being different for different detector pixels.\n",
13+
"\n",
14+
"For more details, see https://scipp.github.io/scippneutron/user-guide/absorption-correction.html."
15+
]
16+
},
17+
{
18+
"cell_type": "code",
19+
"execution_count": null,
20+
"id": "1",
21+
"metadata": {},
22+
"outputs": [],
23+
"source": [
24+
"import scipp as sc\n",
25+
"\n",
26+
"from ess import dream\n",
27+
"import ess.dream.data # noqa: F401\n",
28+
"\n",
29+
"from scippneutron.absorption import compute_transmission_map\n",
30+
"from scippneutron.absorption.cylinder import Cylinder\n",
31+
"from scippneutron.absorption.material import Material\n",
32+
"from scippneutron.atoms import ScatteringParams"
33+
]
34+
},
35+
{
36+
"cell_type": "markdown",
37+
"id": "2",
38+
"metadata": {},
39+
"source": [
40+
"## Load the data\n",
41+
"\n",
42+
"We load a dataset from a Geant4 simulation only to get access to the detector geometry."
43+
]
44+
},
45+
{
46+
"cell_type": "code",
47+
"execution_count": null,
48+
"id": "3",
49+
"metadata": {},
50+
"outputs": [],
51+
"source": [
52+
"dg = dream.io.load_geant4_csv(dream.data.get_path(\"data_dream0_new_hkl_Si_pwd.csv.zip\"))[\"instrument\"]\n",
53+
"dg = sc.DataGroup({key: detector[\"events\"][\"counter\", 0] for key, detector in dg.items()})\n",
54+
"dg.keys()"
55+
]
56+
},
57+
{
58+
"cell_type": "markdown",
59+
"id": "4",
60+
"metadata": {},
61+
"source": [
62+
"## Inhomogeneity from absorption in mantle detector\n",
63+
"\n",
64+
"If the sample absorbs or scatters a large fraction of the incoming neutrons, the intensity in the detector will vary even if the scattering is inhomogeneous.\n"
65+
]
66+
},
67+
{
68+
"cell_type": "markdown",
69+
"id": "5",
70+
"metadata": {},
71+
"source": [
72+
"### Rod-like sample oriented along x-axis"
73+
]
74+
},
75+
{
76+
"cell_type": "code",
77+
"execution_count": null,
78+
"id": "6",
79+
"metadata": {},
80+
"outputs": [],
81+
"source": [
82+
"# The material determines the rate of absorption and scattering\n",
83+
"vanadium = Material(\n",
84+
" scattering_params=ScatteringParams.for_isotope('V'),\n",
85+
" effective_sample_number_density=sc.scalar(0.07192, unit='1/angstrom**3')\n",
86+
")\n",
87+
"# The shape determines the shape and the orientation of the sample\n",
88+
"rod_shape = Cylinder(\n",
89+
" radius=sc.scalar(1, unit='cm'),\n",
90+
" height=(height := sc.scalar(5., unit='cm')),\n",
91+
" # Cylinder is oriented along the x-axis\n",
92+
" symmetry_line=(symmetry_line := sc.vector([1, 0, 0])),\n",
93+
" center_of_base=-height * symmetry_line / 2,\n",
94+
")"
95+
]
96+
},
97+
{
98+
"cell_type": "code",
99+
"execution_count": null,
100+
"id": "7",
101+
"metadata": {},
102+
"outputs": [],
103+
"source": [
104+
"transmission_fraction_mantle = compute_transmission_map(\n",
105+
" rod_shape,\n",
106+
" vanadium,\n",
107+
" beam_direction=sc.vector([0, 0, 1]),\n",
108+
" wavelength=sc.linspace('wavelength', 4, 8, 20, unit='angstrom'),\n",
109+
" # To make it faster, don't compute the transmission fraction for every detector pixel, it's not necessary for the visualization.\n",
110+
" detector_position=dg['mantle'].coords['position']['strip', ::4]['wire', ::2].copy(),\n",
111+
" quadrature_kind='cheap',\n",
112+
")\n",
113+
"\n",
114+
"# The visualization expects the `position` coord to denote detector positions, and `wavelength` to be the last dimension.\n",
115+
"transmission_fraction_mantle.coords['position'] = transmission_fraction_mantle.coords.pop('detector_position')\n",
116+
"dream.instrument_view(transmission_fraction_mantle, dim='wavelength', pixel_size=20.0)"
117+
]
118+
},
119+
{
120+
"cell_type": "code",
121+
"execution_count": null,
122+
"id": "8",
123+
"metadata": {},
124+
"outputs": [],
125+
"source": [
126+
"transmission_fraction_mantle"
127+
]
128+
},
129+
{
130+
"cell_type": "markdown",
131+
"id": "9",
132+
"metadata": {},
133+
"source": [
134+
"## Disk-like sample oriented along x-axis"
135+
]
136+
},
137+
{
138+
"cell_type": "code",
139+
"execution_count": null,
140+
"id": "10",
141+
"metadata": {},
142+
"outputs": [],
143+
"source": [
144+
"disk_shape = Cylinder(\n",
145+
" radius=sc.scalar(5, unit='cm'),\n",
146+
" height=(height := sc.scalar(1., unit='cm')),\n",
147+
" # Cylinder is oriented along the x-axis\n",
148+
" symmetry_line=(symmetry_line := sc.vector([1, 0, 0])),\n",
149+
" center_of_base=-height * symmetry_line / 2,\n",
150+
")\n",
151+
"\n",
152+
"transmission_fraction_mantle = compute_transmission_map(\n",
153+
" disk_shape,\n",
154+
" vanadium,\n",
155+
" beam_direction=sc.vector([0, 0, 1]),\n",
156+
" wavelength=sc.linspace('wavelength', 4, 8, 20, unit='angstrom'),\n",
157+
" # To make it faster, don't compute the transmission fraction for every detector pixel, it's not necessary for the visualization.\n",
158+
" detector_position=dg['mantle'].coords['position']['strip', ::4]['wire', ::2].copy(),\n",
159+
" quadrature_kind='cheap',\n",
160+
")\n",
161+
"\n",
162+
"# The visualization expects the `position` coord to denote detector positions, and `wavelength` to be the last dimension.\n",
163+
"transmission_fraction_mantle.coords['position'] = transmission_fraction_mantle.coords.pop('detector_position')\n",
164+
"dream.instrument_view(transmission_fraction_mantle, dim='wavelength', pixel_size=20.0)"
165+
]
166+
},
167+
{
168+
"cell_type": "markdown",
169+
"id": "11",
170+
"metadata": {},
171+
"source": [
172+
"## Does absorption influence the intensity in the endcap detector?"
173+
]
174+
},
175+
{
176+
"cell_type": "code",
177+
"execution_count": null,
178+
"id": "12",
179+
"metadata": {},
180+
"outputs": [],
181+
"source": [
182+
"transmission_fraction_endcap = compute_transmission_map(\n",
183+
" rod_shape,\n",
184+
" vanadium,\n",
185+
" beam_direction=sc.vector([0, 0, 1]),\n",
186+
" wavelength=sc.linspace('wavelength', 4, 8, 20, unit='angstrom'),\n",
187+
" detector_position=dg['endcap_backward'].coords['position']['strip', 0].copy(),\n",
188+
" quadrature_kind='cheap',\n",
189+
")\n",
190+
"\n",
191+
"transmission_fraction_endcap.coords['position'] = transmission_fraction_endcap.coords.pop('detector_position')\n",
192+
"dream.instrument_view(transmission_fraction_endcap, dim='wavelength', pixel_size=20.0)"
193+
]
194+
},
195+
{
196+
"cell_type": "markdown",
197+
"id": "13",
198+
"metadata": {},
199+
"source": [
200+
"As expected the impact of absorption on on the intensity in the endcap detector is close to uniform."
201+
]
202+
}
203+
],
204+
"metadata": {
205+
"kernelspec": {
206+
"display_name": "Python 3 (ipykernel)",
207+
"language": "python",
208+
"name": "python3"
209+
},
210+
"language_info": {
211+
"codemirror_mode": {
212+
"name": "ipython",
213+
"version": 3
214+
},
215+
"file_extension": ".py",
216+
"mimetype": "text/x-python",
217+
"name": "python",
218+
"nbconvert_exporter": "python",
219+
"pygments_lexer": "ipython3",
220+
"version": "3.10.14"
221+
}
222+
},
223+
"nbformat": 4,
224+
"nbformat_minor": 5
225+
}

docs/user-guide/dream/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ dream-data-reduction
99
dream-instrument-view
1010
workflow-widget-dream
1111
dream-detector-diagnostics
12+
dream-visualize-absorption
1213
```

0 commit comments

Comments
 (0)