Skip to content

Commit

Permalink
Merge pull request #136 from scipp/ux-readability
Browse files Browse the repository at this point in the history
UX: Improve readability for ISIS workflows
  • Loading branch information
SimonHeybrock committed May 7, 2024
2 parents e4e9a69 + 445128c commit 53f868a
Show file tree
Hide file tree
Showing 22 changed files with 800 additions and 639 deletions.
129 changes: 78 additions & 51 deletions docs/user-guide/common/beam-center-finder.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
"source": [
"import scipp as sc\n",
"import plopp as pp\n",
"import sciline\n",
"from ess import sans\n",
"from ess import isissans as isis\n",
"from ess.sans.types import *"
Expand All @@ -38,27 +37,23 @@
"id": "e84bd5a5-8bed-459b-ad8c-0d04aa6117e0",
"metadata": {},
"source": [
"## Setting up the pipeline\n",
"## Create and configure the workflow\n",
"\n",
"We begin by setting some parameters for the pipeline,\n",
"We begin by setting creating a workflow and set some parameters,\n",
"as well as the name of the data file we wish to use."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "327a8b3c-fdde-45cd-9f29-dc33f9bb101d",
"id": "6bfb29ae",
"metadata": {},
"outputs": [],
"source": [
"params = isis.default_parameters()\n",
"params[Filename[SampleRun]] = 'SANS2D00063114.nxs'\n",
"\n",
"# Build the pipeline\n",
"providers = list(\n",
" sans.providers + isis.providers + isis.data.providers + isis.sans2d.providers\n",
")\n",
"pipeline = sciline.Pipeline(providers, params=params)"
"workflow = isis.sans2d.Sans2dTutorialWorkflow()\n",
"# For real data use:\n",
"# workflow = isis.sans2d.Sans2dWorkflow()\n",
"workflow[Filename[SampleRun]] = isis.data.sans2d_tutorial_sample_run()"
]
},
{
Expand All @@ -80,7 +75,7 @@
"metadata": {},
"outputs": [],
"source": [
"raw = pipeline.compute(RawData[SampleRun])['spectrum', :61440]\n",
"raw = workflow.compute(RawData[SampleRun])['spectrum', :61440]\n",
"\n",
"p = isis.plot_flat_detector_xy(raw.hist(), norm='log')\n",
"p.ax.plot(0, 0, '+', color='k', ms=10)\n",
Expand Down Expand Up @@ -132,7 +127,7 @@
"metadata": {},
"outputs": [],
"source": [
"masked = pipeline.compute(MaskedData[SampleRun])['spectrum', :61440].copy()\n",
"masked = workflow.compute(MaskedData[SampleRun])['spectrum', :61440].copy()\n",
"masked.masks['low_counts'] = masked.hist().data < sc.scalar(80.0, unit='counts')\n",
"\n",
"p = isis.plot_flat_detector_xy(masked.hist(), norm='log')\n",
Expand Down Expand Up @@ -161,8 +156,8 @@
"outputs": [],
"source": [
"# Insert the provider that computes the center-of-mass of the pixels\n",
"pipeline.insert(sans.beam_center_finder.beam_center_from_center_of_mass)\n",
"pipeline.visualize(BeamCenter, graph_attr={'rankdir': 'LR'})"
"workflow.insert(sans.beam_center_finder.beam_center_from_center_of_mass)\n",
"workflow.visualize(BeamCenter, graph_attr={'rankdir': 'LR'})"
]
},
{
Expand All @@ -172,7 +167,7 @@
"metadata": {},
"outputs": [],
"source": [
"com = pipeline.compute(BeamCenter)\n",
"com = workflow.compute(BeamCenter)\n",
"com"
]
},
Expand Down Expand Up @@ -217,7 +212,7 @@
"1. Compute $I(Q)$ inside each quadrant and compute the residual difference between all 4 quadrants\n",
"1. Iteratively move the center position and repeat 1. and 2. until all 4 $I(Q)$ curves lie on top of each other\n",
"\n",
"For this, we need to set-up a fully-fledged pipeline that can compute $I(Q)$,\n",
"For this, we need to set-up a fully-fledged workflow that can compute $I(Q)$,\n",
"which requires some additional parameters (see the [SANS2D reduction workflow](../isis/sans2d.ipynb) for more details)."
]
},
Expand All @@ -239,42 +234,73 @@
"</div>"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eadbb74f",
"metadata": {},
"outputs": [],
"source": [
"workflow = isis.sans2d.Sans2dTutorialWorkflow()\n",
"# For real data use:\n",
"# workflow = isis.sans2d.Sans2dWorkflow()\n",
"\n",
"workflow.insert(isis.data.transmission_from_sample_run)\n",
"# Insert the provider that computes the center from I(Q) curves\n",
"workflow.insert(sans.beam_center_finder.beam_center_from_iofq)\n",
"workflow.visualize(BeamCenter, graph_attr={'rankdir': 'LR'})"
]
},
{
"cell_type": "markdown",
"id": "6e1c7413",
"metadata": {},
"source": [
"We set the missing input parameters:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f43d6ddd-6106-4b8e-bc81-5f7b98b58078",
"metadata": {},
"outputs": [],
"source": [
"params[WavelengthBins] = sc.linspace(\n",
"workflow[WavelengthBins] = sc.linspace(\n",
" 'wavelength', start=2.0, stop=16.0, num=141, unit='angstrom'\n",
")\n",
"params[Filename[EmptyBeamRun]] = 'SANS2D00063091.nxs'\n",
"workflow[Filename[EmptyBeamRun]] = isis.data.sans2d_tutorial_empty_beam_run()\n",
"\n",
"params[NeXusMonitorName[Incident]] = 'monitor2'\n",
"params[NeXusMonitorName[Transmission]] = 'monitor4'\n",
"workflow[NeXusMonitorName[Incident]] = 'monitor2'\n",
"workflow[NeXusMonitorName[Transmission]] = 'monitor4'\n",
"\n",
"params[isis.SampleOffset] = sc.vector([0.0, 0.0, 0.053], unit='m')\n",
"params[isis.MonitorOffset[Transmission]] = sc.vector([0.0, 0.0, -6.719], unit='m')\n",
"workflow[isis.SampleOffset] = sc.vector([0.0, 0.0, 0.053], unit='m')\n",
"workflow[isis.MonitorOffset[Transmission]] = sc.vector([0.0, 0.0, -6.719], unit='m')\n",
"\n",
"params[CorrectForGravity] = True\n",
"params[UncertaintyBroadcastMode] = UncertaintyBroadcastMode.upper_bound\n",
"params[sans.beam_center_finder.BeamCenterFinderQBins] = sc.linspace(\n",
"workflow[CorrectForGravity] = True\n",
"workflow[UncertaintyBroadcastMode] = UncertaintyBroadcastMode.upper_bound\n",
"workflow[sans.beam_center_finder.BeamCenterFinderQBins] = sc.linspace(\n",
" 'Q', 0.02, 0.25, 71, unit='1/angstrom'\n",
")\n",
"\n",
"providers.append(isis.data.transmission_from_sample_run)\n",
"\n",
"# Build the pipeline\n",
"pipeline = sciline.Pipeline(providers, params=params)\n",
"\n",
"# Insert the provider that computes the center from I(Q) curves\n",
"pipeline.insert(sans.beam_center_finder.beam_center_from_iofq)\n",
"\n",
"# Override with data that contains the new mask\n",
"pipeline[MaskedData[SampleRun]] = masked\n",
"\n",
"pipeline.visualize(BeamCenter, graph_attr={'rankdir': 'LR'})"
")"
]
},
{
"cell_type": "markdown",
"id": "641be8e9",
"metadata": {},
"source": [
"Finally, we set the data to be used, including overriding with data that contains the new mask defined earlier:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3f772512",
"metadata": {},
"outputs": [],
"source": [
"workflow[Filename[SampleRun]] = isis.data.sans2d_tutorial_sample_run()\n",
"workflow[MaskedData[SampleRun]] = masked"
]
},
{
Expand All @@ -296,7 +322,7 @@
"metadata": {},
"outputs": [],
"source": [
"iofq_center = pipeline.compute(BeamCenter)\n",
"iofq_center = workflow.compute(BeamCenter)\n",
"iofq_center"
]
},
Expand Down Expand Up @@ -405,12 +431,12 @@
"source": [
"kwargs = dict(\n",
" data=masked,\n",
" norm=pipeline.compute(NormWavelengthTerm[SampleRun]),\n",
" graph=pipeline.compute(sans.conversions.ElasticCoordTransformGraph),\n",
" q_bins=params[sans.beam_center_finder.BeamCenterFinderQBins],\n",
" wavelength_bins=params[WavelengthBins],\n",
" transform=pipeline.compute(LabFrameTransform[SampleRun]),\n",
" pixel_shape=pipeline.compute(DetectorPixelShape[SampleRun]),\n",
" norm=workflow.compute(NormWavelengthTerm[SampleRun]),\n",
" graph=workflow.compute(sans.conversions.ElasticCoordTransformGraph),\n",
" q_bins=workflow.compute(sans.beam_center_finder.BeamCenterFinderQBins),\n",
" wavelength_bins=workflow.compute(WavelengthBins),\n",
" transform=workflow.compute(LabFrameTransform[SampleRun]),\n",
" pixel_shape=workflow.compute(DetectorPixelShape[SampleRun]),\n",
")"
]
},
Expand Down Expand Up @@ -572,10 +598,10 @@
"\n",
"*Note*\n",
"\n",
"The result obtained just above is slightly different from the one obtained earlier [using the pipeline](#Method-2:-computing-I(Q)-inside-4-quadrants).\n",
"The result obtained just above is slightly different from the one obtained earlier [using the workflow](#Method-2:-computing-I(Q)-inside-4-quadrants).\n",
"\n",
"This is because in our example, we used `x=0, y=0` as our initial guess,\n",
"while the pipeline uses an additional optimization where it first computes a better initial guess using method 1 (center-of-mass).\n",
"while the workflow uses an additional optimization where it first computes a better initial guess using method 1 (center-of-mass).\n",
"This allows it to converge faster, with fewer iterations, and produce a slightly more accurate result.\n",
"\n",
"</div>"
Expand All @@ -597,7 +623,8 @@
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3"
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
Loading

0 comments on commit 53f868a

Please sign in to comment.