Skip to content
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

Odin simulation workflow loader and hardcoded choppers. #50

Merged
merged 22 commits into from
Dec 13, 2024
Merged
Changes from 1 commit
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
Next Next commit
Odin simulation workflow loader and hardcoded choppers.
YooSunYoung committed Nov 27, 2024

Unverified

This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
commit aa0c22707e06ebe597222bc1f40a576d4de3300b
9 changes: 9 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -15,6 +15,15 @@ Ymir - Histogram Mode Detector

```

````{card}

```{button-ref} user-guide/odin_simulation
:class: stretched-link

ODIN McStas Simulation - Timepix Simulation with Choppers

```

````

```{toctree}
1 change: 1 addition & 0 deletions docs/user-guide/index.md
Original file line number Diff line number Diff line change
@@ -7,4 +7,5 @@ maxdepth: 1
---
installation
histogram_mode_detectors
odin_simulation
```
358 changes: 358 additions & 0 deletions docs/user-guide/odin_simulation.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,358 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "0",
"metadata": {},
"outputs": [],
"source": [
"import scipp as sc"
]
},
{
"cell_type": "markdown",
"id": "1",
"metadata": {},
"source": [
"## Loading dataset\n",
"\n",
"> Loader is not part of ``essimaging`` since McStas dataset format is not stabilized yet."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2",
"metadata": {},
"outputs": [],
"source": [
"import scippnexus as snx\n",
"from typing import cast, NewType\n",
"import numpy as np\n",
"from ess.reduce.nexus.types import FilePath\n",
"\n",
"\n",
"_DataPath = NewType('_DataPath', str)\n",
"_DefaultDataPath = _DataPath(\n",
" \"entry1/data/transmission_event_signal_dat_list_p_t_x_y_z_vx_vy_vz/events\"\n",
")\n",
"_FileLock = NewType('_FileLock', bool)\n",
"\"\"\"Lock the file to prevent concurrent access.\"\"\"\n",
"_DefaultFileLock = _FileLock(True)\n",
"OdinSimulationRawData = NewType('OdinSimulationRawData', sc.DataArray)\n",
"ProbabilityToCountsScaleFactor = NewType('ProbabilityToCountsScaleFactor', sc.Variable)\n",
"\"\"\"Translate the probability to counts.\"\"\"\n",
"DefaultProbabilityToCountsScaleFactor = ProbabilityToCountsScaleFactor(sc.scalar(1_000, unit='dimensionless'))\n",
"\n",
"\n",
"\n",
"def load_odin_simulation_data(\n",
" file_path: FilePath,\n",
" _data_path: _DataPath = _DefaultDataPath,\n",
" _file_lock: _FileLock = _DefaultFileLock,\n",
" probability_scale_factor: ProbabilityToCountsScaleFactor = DefaultProbabilityToCountsScaleFactor,\n",
") -> OdinSimulationRawData:\n",
" with snx.File(file_path, \"r\", locking=_file_lock) as f:\n",
" data = f[_data_path][()].rename_dims({'dim_0': 'event'})\n",
" probabilities = cast(sc.Variable, data['dim_1', 0].copy())\n",
" probabilities.unit = 'dimensionless'\n",
" time_of_arrival = data['dim_1', 1]\n",
" positions = data['dim_1', 2:5]\n",
" velocities = data['dim_1', 5:8]\n",
" counts = ((probabilities / probabilities.max()) * probability_scale_factor).astype(int)\n",
" da = sc.DataArray(\n",
" data=counts,\n",
" coords={\n",
" 'time_of_arrival': cast(sc.Variable, time_of_arrival),\n",
" 'x': cast(sc.Variable, positions['dim_1', 0]),\n",
" 'y': cast(sc.Variable, positions['dim_1', 1]),\n",
" 'z': cast(sc.Variable, positions['dim_1', 2]),\n",
" 'position': sc.vectors(\n",
" dims=['event'], values=cast(np.ndarray, positions.values)\n",
" ),\n",
" 'vx': cast(sc.Variable, velocities['dim_1', 0]),\n",
" 'vy': cast(sc.Variable, velocities['dim_1', 1]),\n",
" 'vz': cast(sc.Variable, velocities['dim_1', 2]),\n",
" 'velocity': sc.vectors(\n",
" dims=['event'], values=cast(np.ndarray, velocities.values)\n",
" ),\n",
" },\n",
" )\n",
" return OdinSimulationRawData(da)\n",
"\n",
"\n",
"\n",
"file_path = FilePath(\"task_bragg_baseline_open/data/mccode.h5\")\n",
"load_odin_simulation_data(file_path)"
]
},
{
"cell_type": "markdown",
"id": "3",
"metadata": {},
"source": [
"## Choppers\n",
"\n",
"> Choppers can be retrieved from nexus file automatically. <br>\n",
"> We are hardcoding them for simulation data reduction. <br>\n",
"> We may automate this once McStas nexus format is stabilized."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4",
"metadata": {},
"outputs": [],
"source": [
"from scippneutron.chopper import DiskChopper\n",
"\n",
"# Collect choppers\n",
"## WFM choppers\n",
"wfm_frequency = sc.scalar(value=56.0, unit='Hz')\n",
"beam_angle = sc.scalar(value=0.0, unit='deg')\n",
"\n",
"WFMC_1 = DiskChopper(\n",
" axle_position=sc.vector(value=(0.026000, 0.000000, 6.850000), unit='m'),\n",
" frequency=wfm_frequency,\n",
" beam_angle=beam_angle,\n",
" phase=sc.scalar(value=93.244, unit='deg'),\n",
" slit_begin=sc.array(\n",
" dims=['slit'],\n",
" values=[-1.9419, 49.5756, 98.9315, 146.2165, 191.5176, 234.9179],\n",
" unit='deg',\n",
" ),\n",
" slit_end=sc.array(\n",
" dims=['slit'],\n",
" values=[1.9419, 55.7157, 107.2332, 156.5891, 203.8741, 249.1752],\n",
" unit='deg',\n",
" ),\n",
")\n",
"\n",
"WFMC_2 = DiskChopper(\n",
" axle_position=sc.vector(value=(0.026000, 0.000000, 7.150000), unit='m'),\n",
" frequency=wfm_frequency,\n",
" beam_angle=beam_angle,\n",
" phase=sc.scalar(value=152.029879, unit='deg'),\n",
" slit_begin=sc.array(\n",
" dims=['slit'],\n",
" values=[-1.9419, 51.8318, 103.3493, 152.7052, 199.9903, 245.2914],\n",
" unit='deg',\n",
" ),\n",
" slit_end=sc.array(\n",
" dims=['slit'],\n",
" values=[1.9419, 57.9719, 111.6510, 163.0778, 212.3468, 259.5486],\n",
" unit='deg',\n",
" ),\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5",
"metadata": {},
"outputs": [],
"source": [
"WFMC_1"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6",
"metadata": {},
"outputs": [],
"source": [
"WFMC_2"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7",
"metadata": {},
"outputs": [],
"source": [
"## FOC choppers\n",
"foc_frequency = sc.scalar(value=42.0, unit='Hz')\n",
"F01 = DiskChopper(\n",
" axle_position=sc.vector(value=(0.026000, 0.000000, 8.400000), unit='m'),\n",
" frequency=foc_frequency,\n",
" beam_angle=beam_angle,\n",
" phase=sc.scalar(value=81.303297, unit='deg'),\n",
" slit_begin=sc.array(\n",
" dims=['slit'],\n",
" values=[-5.1362, 42.5536, 88.2425, 132.0144, 173.9497, 216.7867],\n",
" unit='deg',\n",
" ),\n",
" slit_end=sc.array(\n",
" dims=['slit'],\n",
" values=[5.1362, 54.2095, 101.2237, 146.2653, 189.417, 230.7582],\n",
" unit='deg',\n",
" ),\n",
")\n",
"\n",
"F02 = DiskChopper(\n",
" axle_position=sc.vector(value=(0.026000, 0.000000, 12.200000), unit='m'),\n",
" frequency=foc_frequency,\n",
" beam_angle=beam_angle,\n",
" phase=sc.scalar(value=107.013442, unit='deg'),\n",
" slit_begin=sc.array(\n",
" dims=['slit'],\n",
" values=[-16.3227, 53.7401, 120.8633, 185.1701, 246.7787, 307.0165],\n",
" unit='deg',\n",
" ),\n",
" slit_end=sc.array(\n",
" dims=['slit'],\n",
" values=[16.3227, 86.8303, 154.3794, 218.7551, 280.7508, 340.3188],\n",
" unit='deg',\n",
" ),\n",
")\n",
"\n",
"F03 = DiskChopper(\n",
" axle_position=sc.vector(value=(0.026000, 0.000000, 17.000000), unit='m'),\n",
" frequency=foc_frequency,\n",
" beam_angle=beam_angle,\n",
" phase=sc.scalar(value=158.294923, unit='deg'),\n",
" slit_begin=sc.array(\n",
" dims=['slit'],\n",
" values=[-20.302, 45.247, 108.0457, 168.2095, 225.8489, 282.2199],\n",
" unit='deg',\n",
" ),\n",
" slit_end=sc.array(\n",
" dims=['slit'],\n",
" values=[20.302, 85.357, 147.6824, 207.3927, 264.5977, 319.4024],\n",
" unit='deg',\n",
" ),\n",
")\n",
"\n",
"F04 = DiskChopper(\n",
" axle_position=sc.vector(value=(0.026000, 0.000000, 23.690000), unit='m'),\n",
" frequency=foc_frequency,\n",
" beam_angle=beam_angle,\n",
" phase=sc.scalar(value=61.584, unit='deg'),\n",
" slit_begin=sc.array(\n",
" dims=['slit'],\n",
" values=[-16.7157, 29.1882, 73.1661, 115.2988, 155.6636, 195.5254],\n",
" unit='deg',\n",
" ),\n",
" slit_end=sc.array(\n",
" dims=['slit'],\n",
" values=[16.7157, 61.8217, 105.0352, 146.4355, 186.0987, 224.0978],\n",
" unit='deg',\n",
" ),\n",
")\n",
"\n",
"F05 = DiskChopper(\n",
" axle_position=sc.vector(value=(0.026000, 0.000000, 33.000000), unit='m'),\n",
" frequency=foc_frequency,\n",
" beam_angle=beam_angle,\n",
" phase=sc.scalar(value=145.973844, unit='deg'),\n",
" slit_begin=sc.array(\n",
" dims=['slit'],\n",
" values=[-25.8514, 38.3239, 99.8064, 160.1254, 217.4321, 272.5426],\n",
" unit='deg',\n",
" ),\n",
" slit_end=sc.array(\n",
" dims=['slit'],\n",
" values=[25.8514, 88.4621, 147.4729, 204.0245, 257.7603, 313.7139],\n",
" unit='deg',\n",
" ),\n",
")\n",
"\n",
"F05"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8",
"metadata": {},
"outputs": [],
"source": [
"## BP choppers\n",
"bp_frequency = sc.scalar(value=7.0, unit='Hz')\n",
"BP01 = DiskChopper(\n",
" axle_position=sc.vector(value=(0.026000, 0.000000, 8.450000), unit='m'),\n",
" frequency=bp_frequency,\n",
" beam_angle=beam_angle,\n",
" phase=sc.scalar(value=31.079597, unit='deg'),\n",
" slit_begin=sc.array(dims=['slit'], values=[-23.6029], unit='deg'),\n",
" slit_end=sc.array(dims=['slit'], values=[23.6029], unit='deg'),\n",
" radius=sc.scalar(value=0.5, unit='m'),\n",
" slit_height=sc.scalar(value=0.075000, unit='m'),\n",
")\n",
"\n",
"BP02 = DiskChopper(\n",
" axle_position=sc.vector(value=(0.026000, 0.000000, 12.250000), unit='m'),\n",
" frequency=bp_frequency,\n",
" beam_angle=beam_angle,\n",
" phase=sc.scalar(value=44.223912, unit='deg'),\n",
" slit_begin=sc.array(dims=['slit'], values=[-34.4663], unit='deg'),\n",
" slit_end=sc.array(dims=['slit'], values=[34.4663], unit='deg'),\n",
" radius=sc.scalar(value=0.5, unit='m'),\n",
" slit_height=sc.scalar(value=0.080000, unit='m'),\n",
")\n",
"\n",
"BP02"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9",
"metadata": {},
"outputs": [],
"source": [
"# T0 chopppers\n",
"t0_frequency = sc.scalar(value=14.0, unit='Hz')\n",
"\n",
"TAlpha = DiskChopper(\n",
" axle_position=sc.vector(value=(0.026000, 0.000000, 13.500000), unit='m'),\n",
" frequency=t0_frequency,\n",
" beam_angle=beam_angle,\n",
" phase=sc.scalar(value=179.672400, unit='deg'),\n",
" slit_begin=sc.array(dims=['slit'], values=[-167.8986], unit='deg'),\n",
" slit_end=sc.array(dims=['slit'], values=[167.8986], unit='deg'),\n",
" radius=sc.scalar(value=0.3, unit='m'),\n",
" slit_height=sc.scalar(value=0.075000, unit='m'),\n",
")\n",
"\n",
"TBeta = DiskChopper(\n",
" axle_position=sc.vector(value=(0.000000, 0.000000, 0.200000), unit='m'),\n",
" frequency=t0_frequency,\n",
" beam_angle=beam_angle,\n",
" phase=sc.scalar(value=179.672, unit='deg'),\n",
" slit_begin=sc.array(dims=['slit'], values=[-167.8986], unit='deg'),\n",
" slit_end=sc.array(dims=['slit'], values=[167.8986], unit='deg'),\n",
" radius=sc.scalar(value=0.3, unit='m'),\n",
" slit_height=sc.scalar(value=0.075000, unit='m'),\n",
")\n",
"TBeta"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "img-dev-310",
"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
}
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@ dependencies = [
"plopp[all]",
"sciline>=23.9.1",
"scipp>=23.8.0",
"scippneutron",
"scippnexus>=23.11.1",
"essreduce",
"tifffile",