Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/api-reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@

Chopper
ChopperReading
Component
ComponentReading
Dashboard
Detector
DetectorReading
InelasticSample
Model
ReadingField
Result
Source
SourceParameters
SourceReading
```

## Top-level functions
Expand All @@ -39,5 +41,6 @@
:template: module-template.rst
:recursive:

facilities
utils
```
208 changes: 191 additions & 17 deletions docs/components.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import scipp as sc\n",
"import plopp as pp\n",
"import tof\n",
"\n",
"meter = sc.Unit('m')\n",
Expand Down Expand Up @@ -412,7 +415,183 @@
"id": "33",
"metadata": {},
"source": [
"## Loading from a JSON file\n",
"## Inelastic sample\n",
"\n",
"Placing an `InelasticSample` in the instrument will change the energy of the incoming neutrons by a $\\Delta E$ defined by a probability distribution function.\n",
"It defines the likeliness of what energy-shift will be applied to each neutron.\n",
"\n",
"To give an equal chance for a random $\\Delta E$ between -0.2 and 0.2 meV, we can create a flat distribution (all ones):"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "34",
"metadata": {},
"outputs": [],
"source": [
"sample = tof.InelasticSample(\n",
" distance=28.0 * meter,\n",
" name=\"sample\",\n",
" delta_e=sc.DataArray(\n",
" data=sc.ones(sizes={'e': 100}),\n",
" coords={'e': sc.linspace('e', -0.2, 0.2, 100, unit='meV')},\n",
" ),\n",
")\n",
"sample"
]
},
{
"cell_type": "markdown",
"id": "35",
"metadata": {},
"source": [
"We then make a single fast-rotating chopper with one small opening,\n",
"to select a narrow wavelength range at every rotation.\n",
"\n",
"We also add a monitor before the sample, and a detector after the sample so we can follow the changes in energies/wavelengths."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "36",
"metadata": {},
"outputs": [],
"source": [
"choppers = [\n",
" tof.Chopper(\n",
" frequency=70.0 * Hz,\n",
" open=sc.array(dims=['cutout'], values=[0.0], unit='deg'),\n",
" close=sc.array(dims=['cutout'], values=[1.0], unit='deg'),\n",
" phase=0.0 * deg,\n",
" distance=20.0 * meter,\n",
" name=\"fastchopper\",\n",
" ),\n",
"]\n",
"\n",
"detectors = [\n",
" tof.Detector(distance=26.0 * meter, name='monitor'),\n",
" tof.Detector(distance=32.0 * meter, name='detector'),\n",
"]\n",
"\n",
"source = tof.Source(facility='ess', neutrons=5_000_000)\n",
"\n",
"model = tof.Model(source=source, components=choppers + detectors + [sample])\n",
"res = model.run()\n",
"\n",
"\n",
"fig, ax = plt.subplots(1, 2, figsize=(12, 4.5))\n",
"\n",
"dw = sc.scalar(0.1, unit='angstrom')\n",
"pp.plot(\n",
" {\n",
" 'monitor': res['monitor'].data.hist(wavelength=dw),\n",
" 'detector': res['detector'].data.hist(wavelength=dw),\n",
" },\n",
" title=\"With inelastic sample\",\n",
" xmin=4,\n",
" xmax=20,\n",
" ymin=-20,\n",
" ymax=400,\n",
" ax=ax[1],\n",
")\n",
"\n",
"res.plot(visible_rays=10000, ax=ax[0])"
]
},
{
"cell_type": "markdown",
"id": "37",
"metadata": {},
"source": [
"### Non-uniform energy-transfer distributions"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "38",
"metadata": {},
"outputs": [],
"source": [
"# Sample 1: double-peak at min and max\n",
"delta_e = sc.DataArray(\n",
" data=sc.zeros(sizes={'e': 100}),\n",
" coords={'e': sc.linspace('e', -0.2, 0.2, 100, unit='meV')},\n",
")\n",
"delta_e.values[[0, -1]] = 1.0\n",
"sample1 = tof.InelasticSample(\n",
" distance=28.0 * meter,\n",
" name=\"sample\",\n",
" delta_e=delta_e,\n",
")\n",
"\n",
"# Sample 2: normal distribution\n",
"x = sc.linspace('e', -0.2, 0.2, 100, unit='meV')\n",
"sig = sc.scalar(0.03, unit='meV')\n",
"y = 1.0 / (np.sqrt(2.0 * np.pi) * sig) * sc.exp(-((x / sig) ** 2) / 2)\n",
"y.unit = \"\"\n",
"\n",
"sample2 = tof.InelasticSample(\n",
" distance=28.0 * meter,\n",
" name=\"sample\",\n",
" delta_e=sc.DataArray(data=y, coords={'e': x}),\n",
")\n",
"\n",
"sample1.plot() + sample2.plot()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "39",
"metadata": {},
"outputs": [],
"source": [
"model1 = tof.Model(source=source, components=choppers + detectors + [sample1])\n",
"model2 = tof.Model(source=source, components=choppers + detectors + [sample2])\n",
"\n",
"res1 = model1.run()\n",
"res2 = model2.run()\n",
"\n",
"fig, ax = plt.subplots(2, 2, figsize=(12, 9))\n",
"\n",
"res1.plot(ax=ax[0, 0], title=\"Sample 1\")\n",
"pp.plot(\n",
" {\n",
" 'monitor': res1['monitor'].data.hist(wavelength=dw),\n",
" 'detector': res1['detector'].data.hist(wavelength=dw),\n",
" },\n",
" title=\"Sample 1\",\n",
" xmin=4,\n",
" xmax=20,\n",
" ymin=-20,\n",
" ymax=400,\n",
" ax=ax[0, 1],\n",
")\n",
"\n",
"res2.plot(ax=ax[1, 0], title=\"Sample 2\")\n",
"_ = pp.plot(\n",
" {\n",
" 'monitor': res2['monitor'].data.hist(wavelength=dw),\n",
" 'detector': res2['detector'].data.hist(wavelength=dw),\n",
" },\n",
" title=\"Sample 2\",\n",
" xmin=4,\n",
" xmax=20,\n",
" ymin=-20,\n",
" ymax=400,\n",
" ax=ax[1, 1],\n",
")"
]
},
{
"cell_type": "markdown",
"id": "40",
"metadata": {},
"source": [
"## Loading components from a JSON file\n",
"\n",
"It is also possible to load components from a JSON file,\n",
"which can be very useful to quickly load a pre-configured instrument.\n",
Expand All @@ -423,19 +602,14 @@
{
"cell_type": "code",
"execution_count": null,
"id": "34",
"id": "41",
"metadata": {},
"outputs": [],
"source": [
"import json\n",
"\n",
"params = {\n",
" \"source\": {\n",
" \"type\": \"source\",\n",
" \"facility\": \"ess\",\n",
" \"neutrons\": 1e6,\n",
" \"pulses\": 1\n",
" },\n",
" \"source\": {\"type\": \"source\", \"facility\": \"ess\", \"neutrons\": 1e6, \"pulses\": 1},\n",
" \"chopper1\": {\n",
" \"type\": \"chopper\",\n",
" \"frequency\": {\"value\": 56.0, \"unit\": \"Hz\"},\n",
Expand Down Expand Up @@ -470,7 +644,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "35",
"id": "42",
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -479,7 +653,7 @@
},
{
"cell_type": "markdown",
"id": "36",
"id": "43",
"metadata": {},
"source": [
"We now use the `tof.Model.from_json()` method to load our instrument:"
Expand All @@ -488,7 +662,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "37",
"id": "44",
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -498,7 +672,7 @@
},
{
"cell_type": "markdown",
"id": "38",
"id": "45",
"metadata": {},
"source": [
"We can see that all components have been read in correctly.\n",
Expand All @@ -508,7 +682,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "39",
"id": "46",
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -517,7 +691,7 @@
},
{
"cell_type": "markdown",
"id": "40",
"id": "47",
"metadata": {},
"source": [
"### Modifying the source\n",
Expand All @@ -531,7 +705,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "41",
"id": "48",
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -542,7 +716,7 @@
},
{
"cell_type": "markdown",
"id": "42",
"id": "49",
"metadata": {},
"source": [
"## Saving to JSON\n",
Expand All @@ -553,7 +727,7 @@
{
"cell_type": "code",
"execution_count": null,
"id": "43",
"id": "50",
"metadata": {},
"outputs": [],
"source": [
Expand Down
5 changes: 3 additions & 2 deletions src/tof/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
submodules=['facilities'],
submod_attrs={
'chopper': ['AntiClockwise', 'Chopper', 'ChopperReading', 'Clockwise'],
'component': ['Component', 'ComponentReading', 'ReadingField'],
'dashboard': ['Dashboard'],
'detector': ['Detector', 'DetectorReading'],
'inelastic': ['InelasticSample', 'InelasticSampleReading'],
'model': ['Model'],
'reading': ['ComponentReading', 'ReadingField'],
'result': ['Result'],
'source': ['Source', 'SourceParameters'],
'source': ['Source', 'SourceReading'],
},
)

Expand Down
Loading
Loading