From fbcb4c8feee575ba8c835f711dfa887735b57098 Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Mon, 16 Dec 2024 15:29:46 +0100 Subject: [PATCH 1/4] add stap demo data files and reduction notebook --- .../dream/dream-simulation-si-wfm.ipynb | 653 ++++++++++++++++++ src/ess/dream/data.py | 38 + 2 files changed, 691 insertions(+) create mode 100644 docs/user-guide/dream/dream-simulation-si-wfm.ipynb diff --git a/docs/user-guide/dream/dream-simulation-si-wfm.ipynb b/docs/user-guide/dream/dream-simulation-si-wfm.ipynb new file mode 100644 index 00000000..71987e13 --- /dev/null +++ b/docs/user-guide/dream/dream-simulation-si-wfm.ipynb @@ -0,0 +1,653 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "33f8848d-d8c6-4e9f-8bdc-ae3010f0dc42", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "# DREAM: simulation with Si powder sample\n", + "\n", + "This notebook illustrates the reduction of Powder Diffraction data for DREAM.\n", + "\n", + "- It uses simulated data from McStas/GEANT4 in the High-Flux configuration\n", + "- The samples were Si powder and Vanadium (for normalisation)\n", + "\n", + "For Vanadium, we use the result of a McStas/GEANT4 simulation using the `Incoherent` component to model the Vanadium sample. \n", + "\n", + "In this notebook the input files are NeXus files.\n", + "They created using one of the NeXus files from the CODA pipeline and stored in Scicat and by adding simulated data from McStas/GEANT4." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "de26f86e-69c6-4833-aee8-595c2d7c5443", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import scipp as sc\n", + "import scippneutron as scn\n", + "import plopp as pp\n", + "import matplotlib.pyplot as plt\n", + "import ess.dream as dream\n", + "from ess.dream import data as dream_data\n", + "import ipywidgets as ipw\n", + "import matplotlib.pyplot as plt\n", + "from scipp.constants import m_n, h\n", + "import scippnexus as snx" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7356d2fd-0447-4307-bf80-def807b7da21", + "metadata": {}, + "outputs": [], + "source": [ + "def _nonfinite_to_zero(\n", + " data: sc.DataGroup | sc.DataArray | sc.Dataset\n", + ") -> sc.DataGroup | sc.DataArray | sc.Dataset:\n", + " \"\"\"\n", + " Replace NaN, positive and negative infs by zero\n", + " \"\"\"\n", + " if data.variances is not None:\n", + " replacement = sc.scalar(0.0, variance=0.0, unit=data.unit)\n", + " else:\n", + " replacement = sc.scalar(0.0, unit=data.unit)\n", + " return sc.nan_to_num(\n", + " data,\n", + " nan=replacement,\n", + " posinf=replacement,\n", + " neginf=replacement)\n", + "\n", + "\n", + "def clean_all_dets(\n", + " data: sc.DataGroup | sc.DataArray | sc.Dataset\n", + " ) -> sc.DataGroup | sc.DataArray | sc.Dataset:\n", + " \"\"\"Clean the data, removing NaNs.\"\"\"\n", + " dg_out = sc.DataGroup()\n", + " for item in data.keys():\n", + " out = data[item].copy()\n", + " out.data = _nonfinite_to_zero(out.data)\n", + " dg_out[item] = out\n", + " return dg_out\n", + "\n", + "\n", + "def load_dream_nxs(filename: str) -> sc.DataGroup:\n", + " \"\"\"\n", + " \"\"\"\n", + " dg_out = sc.DataGroup()\n", + " pattern = \"_detector\"\n", + " period = (1.0 / sc.scalar(14., unit='Hz')).to(unit='ns')\n", + "\n", + " # temporarily hard-coding values of sample, source and cave monitor positions\n", + " # until bug fix for DREAM NeXus file\n", + " source_position = sc.vector(value=np.array([-3.478, 0.0, -76550]), unit='mm')\n", + " sample_position = sc.vector(value=np.array([0.0, 0.0, 0.0]), unit='mm')\n", + "\n", + " with snx.File(filename) as f:\n", + " inst = f['entry']['instrument']\n", + " for key in inst:\n", + " if key.endswith(pattern):\n", + " name = key.removesuffix(pattern)\n", + " dg = inst[key][()]\n", + " da = dg[f'{name}_event_data']\n", + " #dg_out[name]['event'].variances = dg_out[name]['event'].values\n", + "\n", + " # add position\n", + " da.coords['position'] = sc.spatial.as_vectors(\n", + " da.coords['x_pixel_offset'],\n", + " da.coords['y_pixel_offset'], \n", + " da.coords['z_pixel_offset'])\n", + " \n", + " # add sample and source position\n", + " da.coords['source_position'] = source_position\n", + " da.coords['sample_position'] = sample_position\n", + " \n", + " # rename ToF\n", + " da.bins.coords['tof'] = da.bins.coords.pop('event_time_offset')\n", + "\n", + " # add variances\n", + " da.bins.constituents['data'].variances = da.bins.constituents['data'].values\n", + " \n", + " \n", + " # In the raw data, the tofs extend beyond 71ms.\n", + " # This is thus not an event_time_offset.\n", + " # In addition, there is only one event_time_zero for all events,\n", + " # when there should be at least 2 because some tofs are larger than 71ms\n", + " \n", + " # Bin the data into bins with a 71ms period\n", + " da = da.bin(tof=sc.arange('tof', 3) * period)\n", + " # Add a event_time_zero coord for each bin, but not as bin edges, as all events in the same pulse have the same event_time_zero, hence the `[:2]`\n", + " da.coords['event_time_zero'] = (sc.scalar(1730450434078980000, unit='ns') + da.coords['tof'])[:2]\n", + " # Remove the meaningless tof coord at the top level\n", + " del da.coords['tof']\n", + " # Remove the original (wrong) event_time_zero event coord inside the bins and rename the dim\n", + " del da.bins.coords['event_time_zero']\n", + " da = da.rename_dims(tof='event_time_zero')\n", + " # Compute a proper event_time_offset as tof % period\n", + " da.bins.coords['event_time_offset'] = (da.bins.coords.pop('tof') % period).to(unit='us')\n", + " dg_out[name] = da\n", + " \n", + " return dg_out\n", + "\n", + "\n", + "def load_monitor(file: str) -> sc.DataArray:\n", + " \"\"\"\n", + " Load histogrammed monitor data,\n", + " making sure that the time-of-flight wraps around the pulse period.\n", + " \"\"\"\n", + " tof, tof_count = np.loadtxt(file, usecols=(0, 1),\n", + " skiprows=42, unpack=True)\n", + "\n", + " raw_data = sc.DataArray(\n", + " data=sc.array(dims=['tof'], \n", + " values=tof_count, \n", + " unit='counts'),\n", + " coords={\n", + " 'tof': sc.array(dims=['tof'], values=tof*1000 , unit='ns')\n", + " })\n", + " raw_data = raw_data['tof', 0.* sc.Unit('ns'):1e8* sc.Unit('ns')].copy()\n", + "\n", + " # Convert coord to bin edges\n", + " tof = raw_data.coords['tof']\n", + " center = sc.midpoints(tof, dim='tof')\n", + " left = center['tof', 0:1] - (tof['tof', 1] - tof['tof', 0])\n", + " right = center['tof', -1] + (tof['tof', -1] - tof['tof', -2])\n", + " raw_data.coords['tof'] = sc.concat([left, center, right], 'tof')\n", + " \n", + " period = (1. / sc.scalar(14., unit='Hz')).to(unit=raw_data.coords['tof'].unit) \n", + " bins = sc.sort(sc.concat([raw_data.coords['tof'], period], 'tof'), 'tof')\n", + " raw_data = raw_data.rebin(tof=bins)\n", + " part1 = raw_data['tof', :period].copy()\n", + " part2 = raw_data['tof', period:].copy()\n", + " part2.coords['tof'] = part2.coords['tof'] % period\n", + " bins = sc.linspace('tof', 0, period.value, 513, unit=period.unit)\n", + " \n", + " out = part2.rebin(tof=bins) + part1.rebin(tof=bins)\n", + " out = out.rename(tof='time_of_flight')\n", + "\n", + " out.coords['Ltotal'] = sc.scalar(np.sqrt(3.478**2 + 72330**2), unit='mm')\n", + " return out" + ] + }, + { + "cell_type": "markdown", + "id": "69b12cdf-d5d4-4164-b10b-cbc0f7edd030", + "metadata": {}, + "source": [ + "## Beamline properties\n", + "\n", + "We set up the chopper parameters,\n", + "used to determine the frame boundaries and compute an accurate neutron time-of-flight." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45947845-8fdb-423e-9a58-da660e081335", + "metadata": {}, + "outputs": [], + "source": [ + "import sciline as sl\n", + "from scippneutron.chopper import DiskChopper\n", + "from scippneutron.tof import unwrap\n", + "from scippneutron.tof import chopper_cascade\n", + "\n", + "psc1 = DiskChopper(\n", + " frequency=sc.scalar(14.0, unit=\"Hz\"),\n", + " beam_position=sc.scalar(0.0, unit=\"deg\"),\n", + " phase=sc.scalar(286 - 180, unit=\"deg\"),\n", + " axle_position=sc.vector(value=[0, 0, 6.145], unit=\"m\"),\n", + " slit_begin=sc.array(\n", + " dims=[\"cutout\"],\n", + " values=[-1.23, 70.49, 84.765, 113.565, 170.29, 271.635, 286.035, 301.17],\n", + " unit=\"deg\",\n", + " ),\n", + " slit_end=sc.array(\n", + " dims=[\"cutout\"],\n", + " values=[1.23, 73.51, 88.035, 116.835, 175.31, 275.565, 289.965, 303.63],\n", + " unit=\"deg\",\n", + " ),\n", + " slit_height=sc.scalar(10.0, unit=\"cm\"),\n", + " radius=sc.scalar(30.0, unit=\"cm\"),\n", + ")\n", + "\n", + "psc2 = DiskChopper(\n", + " frequency=sc.scalar(-14.0, unit=\"Hz\"),\n", + " beam_position=sc.scalar(0.0, unit=\"deg\"),\n", + " phase=sc.scalar(-236, unit=\"deg\"),\n", + " axle_position=sc.vector(value=[0, 0, 6.155], unit=\"m\"),\n", + " slit_begin=sc.array(\n", + " dims=[\"cutout\"],\n", + " values=[-1.23, 27.0, 55.8, 142.385, 156.765, 214.115, 257.23, 315.49],\n", + " unit=\"deg\",\n", + " ),\n", + " slit_end=sc.array(\n", + " dims=[\"cutout\"],\n", + " values=[1.23, 30.6, 59.4, 145.615, 160.035, 217.885, 261.17, 318.11],\n", + " unit=\"deg\",\n", + " ),\n", + " slit_height=sc.scalar(10.0, unit=\"cm\"),\n", + " radius=sc.scalar(30.0, unit=\"cm\"),\n", + ")\n", + "\n", + "oc = DiskChopper(\n", + " frequency=sc.scalar(14.0, unit=\"Hz\"),\n", + " beam_position=sc.scalar(0.0, unit=\"deg\"),\n", + " phase=sc.scalar(297 - 180 - 90, unit=\"deg\"),\n", + " axle_position=sc.vector(value=[0, 0, 6.174], unit=\"m\"),\n", + " slit_begin=sc.array(dims=[\"cutout\"], values=[-27.6 * 0.5], unit=\"deg\"),\n", + " slit_end=sc.array(dims=[\"cutout\"], values=[27.6 * 0.5], unit=\"deg\"),\n", + " slit_height=sc.scalar(10.0, unit=\"cm\"),\n", + " radius=sc.scalar(30.0, unit=\"cm\"),\n", + ")\n", + "\n", + "bcc = DiskChopper(\n", + " frequency=sc.scalar(112.0, unit=\"Hz\"),\n", + " beam_position=sc.scalar(0.0, unit=\"deg\"),\n", + " phase=sc.scalar(240 - 180, unit=\"deg\"),\n", + " axle_position=sc.vector(value=[0, 0, 9.78], unit=\"m\"),\n", + " slit_begin=sc.array(dims=[\"cutout\"], values=[-36.875, 143.125], unit=\"deg\"),\n", + " slit_end=sc.array(dims=[\"cutout\"], values=[36.875, 216.875], unit=\"deg\"),\n", + " slit_height=sc.scalar(10.0, unit=\"cm\"),\n", + " radius=sc.scalar(30.0, unit=\"cm\"),\n", + ")\n", + "\n", + "t0 = DiskChopper(\n", + " frequency=sc.scalar(28.0, unit=\"Hz\"),\n", + " beam_position=sc.scalar(0.0, unit=\"deg\"),\n", + " phase=sc.scalar(280 - 180, unit=\"deg\"),\n", + " axle_position=sc.vector(value=[0, 0, 13.05], unit=\"m\"),\n", + " slit_begin=sc.array(dims=[\"cutout\"], values=[-314.9 * 0.5], unit=\"deg\"),\n", + " slit_end=sc.array(dims=[\"cutout\"], values=[314.9 * 0.5], unit=\"deg\"),\n", + " slit_height=sc.scalar(10.0, unit=\"cm\"),\n", + " radius=sc.scalar(30.0, unit=\"cm\"),\n", + ")\n", + "\n", + "disk_choppers = {\"psc1\": psc1, \"psc2\": psc2, \"oc\": oc, \"bcc\": bcc, \"t0\": t0}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b1e19ad1-81bd-4242-97af-521a1e11499b", + "metadata": {}, + "outputs": [], + "source": [ + "choppers = {\n", + " key: chopper_cascade.Chopper.from_disk_chopper(\n", + " chop,\n", + " pulse_frequency=sc.scalar(14.0, unit=\"Hz\"),\n", + " npulses=1,\n", + " )\n", + " for key, chop in disk_choppers.items()\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27a2de1a-5c9a-440d-8cf5-87dc27cfeeb7", + "metadata": {}, + "outputs": [], + "source": [ + "pulse_tmin = sc.scalar(0., unit='ms')\n", + "pulse_tmax = sc.scalar(5., unit='ms')\n", + "pulse_wmin = sc.scalar(0.2, unit='angstrom')\n", + "pulse_wmax = sc.scalar(20., unit='angstrom')\n", + "\n", + "frames = chopper_cascade.FrameSequence.from_source_pulse(\n", + " time_min=pulse_tmin,\n", + " time_max=pulse_tmax,\n", + " wavelength_min=pulse_wmin,\n", + " wavelength_max=pulse_wmax,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "486710b7-805d-400c-963b-94234fc085b0", + "metadata": {}, + "outputs": [], + "source": [ + "# Chop the frames\n", + "chopped = frames.chop(choppers.values())\n", + "\n", + "# Propagate the neutrons to the detector\n", + "at_detector = chopped.propagate_to(sc.scalar(76.5, unit='m'))\n", + "\n", + "# Visualize the results\n", + "cascade_fig, cascade_ax = at_detector.draw()" + ] + }, + { + "cell_type": "markdown", + "id": "e83ce604-ecc4-47d9-af60-976e049be787", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "## Load and process monitor data\n", + "\n", + "For normalisation, we consider the Cave monitor contained in McStas model of DREAM.\n", + "We load the monitors from the Si and Vanadium simulations.\n", + "\n", + "\n", + "
\n", + "\n", + "*NOTE:*\n", + "\n", + "We use the ASCII file from McStas. This is a temporary solution, which will be replaced once monitor data have been added to the NeXus file.\n", + "\n", + "
\n", + "\n", + "### Load raw data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b232fb62-1932-4656-9bda-b8255a652cce", + "metadata": {}, + "outputs": [], + "source": [ + "tof_mon_cave_si = load_monitor(dream_data.stap_demo_2024_si_monitor())\n", + "tof_mon_cave_van = load_monitor(dream_data.stap_demo_2024_vanadium_monitor())\n", + "\n", + "tof_mon_cave_si.plot(grid=True, title='Si Cave tof monitor') + tof_mon_cave_van.plot(grid=True, title='Vana Cave tof monitor')" + ] + }, + { + "cell_type": "markdown", + "id": "b0356a2e-2eca-453a-b20d-be9603e5950f", + "metadata": {}, + "source": [ + "### Convert monitor data to wavelength" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bb151913-e544-4fec-a3a4-e8da66a24299", + "metadata": {}, + "outputs": [], + "source": [ + "# Setup workflow\n", + "pl = sl.Pipeline((*unwrap.providers(), unwrap.re_histogram_tof_data), params=unwrap.params())\n", + "pl[unwrap.PulsePeriod] = 1.0 / sc.scalar(14.0, unit=\"Hz\")\n", + "\n", + "pl[unwrap.SourceTimeRange] = pulse_tmin, pulse_tmax\n", + "pl[unwrap.SourceWavelengthRange] = pulse_wmin, pulse_wmax\n", + "pl[unwrap.Choppers] = choppers\n", + "\n", + "# Si sample\n", + "pl[unwrap.RawData] = tof_mon_cave_si\n", + "pl[unwrap.Ltotal] = tof_mon_cave_si.coords['Ltotal']\n", + "tofs_si = pl.compute(unwrap.ReHistogrammedTofData)\n", + "\n", + "# Vanadium sample\n", + "pl[unwrap.RawData] = tof_mon_cave_van\n", + "pl[unwrap.Ltotal] = tof_mon_cave_van.coords['Ltotal']\n", + "tofs_van = pl.compute(unwrap.ReHistogrammedTofData)\n", + "\n", + "\n", + "# Convert to wavelength\n", + "wlgth_graph_monitor = {\n", + " **scn.conversion.graph.beamline.beamline(scatter=False),\n", + " **scn.conversion.graph.tof.elastic_wavelength('tof'),\n", + "}\n", + "\n", + "mon_cave_si_wlgth = tofs_si.transform_coords('wavelength', graph=wlgth_graph_monitor)\n", + "mon_cave_van_wlgth = tofs_van.transform_coords('wavelength', graph=wlgth_graph_monitor)\n", + "\n", + "# Plot\n", + "mon_cave_si_wlgth.plot(title='Monitor for Si sample in wavelength', grid=True) + mon_cave_van_wlgth.plot(title='Monitor for Vanadium sample in wavelength', grid=True)" + ] + }, + { + "cell_type": "markdown", + "id": "62e4487f-88e0-4f32-9b37-f65b0dbfe2b1", + "metadata": {}, + "source": [ + "## Load and process detector data\n", + "\n", + "### Load raw data" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "00afd918-36e6-4905-a381-b4a0b287dc71", + "metadata": {}, + "outputs": [], + "source": [ + "from ess.dream import data as dream_data\n", + "\n", + "sample = load_dream_nxs(dream_data.stap_demo_2024_si_sample())\n", + "vana = load_dream_nxs(dream_data.stap_demo_2024_vanadium_sample())\n", + "\n", + "sample" + ] + }, + { + "cell_type": "markdown", + "id": "609b5eb1-51ab-4cb3-b48b-bddb2510d8cd", + "metadata": {}, + "source": [ + "### Conversion to wavelength" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "55b85e57-4df3-434d-825a-fbf8522297d0", + "metadata": {}, + "outputs": [], + "source": [ + "detector_graph = {\n", + " **scn.conversion.graph.beamline.beamline(scatter=True),\n", + " **scn.conversion.graph.tof.elastic_wavelength('tof'),\n", + "}\n", + "\n", + "dg_si_wlgth = sc.DataGroup()\n", + "dg_van_wlgth = sc.DataGroup()\n", + "\n", + "for (run, out) in ((sample, dg_si_wlgth), (vana, dg_van_wlgth)):\n", + " for key, val in run.items():\n", + " da = val.transform_coords(['Ltotal'], graph=detector_graph)\n", + " pl[unwrap.RawData] = da\n", + " pl[unwrap.Ltotal] = da.coords['Ltotal']\n", + " \n", + " result = pl.compute(unwrap.TofData)\n", + " out[key] = result.transform_coords('wavelength', graph=detector_graph)" + ] + }, + { + "cell_type": "markdown", + "id": "74f1bdb1-07ff-4953-ab66-d6b6ac085517", + "metadata": {}, + "source": [ + "## Normalize by integrated monitor counts" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a8684e23-ab95-4c0d-aa41-44b04c87c904", + "metadata": {}, + "outputs": [], + "source": [ + "# TODO: we multiplied the sums by the bin width in the original notebook\n", + "\n", + "dg_si_wlgth_norm = dg_si_wlgth / mon_cave_si_wlgth.sum().data\n", + "dg_van_wlgth_norm = dg_van_wlgth / mon_cave_van_wlgth.sum().data" + ] + }, + { + "cell_type": "markdown", + "id": "5ba44890-67d9-4db3-91fa-cbf5da23027e", + "metadata": {}, + "source": [ + "## Convert to d-spacing" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "445413f6-029d-4fb2-a317-3171962d7334", + "metadata": {}, + "outputs": [], + "source": [ + "dspacing_graph = {\n", + " **scn.conversion.graph.beamline.beamline(scatter=True),\n", + " **scn.conversion.graph.tof.elastic_dspacing('tof')\n", + " }\n", + "\n", + "dg_si_dsp = dg_si_wlgth_norm.transform_coords(['dspacing', 'two_theta'], graph=dspacing_graph)\n", + "dg_van_dsp = dg_van_wlgth_norm.transform_coords(['dspacing', 'two_theta'], graph=dspacing_graph)" + ] + }, + { + "cell_type": "markdown", + "id": "a19aeb2f-6657-478c-84f4-93c8e607dbc3", + "metadata": {}, + "source": [ + "## Binning in d-spacing and two-theta\n", + "\n", + "We consider only the high-resolution and endcap backward detector banks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c9cf90d-cc7d-4073-bf10-aa633e58e7ad", + "metadata": {}, + "outputs": [], + "source": [ + "ttheta_bin_edges_per_bank = {}\n", + "si_norm_bin = sc.DataGroup()\n", + "van_norm_bin = sc.DataGroup()\n", + "\n", + "dspacing_bins = sc.linspace('dspacing', 0.55, 1.75, 601, unit='angstrom')\n", + "\n", + "for bank in ['endcap_backward', 'high_resolution']:\n", + " \n", + " ttheta_bin_edges_per_bank[bank] = (dg_si_dsp[bank].coords['two_theta'].min().value, \n", + " dg_si_dsp[bank].coords['two_theta'].max().value)\n", + "\n", + " twotheta_bins = sc.linspace('two_theta', \n", + " ttheta_bin_edges_per_bank[bank][0],\n", + " ttheta_bin_edges_per_bank[bank][1],\n", + " 181, unit='rad')\n", + "\n", + " si_norm_bin[bank] = dg_si_dsp[bank].bin(two_theta=twotheta_bins, dspacing=dspacing_bins)\n", + " van_norm_bin[bank] = dg_van_dsp[bank].bin(two_theta=twotheta_bins, dspacing=dspacing_bins)\n", + "\n", + "si_norm_bin" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d746dbb5-3554-49db-bcae-b94c2137a804", + "metadata": {}, + "outputs": [], + "source": [ + "p_hr = pp.plot(si_norm_bin['high_resolution'].bins.concat('event_time_zero').hist(), norm='log', title='high_resolution')\n", + "p_ebwd = pp.plot(si_norm_bin['endcap_backward'].bins.concat('event_time_zero').hist(), norm='log', title='endcap_backward')\n", + "\n", + "p_hr / p_ebwd" + ] + }, + { + "cell_type": "markdown", + "id": "4602fca2-2b25-4164-b726-79eb9191b02c", + "metadata": {}, + "source": [ + "## Normalize Si sample data by Vanadium" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "946156b7-d202-4513-93ad-7b34bdf9a6a3", + "metadata": {}, + "outputs": [], + "source": [ + "si_final_norm = si_norm_bin.hist() / van_norm_bin.hist()\n", + "cleaned_final_si = clean_all_dets(si_final_norm).sum('event_time_zero')\n", + "cleaned_final_si" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "602cf29b-554f-48d2-a172-66d7515c9d85", + "metadata": {}, + "outputs": [], + "source": [ + "fig = cleaned_final_si.sum('two_theta').plot()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "57131985-ea9b-47f7-a199-6cb70c3520b1", + "metadata": {}, + "outputs": [], + "source": [ + "theory = np.array([\n", + " 3.1353, 1.6374, 1.5677, 1.3576, 1.2458, 1.0451, 0.9600, 0.9179, 0.8281, 0.8187,\n", + " 0.7838, 0.7604, 0.7257, 0.7070, 0.6788, 0.6634, 0.6271, 0.6229, 0.6072, 0.5961,\n", + " 0.5693, 0.5543, 0.5458, 0.5250, 0.5226])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7002cfb4-fefd-4a5f-9c30-963014628f00", + "metadata": {}, + "outputs": [], + "source": [ + "for l in theory:\n", + " fig.ax.axvline(l, color='gray')\n", + "fig.canvas.draw()\n", + "fig.fig.set_size_inches((12., 4.))\n", + "fig" + ] + } + ], + "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" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/ess/dream/data.py b/src/ess/dream/data.py index 48d00ec7..aefe8f5c 100644 --- a/src/ess/dream/data.py +++ b/src/ess/dream/data.py @@ -27,6 +27,10 @@ def _make_pooch(): "DREAM_simple_pwd_workflow/Cave_TOF_Monitor_diam_in_can.dat": "md5:ef24f4a4186c628574046e6629e31611", # noqa: E501 "DREAM_simple_pwd_workflow/Cave_TOF_Monitor_van_can.dat": "md5:e63456c347fb36a362a0b5ae2556b3cf", # noqa: E501 "DREAM_simple_pwd_workflow/Cave_TOF_Monitor_vana_inc_coh.dat": "md5:701d66792f20eb283a4ce76bae0c8f8f", # noqa: E501 + "stap_demo_october_2024/268227_00024779_Si_BC_offset_240_deg.hdf": "md5:d0d89bcae5bee0619e0333adfda57d70", # noqa: E501 + "stap_demo_october_2024/268227_00024779_Vana_inc_BC_offset_240_deg_wlgth.hdf": "md5:fbc8bde80c8889eea6ccea6f3f8eb9b8", # noqa: E501 + "stap_demo_october_2024/Cave_TOF_Monitor_hf_si_bc240.dat": "md5:8cf6c0a1b42185662ddc579eda07d1e6", # noqa: E501 + "stap_demo_october_2024/Cave_TOF_Monitor_hf_vanainc_bc240.dat": "md5:a9d5593d363a1c1fc51eb86757d6fa81", # noqa: E501 }, ) @@ -146,3 +150,37 @@ def simulated_monitor_empty_can() -> str: This is the DREAM cave monitor for ``simulated_empty_can``. """ return get_path("DREAM_simple_pwd_workflow/Cave_TOF_Monitor_van_can.dat") + + +def stap_demo_2024_si_sample() -> str: + """ + Path to a file containing detector event data for a McStas/Geant4 simulation with a + silicon sample. + """ + return get_path("stap_demo_october_2024/268227_00024779_Si_BC_offset_240_deg.hdf") + + +def stap_demo_2024_vanadium_sample() -> str: + """ + Path to a file containing detector event data for a McStas/Geant4 simulation with a + vanadium sample. + """ + return get_path( + "stap_demo_october_2024/268227_00024779_Vana_inc_BC_offset_240_deg_wlgth.hdf" + ) + + +def stap_demo_2024_si_monitor() -> str: + """ + Path to a file containing histogrammed monitor data for a McStas/Geant4 simulation + with a silicon sample. + """ + return get_path("stap_demo_october_2024/Cave_TOF_Monitor_hf_si_bc240.dat") + + +def stap_demo_2024_vanadium_monitor() -> str: + """ + Path to a file containing histogrammed monitor data for a McStas/Geant4 simulation + with a vanadium sample. + """ + return get_path("stap_demo_october_2024/Cave_TOF_Monitor_hf_vanainc_bc240.dat") From d924580e7eba030cb14ea0a629a7a2860ba2a1f2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 14:31:02 +0000 Subject: [PATCH 2/4] Apply automatic formatting --- .../dream/dream-simulation-si-wfm.ipynb | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/docs/user-guide/dream/dream-simulation-si-wfm.ipynb b/docs/user-guide/dream/dream-simulation-si-wfm.ipynb index 71987e13..7307468f 100644 --- a/docs/user-guide/dream/dream-simulation-si-wfm.ipynb +++ b/docs/user-guide/dream/dream-simulation-si-wfm.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "33f8848d-d8c6-4e9f-8bdc-ae3010f0dc42", + "id": "0", "metadata": { "editable": true, "slideshow": { @@ -27,7 +27,7 @@ { "cell_type": "code", "execution_count": null, - "id": "de26f86e-69c6-4833-aee8-595c2d7c5443", + "id": "1", "metadata": {}, "outputs": [], "source": [ @@ -47,7 +47,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7356d2fd-0447-4307-bf80-def807b7da21", + "id": "2", "metadata": {}, "outputs": [], "source": [ @@ -180,7 +180,7 @@ }, { "cell_type": "markdown", - "id": "69b12cdf-d5d4-4164-b10b-cbc0f7edd030", + "id": "3", "metadata": {}, "source": [ "## Beamline properties\n", @@ -192,7 +192,7 @@ { "cell_type": "code", "execution_count": null, - "id": "45947845-8fdb-423e-9a58-da660e081335", + "id": "4", "metadata": {}, "outputs": [], "source": [ @@ -278,7 +278,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b1e19ad1-81bd-4242-97af-521a1e11499b", + "id": "5", "metadata": {}, "outputs": [], "source": [ @@ -295,7 +295,7 @@ { "cell_type": "code", "execution_count": null, - "id": "27a2de1a-5c9a-440d-8cf5-87dc27cfeeb7", + "id": "6", "metadata": {}, "outputs": [], "source": [ @@ -315,7 +315,7 @@ { "cell_type": "code", "execution_count": null, - "id": "486710b7-805d-400c-963b-94234fc085b0", + "id": "7", "metadata": {}, "outputs": [], "source": [ @@ -331,7 +331,7 @@ }, { "cell_type": "markdown", - "id": "e83ce604-ecc4-47d9-af60-976e049be787", + "id": "8", "metadata": { "editable": true, "slideshow": { @@ -360,7 +360,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b232fb62-1932-4656-9bda-b8255a652cce", + "id": "9", "metadata": {}, "outputs": [], "source": [ @@ -372,7 +372,7 @@ }, { "cell_type": "markdown", - "id": "b0356a2e-2eca-453a-b20d-be9603e5950f", + "id": "10", "metadata": {}, "source": [ "### Convert monitor data to wavelength" @@ -381,7 +381,7 @@ { "cell_type": "code", "execution_count": null, - "id": "bb151913-e544-4fec-a3a4-e8da66a24299", + "id": "11", "metadata": {}, "outputs": [], "source": [ @@ -419,7 +419,7 @@ }, { "cell_type": "markdown", - "id": "62e4487f-88e0-4f32-9b37-f65b0dbfe2b1", + "id": "12", "metadata": {}, "source": [ "## Load and process detector data\n", @@ -430,7 +430,7 @@ { "cell_type": "code", "execution_count": null, - "id": "00afd918-36e6-4905-a381-b4a0b287dc71", + "id": "13", "metadata": {}, "outputs": [], "source": [ @@ -444,7 +444,7 @@ }, { "cell_type": "markdown", - "id": "609b5eb1-51ab-4cb3-b48b-bddb2510d8cd", + "id": "14", "metadata": {}, "source": [ "### Conversion to wavelength" @@ -453,7 +453,7 @@ { "cell_type": "code", "execution_count": null, - "id": "55b85e57-4df3-434d-825a-fbf8522297d0", + "id": "15", "metadata": {}, "outputs": [], "source": [ @@ -477,7 +477,7 @@ }, { "cell_type": "markdown", - "id": "74f1bdb1-07ff-4953-ab66-d6b6ac085517", + "id": "16", "metadata": {}, "source": [ "## Normalize by integrated monitor counts" @@ -486,7 +486,7 @@ { "cell_type": "code", "execution_count": null, - "id": "a8684e23-ab95-4c0d-aa41-44b04c87c904", + "id": "17", "metadata": {}, "outputs": [], "source": [ @@ -498,7 +498,7 @@ }, { "cell_type": "markdown", - "id": "5ba44890-67d9-4db3-91fa-cbf5da23027e", + "id": "18", "metadata": {}, "source": [ "## Convert to d-spacing" @@ -507,7 +507,7 @@ { "cell_type": "code", "execution_count": null, - "id": "445413f6-029d-4fb2-a317-3171962d7334", + "id": "19", "metadata": {}, "outputs": [], "source": [ @@ -522,7 +522,7 @@ }, { "cell_type": "markdown", - "id": "a19aeb2f-6657-478c-84f4-93c8e607dbc3", + "id": "20", "metadata": {}, "source": [ "## Binning in d-spacing and two-theta\n", @@ -533,7 +533,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4c9cf90d-cc7d-4073-bf10-aa633e58e7ad", + "id": "21", "metadata": {}, "outputs": [], "source": [ @@ -562,7 +562,7 @@ { "cell_type": "code", "execution_count": null, - "id": "d746dbb5-3554-49db-bcae-b94c2137a804", + "id": "22", "metadata": {}, "outputs": [], "source": [ @@ -574,7 +574,7 @@ }, { "cell_type": "markdown", - "id": "4602fca2-2b25-4164-b726-79eb9191b02c", + "id": "23", "metadata": {}, "source": [ "## Normalize Si sample data by Vanadium" @@ -583,7 +583,7 @@ { "cell_type": "code", "execution_count": null, - "id": "946156b7-d202-4513-93ad-7b34bdf9a6a3", + "id": "24", "metadata": {}, "outputs": [], "source": [ @@ -595,7 +595,7 @@ { "cell_type": "code", "execution_count": null, - "id": "602cf29b-554f-48d2-a172-66d7515c9d85", + "id": "25", "metadata": {}, "outputs": [], "source": [ @@ -605,7 +605,7 @@ { "cell_type": "code", "execution_count": null, - "id": "57131985-ea9b-47f7-a199-6cb70c3520b1", + "id": "26", "metadata": {}, "outputs": [], "source": [ @@ -618,7 +618,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7002cfb4-fefd-4a5f-9c30-963014628f00", + "id": "27", "metadata": {}, "outputs": [], "source": [ From ff185702c99225188af49ea62bbfc7b2712459a7 Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Mon, 16 Dec 2024 15:58:25 +0100 Subject: [PATCH 3/4] formatting --- .../dream/dream-simulation-si-wfm.ipynb | 250 ++++++++++-------- 1 file changed, 137 insertions(+), 113 deletions(-) diff --git a/docs/user-guide/dream/dream-simulation-si-wfm.ipynb b/docs/user-guide/dream/dream-simulation-si-wfm.ipynb index 7307468f..9c7240ca 100644 --- a/docs/user-guide/dream/dream-simulation-si-wfm.ipynb +++ b/docs/user-guide/dream/dream-simulation-si-wfm.ipynb @@ -35,12 +35,7 @@ "import scipp as sc\n", "import scippneutron as scn\n", "import plopp as pp\n", - "import matplotlib.pyplot as plt\n", - "import ess.dream as dream\n", "from ess.dream import data as dream_data\n", - "import ipywidgets as ipw\n", - "import matplotlib.pyplot as plt\n", - "from scipp.constants import m_n, h\n", "import scippnexus as snx" ] }, @@ -52,7 +47,7 @@ "outputs": [], "source": [ "def _nonfinite_to_zero(\n", - " data: sc.DataGroup | sc.DataArray | sc.Dataset\n", + " data: sc.DataGroup | sc.DataArray | sc.Dataset,\n", ") -> sc.DataGroup | sc.DataArray | sc.Dataset:\n", " \"\"\"\n", " Replace NaN, positive and negative infs by zero\n", @@ -61,16 +56,12 @@ " replacement = sc.scalar(0.0, variance=0.0, unit=data.unit)\n", " else:\n", " replacement = sc.scalar(0.0, unit=data.unit)\n", - " return sc.nan_to_num(\n", - " data,\n", - " nan=replacement,\n", - " posinf=replacement,\n", - " neginf=replacement)\n", + " return sc.nan_to_num(data, nan=replacement, posinf=replacement, neginf=replacement)\n", "\n", "\n", "def clean_all_dets(\n", - " data: sc.DataGroup | sc.DataArray | sc.Dataset\n", - " ) -> sc.DataGroup | sc.DataArray | sc.Dataset:\n", + " data: sc.DataGroup | sc.DataArray | sc.Dataset,\n", + ") -> sc.DataGroup | sc.DataArray | sc.Dataset:\n", " \"\"\"Clean the data, removing NaNs.\"\"\"\n", " dg_out = sc.DataGroup()\n", " for item in data.keys():\n", @@ -81,61 +72,66 @@ "\n", "\n", "def load_dream_nxs(filename: str) -> sc.DataGroup:\n", - " \"\"\"\n", - " \"\"\"\n", + " \"\"\" \"\"\"\n", " dg_out = sc.DataGroup()\n", " pattern = \"_detector\"\n", - " period = (1.0 / sc.scalar(14., unit='Hz')).to(unit='ns')\n", + " period = (1.0 / sc.scalar(14.0, unit=\"Hz\")).to(unit=\"ns\")\n", "\n", " # temporarily hard-coding values of sample, source and cave monitor positions\n", " # until bug fix for DREAM NeXus file\n", - " source_position = sc.vector(value=np.array([-3.478, 0.0, -76550]), unit='mm')\n", - " sample_position = sc.vector(value=np.array([0.0, 0.0, 0.0]), unit='mm')\n", + " source_position = sc.vector(value=np.array([-3.478, 0.0, -76550]), unit=\"mm\")\n", + " sample_position = sc.vector(value=np.array([0.0, 0.0, 0.0]), unit=\"mm\")\n", "\n", " with snx.File(filename) as f:\n", - " inst = f['entry']['instrument']\n", + " inst = f[\"entry\"][\"instrument\"]\n", " for key in inst:\n", " if key.endswith(pattern):\n", " name = key.removesuffix(pattern)\n", " dg = inst[key][()]\n", - " da = dg[f'{name}_event_data']\n", - " #dg_out[name]['event'].variances = dg_out[name]['event'].values\n", + " da = dg[f\"{name}_event_data\"]\n", + " # dg_out[name]['event'].variances = dg_out[name]['event'].values\n", "\n", " # add position\n", - " da.coords['position'] = sc.spatial.as_vectors(\n", - " da.coords['x_pixel_offset'],\n", - " da.coords['y_pixel_offset'], \n", - " da.coords['z_pixel_offset'])\n", - " \n", + " da.coords[\"position\"] = sc.spatial.as_vectors(\n", + " da.coords[\"x_pixel_offset\"],\n", + " da.coords[\"y_pixel_offset\"],\n", + " da.coords[\"z_pixel_offset\"],\n", + " )\n", + "\n", " # add sample and source position\n", - " da.coords['source_position'] = source_position\n", - " da.coords['sample_position'] = sample_position\n", - " \n", + " da.coords[\"source_position\"] = source_position\n", + " da.coords[\"sample_position\"] = sample_position\n", + "\n", " # rename ToF\n", - " da.bins.coords['tof'] = da.bins.coords.pop('event_time_offset')\n", + " da.bins.coords[\"tof\"] = da.bins.coords.pop(\"event_time_offset\")\n", "\n", " # add variances\n", - " da.bins.constituents['data'].variances = da.bins.constituents['data'].values\n", - " \n", - " \n", + " da.bins.constituents[\"data\"].variances = da.bins.constituents[\n", + " \"data\"\n", + " ].values\n", + "\n", " # In the raw data, the tofs extend beyond 71ms.\n", " # This is thus not an event_time_offset.\n", " # In addition, there is only one event_time_zero for all events,\n", " # when there should be at least 2 because some tofs are larger than 71ms\n", - " \n", + "\n", " # Bin the data into bins with a 71ms period\n", - " da = da.bin(tof=sc.arange('tof', 3) * period)\n", + " da = da.bin(tof=sc.arange(\"tof\", 3) * period)\n", " # Add a event_time_zero coord for each bin, but not as bin edges, as all events in the same pulse have the same event_time_zero, hence the `[:2]`\n", - " da.coords['event_time_zero'] = (sc.scalar(1730450434078980000, unit='ns') + da.coords['tof'])[:2]\n", + " da.coords[\"event_time_zero\"] = (\n", + " sc.scalar(1730450434078980000, unit=\"ns\") + da.coords[\"tof\"]\n", + " )[:2]\n", " # Remove the meaningless tof coord at the top level\n", - " del da.coords['tof']\n", + " del da.coords[\"tof\"]\n", " # Remove the original (wrong) event_time_zero event coord inside the bins and rename the dim\n", - " del da.bins.coords['event_time_zero']\n", - " da = da.rename_dims(tof='event_time_zero')\n", + " del da.bins.coords[\"event_time_zero\"]\n", + " da = da.rename_dims(tof=\"event_time_zero\")\n", " # Compute a proper event_time_offset as tof % period\n", - " da.bins.coords['event_time_offset'] = (da.bins.coords.pop('tof') % period).to(unit='us')\n", + " da.bins.coords[\"event_time_offset\"] = (\n", + " da.bins.coords.pop(\"tof\") % period\n", + " ).to(unit=\"us\")\n", " dg_out[name] = da\n", - " \n", + "\n", " return dg_out\n", "\n", "\n", @@ -144,37 +140,33 @@ " Load histogrammed monitor data,\n", " making sure that the time-of-flight wraps around the pulse period.\n", " \"\"\"\n", - " tof, tof_count = np.loadtxt(file, usecols=(0, 1),\n", - " skiprows=42, unpack=True)\n", - "\n", - " raw_data = sc.DataArray(\n", - " data=sc.array(dims=['tof'], \n", - " values=tof_count, \n", - " unit='counts'),\n", - " coords={\n", - " 'tof': sc.array(dims=['tof'], values=tof*1000 , unit='ns')\n", - " })\n", - " raw_data = raw_data['tof', 0.* sc.Unit('ns'):1e8* sc.Unit('ns')].copy()\n", + " tof, tof_count = np.loadtxt(file, usecols=(0, 1), skiprows=42, unpack=True)\n", + "\n", + " raw_data = sc.DataArray(\n", + " data=sc.array(dims=[\"tof\"], values=tof_count, unit=\"counts\"),\n", + " coords={\"tof\": sc.array(dims=[\"tof\"], values=tof * 1000, unit=\"ns\")},\n", + " )\n", + " raw_data = raw_data[\"tof\", 0.0 * sc.Unit(\"ns\") : 1e8 * sc.Unit(\"ns\")].copy()\n", "\n", " # Convert coord to bin edges\n", - " tof = raw_data.coords['tof']\n", - " center = sc.midpoints(tof, dim='tof')\n", - " left = center['tof', 0:1] - (tof['tof', 1] - tof['tof', 0])\n", - " right = center['tof', -1] + (tof['tof', -1] - tof['tof', -2])\n", - " raw_data.coords['tof'] = sc.concat([left, center, right], 'tof')\n", - " \n", - " period = (1. / sc.scalar(14., unit='Hz')).to(unit=raw_data.coords['tof'].unit) \n", - " bins = sc.sort(sc.concat([raw_data.coords['tof'], period], 'tof'), 'tof')\n", + " tof = raw_data.coords[\"tof\"]\n", + " center = sc.midpoints(tof, dim=\"tof\")\n", + " left = center[\"tof\", 0:1] - (tof[\"tof\", 1] - tof[\"tof\", 0])\n", + " right = center[\"tof\", -1] + (tof[\"tof\", -1] - tof[\"tof\", -2])\n", + " raw_data.coords[\"tof\"] = sc.concat([left, center, right], \"tof\")\n", + "\n", + " period = (1.0 / sc.scalar(14.0, unit=\"Hz\")).to(unit=raw_data.coords[\"tof\"].unit)\n", + " bins = sc.sort(sc.concat([raw_data.coords[\"tof\"], period], \"tof\"), \"tof\")\n", " raw_data = raw_data.rebin(tof=bins)\n", - " part1 = raw_data['tof', :period].copy()\n", - " part2 = raw_data['tof', period:].copy()\n", - " part2.coords['tof'] = part2.coords['tof'] % period\n", - " bins = sc.linspace('tof', 0, period.value, 513, unit=period.unit)\n", - " \n", + " part1 = raw_data[\"tof\", :period].copy()\n", + " part2 = raw_data[\"tof\", period:].copy()\n", + " part2.coords[\"tof\"] = part2.coords[\"tof\"] % period\n", + " bins = sc.linspace(\"tof\", 0, period.value, 513, unit=period.unit)\n", + "\n", " out = part2.rebin(tof=bins) + part1.rebin(tof=bins)\n", - " out = out.rename(tof='time_of_flight')\n", + " out = out.rename(tof=\"time_of_flight\")\n", "\n", - " out.coords['Ltotal'] = sc.scalar(np.sqrt(3.478**2 + 72330**2), unit='mm')\n", + " out.coords[\"Ltotal\"] = sc.scalar(np.sqrt(3.478**2 + 72330**2), unit=\"mm\")\n", " return out" ] }, @@ -299,10 +291,10 @@ "metadata": {}, "outputs": [], "source": [ - "pulse_tmin = sc.scalar(0., unit='ms')\n", - "pulse_tmax = sc.scalar(5., unit='ms')\n", - "pulse_wmin = sc.scalar(0.2, unit='angstrom')\n", - "pulse_wmax = sc.scalar(20., unit='angstrom')\n", + "pulse_tmin = sc.scalar(0.0, unit=\"ms\")\n", + "pulse_tmax = sc.scalar(5.0, unit=\"ms\")\n", + "pulse_wmin = sc.scalar(0.2, unit=\"angstrom\")\n", + "pulse_wmax = sc.scalar(20.0, unit=\"angstrom\")\n", "\n", "frames = chopper_cascade.FrameSequence.from_source_pulse(\n", " time_min=pulse_tmin,\n", @@ -323,7 +315,7 @@ "chopped = frames.chop(choppers.values())\n", "\n", "# Propagate the neutrons to the detector\n", - "at_detector = chopped.propagate_to(sc.scalar(76.5, unit='m'))\n", + "at_detector = chopped.propagate_to(sc.scalar(76.5, unit=\"m\"))\n", "\n", "# Visualize the results\n", "cascade_fig, cascade_ax = at_detector.draw()" @@ -367,7 +359,9 @@ "tof_mon_cave_si = load_monitor(dream_data.stap_demo_2024_si_monitor())\n", "tof_mon_cave_van = load_monitor(dream_data.stap_demo_2024_vanadium_monitor())\n", "\n", - "tof_mon_cave_si.plot(grid=True, title='Si Cave tof monitor') + tof_mon_cave_van.plot(grid=True, title='Vana Cave tof monitor')" + "tof_mon_cave_si.plot(grid=True, title=\"Si Cave tof monitor\") + tof_mon_cave_van.plot(\n", + " grid=True, title=\"Vana Cave tof monitor\"\n", + ")" ] }, { @@ -386,7 +380,9 @@ "outputs": [], "source": [ "# Setup workflow\n", - "pl = sl.Pipeline((*unwrap.providers(), unwrap.re_histogram_tof_data), params=unwrap.params())\n", + "pl = sl.Pipeline(\n", + " (*unwrap.providers(), unwrap.re_histogram_tof_data), params=unwrap.params()\n", + ")\n", "pl[unwrap.PulsePeriod] = 1.0 / sc.scalar(14.0, unit=\"Hz\")\n", "\n", "pl[unwrap.SourceTimeRange] = pulse_tmin, pulse_tmax\n", @@ -395,26 +391,30 @@ "\n", "# Si sample\n", "pl[unwrap.RawData] = tof_mon_cave_si\n", - "pl[unwrap.Ltotal] = tof_mon_cave_si.coords['Ltotal']\n", + "pl[unwrap.Ltotal] = tof_mon_cave_si.coords[\"Ltotal\"]\n", "tofs_si = pl.compute(unwrap.ReHistogrammedTofData)\n", "\n", "# Vanadium sample\n", "pl[unwrap.RawData] = tof_mon_cave_van\n", - "pl[unwrap.Ltotal] = tof_mon_cave_van.coords['Ltotal']\n", + "pl[unwrap.Ltotal] = tof_mon_cave_van.coords[\"Ltotal\"]\n", "tofs_van = pl.compute(unwrap.ReHistogrammedTofData)\n", "\n", "\n", "# Convert to wavelength\n", "wlgth_graph_monitor = {\n", " **scn.conversion.graph.beamline.beamline(scatter=False),\n", - " **scn.conversion.graph.tof.elastic_wavelength('tof'),\n", + " **scn.conversion.graph.tof.elastic_wavelength(\"tof\"),\n", "}\n", "\n", - "mon_cave_si_wlgth = tofs_si.transform_coords('wavelength', graph=wlgth_graph_monitor)\n", - "mon_cave_van_wlgth = tofs_van.transform_coords('wavelength', graph=wlgth_graph_monitor)\n", + "mon_cave_si_wlgth = tofs_si.transform_coords(\"wavelength\", graph=wlgth_graph_monitor)\n", + "mon_cave_van_wlgth = tofs_van.transform_coords(\"wavelength\", graph=wlgth_graph_monitor)\n", "\n", "# Plot\n", - "mon_cave_si_wlgth.plot(title='Monitor for Si sample in wavelength', grid=True) + mon_cave_van_wlgth.plot(title='Monitor for Vanadium sample in wavelength', grid=True)" + "mon_cave_si_wlgth.plot(\n", + " title=\"Monitor for Si sample in wavelength\", grid=True\n", + ") + mon_cave_van_wlgth.plot(\n", + " title=\"Monitor for Vanadium sample in wavelength\", grid=True\n", + ")" ] }, { @@ -459,20 +459,20 @@ "source": [ "detector_graph = {\n", " **scn.conversion.graph.beamline.beamline(scatter=True),\n", - " **scn.conversion.graph.tof.elastic_wavelength('tof'),\n", + " **scn.conversion.graph.tof.elastic_wavelength(\"tof\"),\n", "}\n", "\n", "dg_si_wlgth = sc.DataGroup()\n", "dg_van_wlgth = sc.DataGroup()\n", "\n", - "for (run, out) in ((sample, dg_si_wlgth), (vana, dg_van_wlgth)):\n", + "for run, out in ((sample, dg_si_wlgth), (vana, dg_van_wlgth)):\n", " for key, val in run.items():\n", - " da = val.transform_coords(['Ltotal'], graph=detector_graph)\n", + " da = val.transform_coords([\"Ltotal\"], graph=detector_graph)\n", " pl[unwrap.RawData] = da\n", - " pl[unwrap.Ltotal] = da.coords['Ltotal']\n", - " \n", + " pl[unwrap.Ltotal] = da.coords[\"Ltotal\"]\n", + "\n", " result = pl.compute(unwrap.TofData)\n", - " out[key] = result.transform_coords('wavelength', graph=detector_graph)" + " out[key] = result.transform_coords(\"wavelength\", graph=detector_graph)" ] }, { @@ -512,12 +512,16 @@ "outputs": [], "source": [ "dspacing_graph = {\n", - " **scn.conversion.graph.beamline.beamline(scatter=True),\n", - " **scn.conversion.graph.tof.elastic_dspacing('tof')\n", - " }\n", + " **scn.conversion.graph.beamline.beamline(scatter=True),\n", + " **scn.conversion.graph.tof.elastic_dspacing(\"tof\"),\n", + "}\n", "\n", - "dg_si_dsp = dg_si_wlgth_norm.transform_coords(['dspacing', 'two_theta'], graph=dspacing_graph)\n", - "dg_van_dsp = dg_van_wlgth_norm.transform_coords(['dspacing', 'two_theta'], graph=dspacing_graph)" + "dg_si_dsp = dg_si_wlgth_norm.transform_coords(\n", + " [\"dspacing\", \"two_theta\"], graph=dspacing_graph\n", + ")\n", + "dg_van_dsp = dg_van_wlgth_norm.transform_coords(\n", + " [\"dspacing\", \"two_theta\"], graph=dspacing_graph\n", + ")" ] }, { @@ -541,20 +545,29 @@ "si_norm_bin = sc.DataGroup()\n", "van_norm_bin = sc.DataGroup()\n", "\n", - "dspacing_bins = sc.linspace('dspacing', 0.55, 1.75, 601, unit='angstrom')\n", + "dspacing_bins = sc.linspace(\"dspacing\", 0.55, 1.75, 601, unit=\"angstrom\")\n", "\n", - "for bank in ['endcap_backward', 'high_resolution']:\n", - " \n", - " ttheta_bin_edges_per_bank[bank] = (dg_si_dsp[bank].coords['two_theta'].min().value, \n", - " dg_si_dsp[bank].coords['two_theta'].max().value)\n", + "for bank in [\"endcap_backward\", \"high_resolution\"]:\n", "\n", - " twotheta_bins = sc.linspace('two_theta', \n", - " ttheta_bin_edges_per_bank[bank][0],\n", - " ttheta_bin_edges_per_bank[bank][1],\n", - " 181, unit='rad')\n", + " ttheta_bin_edges_per_bank[bank] = (\n", + " dg_si_dsp[bank].coords[\"two_theta\"].min().value,\n", + " dg_si_dsp[bank].coords[\"two_theta\"].max().value,\n", + " )\n", "\n", - " si_norm_bin[bank] = dg_si_dsp[bank].bin(two_theta=twotheta_bins, dspacing=dspacing_bins)\n", - " van_norm_bin[bank] = dg_van_dsp[bank].bin(two_theta=twotheta_bins, dspacing=dspacing_bins)\n", + " twotheta_bins = sc.linspace(\n", + " \"two_theta\",\n", + " ttheta_bin_edges_per_bank[bank][0],\n", + " ttheta_bin_edges_per_bank[bank][1],\n", + " 181,\n", + " unit=\"rad\",\n", + " )\n", + "\n", + " si_norm_bin[bank] = dg_si_dsp[bank].bin(\n", + " two_theta=twotheta_bins, dspacing=dspacing_bins\n", + " )\n", + " van_norm_bin[bank] = dg_van_dsp[bank].bin(\n", + " two_theta=twotheta_bins, dspacing=dspacing_bins\n", + " )\n", "\n", "si_norm_bin" ] @@ -566,8 +579,16 @@ "metadata": {}, "outputs": [], "source": [ - "p_hr = pp.plot(si_norm_bin['high_resolution'].bins.concat('event_time_zero').hist(), norm='log', title='high_resolution')\n", - "p_ebwd = pp.plot(si_norm_bin['endcap_backward'].bins.concat('event_time_zero').hist(), norm='log', title='endcap_backward')\n", + "p_hr = pp.plot(\n", + " si_norm_bin[\"high_resolution\"].bins.concat(\"event_time_zero\").hist(),\n", + " norm=\"log\",\n", + " title=\"high_resolution\",\n", + ")\n", + "p_ebwd = pp.plot(\n", + " si_norm_bin[\"endcap_backward\"].bins.concat(\"event_time_zero\").hist(),\n", + " norm=\"log\",\n", + " title=\"endcap_backward\",\n", + ")\n", "\n", "p_hr / p_ebwd" ] @@ -588,7 +609,7 @@ "outputs": [], "source": [ "si_final_norm = si_norm_bin.hist() / van_norm_bin.hist()\n", - "cleaned_final_si = clean_all_dets(si_final_norm).sum('event_time_zero')\n", + "cleaned_final_si = clean_all_dets(si_final_norm).sum(\"event_time_zero\")\n", "cleaned_final_si" ] }, @@ -599,7 +620,7 @@ "metadata": {}, "outputs": [], "source": [ - "fig = cleaned_final_si.sum('two_theta').plot()" + "fig = cleaned_final_si.sum(\"two_theta\").plot()" ] }, { @@ -609,10 +630,13 @@ "metadata": {}, "outputs": [], "source": [ - "theory = np.array([\n", - " 3.1353, 1.6374, 1.5677, 1.3576, 1.2458, 1.0451, 0.9600, 0.9179, 0.8281, 0.8187,\n", - " 0.7838, 0.7604, 0.7257, 0.7070, 0.6788, 0.6634, 0.6271, 0.6229, 0.6072, 0.5961,\n", - " 0.5693, 0.5543, 0.5458, 0.5250, 0.5226])" + "theory = np.array(\n", + " [\n", + " 3.1353, 1.6374, 1.5677, 1.3576, 1.2458, 1.0451, 0.9600, 0.9179, 0.8281,\n", + " 0.8187, 0.7838, 0.7604, 0.7257, 0.7070, 0.6788, 0.6634, 0.6271, 0.6229,\n", + " 0.6072, 0.5961, 0.5693, 0.5543, 0.5458, 0.5250, 0.5226,\n", + " ]\n", + ")" ] }, { @@ -622,10 +646,10 @@ "metadata": {}, "outputs": [], "source": [ - "for l in theory:\n", - " fig.ax.axvline(l, color='gray')\n", + "for line in theory:\n", + " fig.ax.axvline(line, color=\"gray\")\n", "fig.canvas.draw()\n", - "fig.fig.set_size_inches((12., 4.))\n", + "fig.fig.set_size_inches((12.0, 4.0))\n", "fig" ] } From e7ddb8a7702d7a611e9a0966e6188decfd3a8edd Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Tue, 17 Dec 2024 10:32:54 +0100 Subject: [PATCH 4/4] update deps to get new scippneutron --- requirements/base.txt | 20 +++++++++----------- requirements/basetest.txt | 8 ++++---- requirements/ci.txt | 2 +- requirements/dev.txt | 18 ++++++++---------- requirements/docs.txt | 12 ++++++------ requirements/nightly.txt | 10 +++++----- 6 files changed, 33 insertions(+), 37 deletions(-) diff --git a/requirements/base.txt b/requirements/base.txt index 153660af..e34e07ed 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -5,7 +5,7 @@ # # pip-compile-multi # -asttokens==2.4.1 +asttokens==3.0.0 # via stack-data click==8.1.7 # via dask @@ -19,7 +19,7 @@ cyclebane==24.10.0 # via sciline cycler==0.12.1 # via matplotlib -dask==2024.11.2 +dask==2024.12.0 # via -r base.in decorator==5.1.1 # via ipython @@ -29,7 +29,7 @@ exceptiongroup==1.2.2 # via ipython executing==2.1.0 # via stack-data -fonttools==4.55.0 +fonttools==4.55.3 # via matplotlib fsspec==2024.10.0 # via dask @@ -43,7 +43,7 @@ importlib-metadata==8.5.0 # via dask ipydatawidgets==4.3.5 # via pythreejs -ipython==8.29.0 +ipython==8.30.0 # via ipywidgets ipywidgets==8.1.5 # via @@ -57,7 +57,7 @@ kiwisolver==1.4.7 # via matplotlib locket==1.0.0 # via partd -matplotlib==3.9.2 +matplotlib==3.10.0 # via # mpltoolbox # plopp @@ -67,7 +67,7 @@ mpltoolbox==24.5.1 # via scippneutron networkx==3.4.2 # via cyclebane -numpy==2.1.3 +numpy==2.2.0 # via # -r base.in # contourpy @@ -123,7 +123,7 @@ scipp==24.11.2 # essreduce # scippneutron # scippnexus -scippneutron==24.11.0 +scippneutron==24.12.0 # via # -r base.in # essreduce @@ -136,10 +136,8 @@ scipy==1.14.1 # via # scippneutron # scippnexus -six==1.16.0 - # via - # asttokens - # python-dateutil +six==1.17.0 + # via python-dateutil stack-data==0.6.3 # via ipython toolz==1.0.0 diff --git a/requirements/basetest.txt b/requirements/basetest.txt index ad1f8e94..906d87e8 100644 --- a/requirements/basetest.txt +++ b/requirements/basetest.txt @@ -5,7 +5,7 @@ # # pip-compile-multi # -certifi==2024.8.30 +certifi==2024.12.14 # via requests charset-normalizer==3.4.0 # via requests @@ -15,7 +15,7 @@ idna==3.10 # via requests iniconfig==2.0.0 # via pytest -numpy==2.1.3 +numpy==2.2.0 # via pandas packaging==24.2 # via @@ -29,7 +29,7 @@ pluggy==1.5.0 # via pytest pooch==1.8.2 # via -r basetest.in -pytest==8.3.3 +pytest==8.3.4 # via -r basetest.in python-dateutil==2.9.0.post0 # via pandas @@ -37,7 +37,7 @@ pytz==2024.2 # via pandas requests==2.32.3 # via pooch -six==1.16.0 +six==1.17.0 # via python-dateutil tomli==2.2.1 # via pytest diff --git a/requirements/ci.txt b/requirements/ci.txt index 045acba6..c3ccdde1 100644 --- a/requirements/ci.txt +++ b/requirements/ci.txt @@ -7,7 +7,7 @@ # cachetools==5.5.0 # via tox -certifi==2024.8.30 +certifi==2024.12.14 # via requests chardet==5.2.0 # via tox diff --git a/requirements/dev.txt b/requirements/dev.txt index d7d5de02..d77a0233 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -14,7 +14,7 @@ -r wheels.txt annotated-types==0.7.0 # via pydantic -anyio==4.6.2.post1 +anyio==4.7.0 # via # httpx # jupyter-server @@ -40,7 +40,7 @@ h11==0.14.0 # via httpcore httpcore==1.0.7 # via httpx -httpx==0.27.2 +httpx==0.28.1 # via jupyterlab isoduration==20.11.0 # via jsonschema @@ -67,7 +67,7 @@ jupyter-server==2.14.2 # notebook-shim jupyter-server-terminals==0.5.3 # via jupyter-server -jupyterlab==4.3.1 +jupyterlab==4.3.3 # via -r dev.in jupyterlab-server==2.27.3 # via jupyterlab @@ -83,15 +83,15 @@ pip-tools==7.4.1 # via pip-compile-multi plumbum==1.9.0 # via copier -prometheus-client==0.21.0 +prometheus-client==0.21.1 # via jupyter-server pycparser==2.22 # via cffi -pydantic==2.10.2 +pydantic==2.10.3 # via copier pydantic-core==2.27.1 # via pydantic -python-json-logger==2.0.7 +python-json-logger==3.2.1 # via jupyter-events questionary==1.10.0 # via copier @@ -106,16 +106,14 @@ rfc3986-validator==0.1.1 send2trash==1.8.3 # via jupyter-server sniffio==1.3.1 - # via - # anyio - # httpx + # via anyio terminado==0.18.1 # via # jupyter-server # jupyter-server-terminals toposort==1.10 # via pip-compile-multi -types-python-dateutil==2.9.0.20241003 +types-python-dateutil==2.9.0.20241206 # via arrow uri-template==1.3.0 # via jsonschema diff --git a/requirements/docs.txt b/requirements/docs.txt index 4dc07134..316cdbc4 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -10,7 +10,7 @@ accessible-pygments==0.0.5 # via pydata-sphinx-theme alabaster==1.0.0 # via sphinx -attrs==24.2.0 +attrs==24.3.0 # via # jsonschema # referencing @@ -24,11 +24,11 @@ beautifulsoup4==4.12.3 # pydata-sphinx-theme bleach==6.2.0 # via nbconvert -certifi==2024.8.30 +certifi==2024.12.14 # via requests charset-normalizer==3.4.0 # via requests -debugpy==1.8.9 +debugpy==1.8.11 # via ipykernel defusedxml==0.7.1 # via nbconvert @@ -40,7 +40,7 @@ docutils==0.21.2 # pydata-sphinx-theme # sphinx # sphinxcontrib-bibtex -fastjsonschema==2.21.0 +fastjsonschema==2.21.1 # via nbformat idna==3.10 # via requests @@ -93,7 +93,7 @@ mistune==3.0.2 # via nbconvert myst-parser==4.0.0 # via -r docs.in -nbclient==0.10.0 +nbclient==0.10.1 # via nbconvert nbconvert==7.16.4 # via nbsphinx @@ -142,7 +142,7 @@ requests==2.32.3 # via # pooch # sphinx -rpds-py==0.21.0 +rpds-py==0.22.3 # via # jsonschema # referencing diff --git a/requirements/nightly.txt b/requirements/nightly.txt index 7ccb8b60..85bf1099 100644 --- a/requirements/nightly.txt +++ b/requirements/nightly.txt @@ -6,7 +6,7 @@ # pip-compile-multi # -r basetest.txt -asttokens==2.4.1 +asttokens==3.0.0 # via stack-data click==8.1.7 # via dask @@ -20,7 +20,7 @@ cyclebane==24.10.0 # via sciline cycler==0.12.1 # via matplotlib -dask==2024.11.2 +dask==2024.12.0 # via -r nightly.in decorator==5.1.1 # via ipython @@ -28,7 +28,7 @@ essreduce @ git+https://github.com/scipp/essreduce@main # via -r nightly.in executing==2.1.0 # via stack-data -fonttools==4.55.0 +fonttools==4.55.3 # via matplotlib fsspec==2024.10.0 # via dask @@ -42,7 +42,7 @@ importlib-metadata==8.5.0 # via dask ipydatawidgets==4.3.5 # via pythreejs -ipython==8.29.0 +ipython==8.30.0 # via ipywidgets ipywidgets==8.1.5 # via @@ -56,7 +56,7 @@ kiwisolver==1.4.7 # via matplotlib locket==1.0.0 # via partd -matplotlib==3.9.2 +matplotlib==3.10.0 # via # mpltoolbox # plopp