Skip to content

Commit

Permalink
Merge pull request #18 from scipp/mcstas-instrument
Browse files Browse the repository at this point in the history
Mcstas instrument geometry in the loader.
  • Loading branch information
YooSunYoung authored Jan 10, 2024
2 parents 9e8c8c5 + f4495e2 commit 3b1c0de
Show file tree
Hide file tree
Showing 5 changed files with 536 additions and 14 deletions.
38 changes: 34 additions & 4 deletions docs/examples/workflow.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"## Collect Parameters and Providers\n",
"### Simulation(McStas) Data\n",
"There is a dedicated loader, ``load_mcstas_nexus`` for ``McStas`` simulation data workflow. <br>\n",
"``MaximumProbability`` can be manually provided to the loader to derive more realistic number of events. <br>\n",
"``MaximumProbability`` can be manually provided to the loader <br>\n",
"to derive more realistic number of events. <br>\n",
"It is because ``weights`` are given as probability, not number of events in a McStas file. <br>"
]
},
Expand Down Expand Up @@ -47,7 +48,9 @@
"source": [
"from typing import get_type_hints\n",
"param_reprs = {key.__name__: value for key, value in params.items()}\n",
"prov_reprs = {get_type_hints(prov)['return'].__name__: prov.__name__ for prov in providers}\n",
"prov_reprs = {\n",
" get_type_hints(prov)['return'].__name__: prov.__name__ for prov in providers\n",
"}\n",
"\n",
"# Providers and parameters to be used for pipeline\n",
"sc.DataGroup(**prov_reprs, **param_reprs)"
Expand Down Expand Up @@ -91,11 +94,38 @@
"da = nmx_workflow.compute(NMXData)\n",
"da"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Instrument View\n",
"\n",
"Pixel positions are not used for later steps,\n",
"but it is included in the coordinates for instrument view.\n",
"\n",
"All pixel positions are relative to the sample position,\n",
"therefore the sample is at (0, 0, 0).\n",
"\n",
"You can plot the instrument view like below.\n",
"\n",
"```python\n",
"import scippneutron as scn\n",
"\n",
"unnecessary_coords = list(coord for coord in da.coords if coord != 'position')\n",
"instrument_view_da = da.drop_coords(unnecessary_coords).flatten(['panel', 'id'], 'id').hist()\n",
"view = scn.instrument_view(instrument_view_da)\n",
"view.children[0].toolbar.cameraz()\n",
"view\n",
"```\n",
"\n",
"**It might be very slow or not work in the ``VS Code`` jupyter notebook editor.**"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "nmx-dev-39",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
Expand All @@ -113,5 +143,5 @@
}
},
"nbformat": 4,
"nbformat_minor": 2
"nbformat_minor": 4
}
19 changes: 9 additions & 10 deletions src/ess/nmx/mcstas_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

PixelIDs = NewType("PixelIDs", sc.Variable)
InputFilepath = NewType("InputFilepath", str)
NMXData = NewType("NMXData", sc.DataArray)
NMXData = NewType("NMXData", sc.DataGroup)

# McStas Configurations
MaximumProbability = NewType("MaximumProbability", int)
Expand Down Expand Up @@ -37,13 +37,6 @@ def _copy_partial_var(
return var


def _get_mcstas_pixel_ids() -> PixelIDs:
"""pixel IDs for each detector"""
intervals = [(1, 1638401), (2000001, 3638401), (4000001, 5638401)]
ids = [sc.arange('id', start, stop, unit=None) for start, stop in intervals]
return PixelIDs(sc.concat(ids, 'id'))


def load_mcstas_nexus(
file_path: InputFilepath,
max_probability: Optional[MaximumProbability] = None,
Expand All @@ -60,6 +53,9 @@ def load_mcstas_nexus(
"""

from .mcstas_xml import read_mcstas_geometry_xml

geometry = read_mcstas_geometry_xml(file_path)
probability = max_probability or DefaultMaximumProbability

with snx.File(file_path) as file:
Expand All @@ -76,6 +72,9 @@ def load_mcstas_nexus(
weights = (probability / weights.max()) * weights

loaded = sc.DataArray(data=weights, coords={'t': t_list, 'id': id_list})
grouped = loaded.group(_get_mcstas_pixel_ids())
coords = geometry.to_coords()
grouped = loaded.group(coords.pop('pixel_id'))
da = grouped.fold(dim='id', sizes={'panel': len(geometry.detectors), 'id': -1})
da.coords.update(coords)

return NMXData(grouped.fold(dim='id', sizes={'panel': 3, 'id': -1}))
return NMXData(da)
Loading

0 comments on commit 3b1c0de

Please sign in to comment.