|
117 | 117 | "# Direct measurement is with the empty sample holder/cuvette\n",
|
118 | 118 | "direct = loki.io.load_sans2d(filename=loki.data.get_path('SANS2D00063091.hdf5'))\n",
|
119 | 119 | "# Load direct beam function for main detector\n",
|
120 |
| - "direct_beam = sc.io.open_hdf5(loki.data.get_path('DIRECT_SANS2D_REAR_34327_4m_8mm_16Feb16.hdf5'))\n", |
| 120 | + "direct_beam = sc.io.load_hdf5(loki.data.get_path('DIRECT_SANS2D_REAR_34327_4m_8mm_16Feb16.hdf5'))\n", |
121 | 121 | "# Inspect sample data\n",
|
122 | 122 | "sample"
|
123 | 123 | ]
|
|
127 | 127 | "id": "c4569a53-a19a-440e-8aa0-63df29f67d05",
|
128 | 128 | "metadata": {},
|
129 | 129 | "source": [
|
130 |
| - "## Inspect monitor data\n", |
| 130 | + "## Inspecting the monitor data\n", |
131 | 131 | "\n",
|
132 | 132 | "The monitor counts play a major role in normalizing the detector counts.\n",
|
133 | 133 | "From the two loaded runs, we extract the data from the incident and transmission monitors."
|
|
261 | 261 | },
|
262 | 262 | "outputs": [],
|
263 | 263 | "source": [
|
264 |
| - "monitors = sans.i_of_q.preprocess_monitor_data(\n", |
| 264 | + "processed_monitors = sans.i_of_q.preprocess_monitor_data(\n", |
265 | 265 | " monitors,\n",
|
266 | 266 | " non_background_range=non_background_range,\n",
|
267 | 267 | " wavelength_bins=wavelength_bins)\n",
|
268 | 268 | "\n",
|
269 | 269 | "sample_monitors = {\n",
|
270 |
| - " 'incident': monitors['sample-incident'],\n", |
271 |
| - " 'transmission': monitors['sample-transmission']\n", |
| 270 | + " 'incident': processed_monitors['sample-incident'],\n", |
| 271 | + " 'transmission': processed_monitors['sample-transmission']\n", |
272 | 272 | "}\n",
|
273 | 273 | "direct_monitors = {\n",
|
274 |
| - " 'incident': monitors['direct-incident'],\n", |
275 |
| - " 'transmission': monitors['direct-transmission']\n", |
| 274 | + " 'incident': processed_monitors['direct-incident'],\n", |
| 275 | + " 'transmission': processed_monitors['direct-transmission']\n", |
276 | 276 | "}"
|
277 | 277 | ]
|
278 | 278 | },
|
|
623 | 623 | "sc.plot(direct_beam)"
|
624 | 624 | ]
|
625 | 625 | },
|
626 |
| - { |
627 |
| - "cell_type": "markdown", |
628 |
| - "id": "894e8329-8987-4565-b070-5d262af746d8", |
629 |
| - "metadata": {}, |
630 |
| - "source": [ |
631 |
| - "### Solid Angle\n", |
632 |
| - "\n", |
633 |
| - "The `sans.normalization` module also provides a utility to compute the solid angles of rectangular detector pixels:" |
634 |
| - ] |
635 |
| - }, |
636 |
| - { |
637 |
| - "cell_type": "code", |
638 |
| - "execution_count": null, |
639 |
| - "id": "e126e749-3dad-4ad8-a6f9-2d446e0153e4", |
640 |
| - "metadata": { |
641 |
| - "tags": [] |
642 |
| - }, |
643 |
| - "outputs": [], |
644 |
| - "source": [ |
645 |
| - "solid_angle = sans.normalization.solid_angle_of_rectangular_pixels(\n", |
646 |
| - " sample,\n", |
647 |
| - " pixel_width=sample.coords['pixel_width'],\n", |
648 |
| - " pixel_height=sample.coords['pixel_height'])\n", |
649 |
| - "solid_angle" |
650 |
| - ] |
651 |
| - }, |
652 | 626 | {
|
653 | 627 | "cell_type": "markdown",
|
654 | 628 | "id": "92b7cba6-c4aa-458f-8564-a0c265cf4332",
|
|
657 | 631 | "### The denominator term\n",
|
658 | 632 | "\n",
|
659 | 633 | "We combine all the terms above to compute the `denominator`.\n",
|
660 |
| - "We then attach to the denominator some coordinates required to perform the conversion to $Q$." |
| 634 | + "\n", |
| 635 | + "**Note:**\n", |
| 636 | + "\n", |
| 637 | + "[Heybrock et al. (2023)](#heybrock2023) describe how broadcasting operations introduce correlations which are not tracked by Scipp's uncertainty propagation.\n", |
| 638 | + "In the normalization term above, multiplying $M(\\lambda)T(\\lambda)D(\\lambda)$ (wavelength dependent) by the solid angle $\\Omega(R)$ (pixel dependent) is such a broadcasting operation.\n", |
| 639 | + "The article however states that for normalization operations, under the limit where the counts of the numerator a much smaller than that of the denominator,\n", |
| 640 | + "dropping the variances of the denominator is a satisfactory approximation.\n", |
| 641 | + "\n", |
| 642 | + "The helper function below internally calculates the solid angles of the detector pixels $\\Omega(R)$,\n", |
| 643 | + "and performs a verification that our data satisfies that condition.\n", |
| 644 | + "\n", |
| 645 | + "We are not able to perform this check earlier in the workflow, because the verification involves comparing integrated counts,\n", |
| 646 | + "and the integration needs to be performed over the same wavelength range for both the monitors and the detector counts.\n", |
| 647 | + "To be able to compute the wavelengths of the detector data, we needed to first run the beam center finder." |
661 | 648 | ]
|
662 | 649 | },
|
663 | 650 | {
|
664 | 651 | "cell_type": "code",
|
665 | 652 | "execution_count": null,
|
666 |
| - "id": "30250d51-0d6f-4265-b372-881900a16e2a", |
| 653 | + "id": "fc07f7b3-73dd-410d-9c1c-905d579a97cf", |
667 | 654 | "metadata": {
|
668 | 655 | "tags": []
|
669 | 656 | },
|
670 | 657 | "outputs": [],
|
671 | 658 | "source": [
|
672 |
| - "denominator = sans.normalization.compute_denominator(\n", |
673 |
| - " direct_beam=direct_beam,\n", |
674 |
| - " data_incident_monitor=sample_monitors['incident'],\n", |
675 |
| - " transmission_fraction=transmission_fraction,\n", |
676 |
| - " solid_angle=solid_angle)\n", |
| 659 | + "denominator = sans.normalization.iofq_denominator(\n", |
| 660 | + " data=sample,\n", |
| 661 | + " data_transmission_monitor=sample_monitors['transmission'],\n", |
| 662 | + " direct_incident_monitor=direct_monitors['incident'],\n", |
| 663 | + " direct_transmission_monitor=direct_monitors['transmission'],\n", |
| 664 | + " direct_beam=direct_beam\n", |
| 665 | + " )\n", |
| 666 | + "\n", |
677 | 667 | "# Insert a copy of coords needed for conversion to Q.\n",
|
678 | 668 | "# TODO: can this be avoided by copying the Q coords from the converted numerator?\n",
|
679 | 669 | "for coord in ['position', 'sample_position', 'source_position']:\n",
|
|
826 | 816 | },
|
827 | 817 | {
|
828 | 818 | "cell_type": "markdown",
|
829 |
| - "id": "faf45578-6b6a-4046-82aa-4864a2e8bb8b", |
| 819 | + "id": "cf7ef2db-6ea0-4ea8-a0c4-04ef96831596", |
830 | 820 | "metadata": {},
|
831 | 821 | "source": [
|
832 | 822 | "<div id='heenan1997'></div>\n",
|
|
836 | 826 | "[J. Appl. Cryst., 30, 1140-1147](https://doi.org/10.1107/S0021889897002173)"
|
837 | 827 | ]
|
838 | 828 | },
|
| 829 | + { |
| 830 | + "cell_type": "markdown", |
| 831 | + "id": "faf45578-6b6a-4046-82aa-4864a2e8bb8b", |
| 832 | + "metadata": {}, |
| 833 | + "source": [ |
| 834 | + "<div id='heybrock2023'></div>\n", |
| 835 | + "\n", |
| 836 | + "Heybrock S., Wynen J.-L., Vaytet N., **2023**,\n", |
| 837 | + "*Systematic underestimation of uncertainties by widespread neutron-scattering data-reduction software*,\n", |
| 838 | + "Journal of Neutron Research" |
| 839 | + ] |
| 840 | + }, |
839 | 841 | {
|
840 | 842 | "cell_type": "markdown",
|
841 | 843 | "id": "4ca6948e-ed72-49de-8529-4faf1474535c",
|
|
0 commit comments