-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add illustration of inhomogeneity from absorption #113
base: main
Are you sure you want to change the base?
Changes from all commits
53343f5
c3c0a60
3401b79
aee7dc8
1822947
f361d77
1cf402a
de85d7d
bd985c9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "0", | ||
"metadata": {}, | ||
"source": [ | ||
"# Visualize effect of absorption\n", | ||
"\n", | ||
"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", | ||
"\n", | ||
"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", | ||
"\n", | ||
"For more details, see https://scipp.github.io/scippneutron/user-guide/absorption-correction.html." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "1", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import scipp as sc\n", | ||
"\n", | ||
"from plopp.graphics import Camera\n", | ||
"\n", | ||
"from ess import dream\n", | ||
"import ess.dream.data # noqa: F401\n", | ||
"\n", | ||
"from scippneutron.absorption import compute_transmission_map\n", | ||
"from scippneutron.absorption.cylinder import Cylinder\n", | ||
"from scippneutron.absorption.material import Material\n", | ||
"from scippneutron.atoms import ScatteringParams" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "2", | ||
"metadata": {}, | ||
"source": [ | ||
"## Load the data\n", | ||
"\n", | ||
"We load a dataset from a Geant4 simulation only to get access to the detector geometry." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "3", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"dg = dream.io.load_geant4_csv(dream.data.get_path(\"data_dream0_new_hkl_Si_pwd.csv.zip\"))[\"instrument\"]\n", | ||
"dg = sc.DataGroup({key: detector[\"events\"] for key, detector in dg.items()})\n", | ||
"dg.keys()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "4", | ||
"metadata": {}, | ||
"source": [ | ||
"## Inhomogeneity from absorption in mantle detector\n", | ||
"\n", | ||
"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" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "5", | ||
"metadata": {}, | ||
"source": [ | ||
"### Rod-like sample oriented along x-axis" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "6", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"# The material determines the rate of absorption and scattering\n", | ||
"vanadium = Material(\n", | ||
" scattering_params=ScatteringParams.for_isotope('V'),\n", | ||
" effective_sample_number_density=sc.scalar(0.07192, unit='1/angstrom**3')\n", | ||
")\n", | ||
"# The shape determines the shape and the orientation of the sample\n", | ||
"rod_shape = Cylinder(\n", | ||
" radius=sc.scalar(1, unit='cm'),\n", | ||
" height=(height := sc.scalar(5., unit='cm')),\n", | ||
" # Cylinder is oriented along the x-axis\n", | ||
" symmetry_line=(symmetry_line := sc.vector([1, 0, 0])),\n", | ||
" center_of_base=-height * symmetry_line / 2,\n", | ||
")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "7", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"transmission_fraction_mantle = compute_transmission_map(\n", | ||
" rod_shape,\n", | ||
" vanadium,\n", | ||
" beam_direction=sc.vector([0, 0, 1]),\n", | ||
" wavelength=sc.linspace('wavelength', 4, 8, 20, unit='angstrom'),\n", | ||
" # To make it faster, don't compute the transmission fraction for every detector pixel, it's not necessary for the visualization.\n", | ||
" detector_position=dg['mantle'].coords['position']['strip', ::4]['wire', ::2].copy(),\n", | ||
" quadrature_kind='cheap',\n", | ||
")\n", | ||
"\n", | ||
"# The visualization expects the `position` coord to denote detector positions, and `wavelength` to be the last dimension.\n", | ||
"transmission_fraction_mantle.coords['position'] = transmission_fraction_mantle.coords.pop('detector_position')\n", | ||
"dream.instrument_view(transmission_fraction_mantle.transpose((*set(transmission_fraction_mantle.dims) - {'wavelength'}, 'wavelength')), dim='wavelength', camera=Camera(position=sc.vector((-2, 2, -2), unit='m'), look_at=sc.vector((1, -1/3, 1/2), unit='m')))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "8", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"transmission_fraction_mantle" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "9", | ||
"metadata": {}, | ||
"source": [ | ||
"## Disk-like sample oriented along x-axis" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "10", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"disk_shape = Cylinder(\n", | ||
" radius=sc.scalar(5, unit='cm'),\n", | ||
" height=(height := sc.scalar(1., unit='cm')),\n", | ||
" # Cylinder is oriented along the x-axis\n", | ||
" symmetry_line=(symmetry_line := sc.vector([1, 0, 0])),\n", | ||
" center_of_base=-height * symmetry_line / 2,\n", | ||
")\n", | ||
"\n", | ||
"transmission_fraction_mantle = compute_transmission_map(\n", | ||
" disk_shape,\n", | ||
" vanadium,\n", | ||
" beam_direction=sc.vector([0, 0, 1]),\n", | ||
" wavelength=sc.linspace('wavelength', 4, 8, 20, unit='angstrom'),\n", | ||
" # To make it faster, don't compute the transmission fraction for every detector pixel, it's not necessary for the visualization.\n", | ||
" detector_position=dg['mantle'].coords['position']['strip', ::4]['wire', ::2].copy(),\n", | ||
" quadrature_kind='cheap',\n", | ||
")\n", | ||
"\n", | ||
"# The visualization expects the `position` coord to denote detector positions, and `wavelength` to be the last dimension.\n", | ||
"transmission_fraction_mantle.coords['position'] = transmission_fraction_mantle.coords.pop('detector_position')\n", | ||
"dream.instrument_view(transmission_fraction_mantle.transpose((*set(transmission_fraction_mantle.dims) - {'wavelength'}, 'wavelength')), dim='wavelength', camera=Camera(position=sc.vector((-2, 2, -2), unit='m'), look_at=sc.vector((1, -1/3, 1/2), unit='m')))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "11", | ||
"metadata": {}, | ||
"source": [ | ||
"## Does absorption influence the intensity in the endcap detector?" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "12", | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"transmission_fraction_endcap = compute_transmission_map(\n", | ||
" rod_shape,\n", | ||
" vanadium,\n", | ||
" beam_direction=sc.vector([0, 0, 1]),\n", | ||
" wavelength=sc.linspace('wavelength', 4, 8, 20, unit='angstrom'),\n", | ||
" detector_position=dg['endcap_backward'].coords['position']['strip', 0].copy(),\n", | ||
" quadrature_kind='cheap',\n", | ||
")\n", | ||
"\n", | ||
"transmission_fraction_endcap.coords['position'] = transmission_fraction_endcap.coords.pop('detector_position')\n", | ||
"dream.instrument_view(transmission_fraction_endcap.transpose((*set(transmission_fraction_endcap.dims) - {'wavelength'}, 'wavelength')), dim='wavelength', camera=Camera(position=sc.vector((-1, 1, -3), unit='m'), look_at=sc.vector((0.3, -0.3, 1), unit='m')))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "13", | ||
"metadata": {}, | ||
"source": [ | ||
"As expected the impact of absorption on on the intensity in the endcap detector is close to uniform." | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't look so uniform when you look at the figure... until you look at the colorbar. Should we use some common colorbar limits for all 3 views? Also, do we really have to use the heavy instrument view, or could we use 2d scatter plots instead? The 3d views dramatically increase the size of the docs, and thus the repository itself. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
No I don't think that's important. It's better to keep it simple and to make it look like something they might encounter in their own notebook.
Did you check how much the repo size is increased? We could make it 2d, it's not good to make the repo cumbersome to download. Byt the 3d view is nicer to play around with. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Took a look at the sizes now, after building the docs locally I have the following files:
So it seems the absorption visualization notebook is significantly smaller than the instrument view notebook. I also tried cloning
Compressed it seems the size (of the current repo) is closer to 10Mb. Overall I get the impression that it doesn't really matter if we put this file here, it's unlikely to make the repo hard to download for anyone. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 10Mb is a lot. Maybe we should really reduce the size of the instrument view notebook?
It might be nice to play with, but I don't think it adds any information to what we are viewing? I think the views might be clearer in 2D. I will have a go at making them and we can compare. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Let's just ask Celine if this solves her use-case? Then we don't have to guess and re-implement something that already works. |
||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3 (ipykernel)", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.10.14" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want this notebook to appear in the docs, you need to add it to the
dream/index.md
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot that, thanks.