|
20 | 20 | "outputs": [],
|
21 | 21 | "source": [
|
22 | 22 | "import scipp as sc\n",
|
23 |
| - "from scippneutron.io import cif\n", |
| 23 | + "import scippneutron as scn\n", |
| 24 | + "import scippneutron.io\n", |
24 | 25 | "\n",
|
25 | 26 | "from ess import dream, powder\n",
|
26 | 27 | "import ess.dream.data # noqa: F401\n",
|
|
44 | 45 | "metadata": {},
|
45 | 46 | "outputs": [],
|
46 | 47 | "source": [
|
47 |
| - "workflow = dream.DreamGeant4Workflow()" |
| 48 | + "workflow = dream.DreamGeant4Workflow(run_norm=powder.RunNormalization.proton_charge)" |
48 | 49 | ]
|
49 | 50 | },
|
50 | 51 | {
|
|
74 | 75 | "workflow[DspacingBins] = sc.linspace(\"dspacing\", 0.0, 2.3434, 201, unit=\"angstrom\")\n",
|
75 | 76 | "# Mask in time-of-flight to crop to valid range\n",
|
76 | 77 | "workflow[TofMask] = lambda x: (x < sc.scalar(0.0, unit=\"ns\")) | (\n",
|
77 |
| - " x > sc.scalar(86e6, unit=\"ns\")\n", |
| 78 | + " x > sc.scalar(86e6, unit=\"ns\")\n", |
78 | 79 | ")\n",
|
79 | 80 | "workflow[TwoThetaMask] = None\n",
|
80 | 81 | "workflow[WavelengthMask] = None\n",
|
|
86 | 87 | "cell_type": "markdown",
|
87 | 88 | "id": "6",
|
88 | 89 | "metadata": {},
|
89 |
| - "source": [ |
90 |
| - "We also need some parameters to configure the output file:" |
91 |
| - ] |
92 |
| - }, |
93 |
| - { |
94 |
| - "cell_type": "code", |
95 |
| - "execution_count": null, |
96 |
| - "id": "7", |
97 |
| - "metadata": {}, |
98 |
| - "outputs": [], |
99 |
| - "source": [ |
100 |
| - "workflow[CIFAuthors] = CIFAuthors([\n", |
101 |
| - " cif.Author(\n", |
102 |
| - " name=\"Jane Doe\",\n", |
103 |
| - " email=\"[email protected]\",\n", |
104 |
| - " orcid=\"0000-0000-0000-0001\",\n", |
105 |
| - " role=\"measurement\",\n", |
106 |
| - " ),\n", |
107 |
| - "])" |
108 |
| - ] |
109 |
| - }, |
110 |
| - { |
111 |
| - "cell_type": "markdown", |
112 |
| - "id": "8", |
113 |
| - "metadata": {}, |
114 | 90 | "source": [
|
115 | 91 | "## Use the workflow\n",
|
116 | 92 | "\n",
|
|
120 | 96 | {
|
121 | 97 | "cell_type": "code",
|
122 | 98 | "execution_count": null,
|
123 |
| - "id": "9", |
| 99 | + "id": "7", |
124 | 100 | "metadata": {},
|
125 | 101 | "outputs": [],
|
126 | 102 | "source": [
|
|
129 | 105 | },
|
130 | 106 | {
|
131 | 107 | "cell_type": "markdown",
|
132 |
| - "id": "10", |
| 108 | + "id": "8", |
133 | 109 | "metadata": {},
|
134 | 110 | "source": [
|
135 |
| - "We then call `compute()` to compute the result:\n", |
136 |
| - "(The `cif` object will later be used to write the result to disk.)" |
| 111 | + "We then call `compute()` to compute the result:" |
137 | 112 | ]
|
138 | 113 | },
|
139 | 114 | {
|
140 | 115 | "cell_type": "code",
|
141 | 116 | "execution_count": null,
|
142 |
| - "id": "11", |
| 117 | + "id": "9", |
143 | 118 | "metadata": {},
|
144 | 119 | "outputs": [],
|
145 | 120 | "source": [
|
146 |
| - "results = workflow.compute([IofDspacing, ReducedDspacingCIF])\n", |
147 |
| - "result = results[IofDspacing]\n", |
148 |
| - "cif_data = results[ReducedDspacingCIF]" |
| 121 | + "result = workflow.compute(IofDspacing)\n", |
| 122 | + "result" |
149 | 123 | ]
|
150 | 124 | },
|
151 | 125 | {
|
152 | 126 | "cell_type": "code",
|
153 | 127 | "execution_count": null,
|
154 |
| - "id": "12", |
| 128 | + "id": "10", |
155 | 129 | "metadata": {},
|
156 | 130 | "outputs": [],
|
157 | 131 | "source": [
|
|
161 | 135 | },
|
162 | 136 | {
|
163 | 137 | "cell_type": "markdown",
|
164 |
| - "id": "13", |
| 138 | + "id": "11", |
165 | 139 | "metadata": {},
|
166 | 140 | "source": [
|
167 |
| - "We can now save the result to disk:\n", |
168 |
| - "(The comment is optional but helps to identify the file later.)" |
| 141 | + "We can now save the result to disk:" |
169 | 142 | ]
|
170 | 143 | },
|
171 | 144 | {
|
172 | 145 | "cell_type": "code",
|
173 | 146 | "execution_count": null,
|
174 |
| - "id": "14", |
| 147 | + "id": "12", |
175 | 148 | "metadata": {},
|
176 | 149 | "outputs": [],
|
177 | 150 | "source": [
|
178 |
| - "cif_data.comment = \"\"\"This file was generated with the DREAM data reduction user guide\n", |
179 |
| - "in the documentation of ESSdiffraction.\n", |
180 |
| - "See https://scipp.github.io/essdiffraction/\n", |
181 |
| - "\"\"\"\n", |
182 |
| - "cif_data.save('dspacing.cif')" |
| 151 | + "to_save = dspacing_histogram.assign_coords(\n", |
| 152 | + " dspacing=sc.midpoints(\n", |
| 153 | + " dspacing_histogram.coords[\"dspacing\"]\n", |
| 154 | + " ))\n", |
| 155 | + "scn.io.save_xye(\"dspacing.xye\", to_save)" |
183 | 156 | ]
|
184 | 157 | },
|
185 | 158 | {
|
186 | 159 | "cell_type": "markdown",
|
187 |
| - "id": "15", |
| 160 | + "id": "13", |
188 | 161 | "metadata": {},
|
189 | 162 | "source": [
|
190 | 163 | "## Compute intermediate results\n",
|
|
197 | 170 | {
|
198 | 171 | "cell_type": "code",
|
199 | 172 | "execution_count": null,
|
200 |
| - "id": "16", |
| 173 | + "id": "14", |
201 | 174 | "metadata": {},
|
202 | 175 | "outputs": [],
|
203 | 176 | "source": [
|
|
214 | 187 | {
|
215 | 188 | "cell_type": "code",
|
216 | 189 | "execution_count": null,
|
217 |
| - "id": "17", |
| 190 | + "id": "15", |
218 | 191 | "metadata": {},
|
219 | 192 | "outputs": [],
|
220 | 193 | "source": [
|
|
226 | 199 | },
|
227 | 200 | {
|
228 | 201 | "cell_type": "markdown",
|
229 |
| - "id": "18", |
| 202 | + "id": "16", |
230 | 203 | "metadata": {},
|
231 | 204 | "source": [
|
232 | 205 | "## Grouping by scattering angle\n",
|
|
238 | 211 | {
|
239 | 212 | "cell_type": "code",
|
240 | 213 | "execution_count": null,
|
241 |
| - "id": "19", |
| 214 | + "id": "17", |
242 | 215 | "metadata": {},
|
243 | 216 | "outputs": [],
|
244 | 217 | "source": [
|
|
250 | 223 | {
|
251 | 224 | "cell_type": "code",
|
252 | 225 | "execution_count": null,
|
253 |
| - "id": "20", |
| 226 | + "id": "18", |
254 | 227 | "metadata": {},
|
255 | 228 | "outputs": [],
|
256 | 229 | "source": [
|
|
261 | 234 | {
|
262 | 235 | "cell_type": "code",
|
263 | 236 | "execution_count": null,
|
264 |
| - "id": "21", |
| 237 | + "id": "19", |
265 | 238 | "metadata": {},
|
266 | 239 | "outputs": [],
|
267 | 240 | "source": [
|
|
279 | 252 | {
|
280 | 253 | "cell_type": "code",
|
281 | 254 | "execution_count": null,
|
282 |
| - "id": "22", |
| 255 | + "id": "20", |
283 | 256 | "metadata": {},
|
284 | 257 | "outputs": [],
|
285 | 258 | "source": [
|
286 | 259 | "grouped_dspacing.hist().plot(norm=\"log\")"
|
287 | 260 | ]
|
| 261 | + }, |
| 262 | + { |
| 263 | + "cell_type": "markdown", |
| 264 | + "id": "21", |
| 265 | + "metadata": {}, |
| 266 | + "source": [ |
| 267 | + "## Normalizing by monitor\n", |
| 268 | + "\n", |
| 269 | + "The workflow used above normalizes the detected counts by proton charge.\n", |
| 270 | + "Alternatively, ESSdiffraction can normalize by a monitor.\n", |
| 271 | + "In this example, this is DREAM's cave monitor.\n", |
| 272 | + "\n", |
| 273 | + "There are two options for normalizing by monitor:\n", |
| 274 | + "1. Normalize by a wavelength-histogram of the monitor counts ([normalize_by_monitor_histogram](../../generated/modules/ess.powder.correction.normalize_by_monitor_histogram.rst)).\n", |
| 275 | + "2. Normalized by the integral over all wavelength bins ([normalize_by_monitor_integrated](../../generated/modules/ess.powder.correction.normalize_by_monitor_integrated.rst)).\n", |
| 276 | + "\n", |
| 277 | + "Here, we use option 1.\n", |
| 278 | + "Option 2 can be chosen by constructing a workflow using `run_norm=powder.RunNormalization.monitor_integrated`.\n", |
| 279 | + "\n", |
| 280 | + "Construct a workflow as before but select normalization by monitor histogram:" |
| 281 | + ] |
| 282 | + }, |
| 283 | + { |
| 284 | + "cell_type": "code", |
| 285 | + "execution_count": null, |
| 286 | + "id": "22", |
| 287 | + "metadata": {}, |
| 288 | + "outputs": [], |
| 289 | + "source": [ |
| 290 | + "workflow = dream.DreamGeant4Workflow(run_norm=powder.RunNormalization.monitor_histogram)" |
| 291 | + ] |
| 292 | + }, |
| 293 | + { |
| 294 | + "cell_type": "markdown", |
| 295 | + "id": "23", |
| 296 | + "metadata": {}, |
| 297 | + "source": [ |
| 298 | + "In addition to the parameters used before, we also need to provide filenames for monitor data and a position of the monitor as that is not saved in the simulation files:" |
| 299 | + ] |
| 300 | + }, |
| 301 | + { |
| 302 | + "cell_type": "code", |
| 303 | + "execution_count": null, |
| 304 | + "id": "24", |
| 305 | + "metadata": {}, |
| 306 | + "outputs": [], |
| 307 | + "source": [ |
| 308 | + "workflow[MonitorFilename[SampleRun]] = dream.data.simulated_monitor_diamond_sample()\n", |
| 309 | + "workflow[MonitorFilename[VanadiumRun]] = dream.data.simulated_monitor_vanadium_sample()\n", |
| 310 | + "workflow[MonitorFilename[BackgroundRun]] = dream.data.simulated_monitor_empty_can()\n", |
| 311 | + "workflow[CaveMonitorPosition] = sc.vector([0.0, 0.0, -4220.0], unit='mm')\n", |
| 312 | + "\n", |
| 313 | + "# These are the same as at the top of the notebook:\n", |
| 314 | + "workflow[Filename[SampleRun]] = dream.data.simulated_diamond_sample()\n", |
| 315 | + "workflow[Filename[VanadiumRun]] = dream.data.simulated_vanadium_sample()\n", |
| 316 | + "workflow[Filename[BackgroundRun]] = dream.data.simulated_empty_can()\n", |
| 317 | + "workflow[CalibrationFilename] = None\n", |
| 318 | + "workflow[NeXusDetectorName] = \"mantle\"\n", |
| 319 | + "workflow[UncertaintyBroadcastMode] = UncertaintyBroadcastMode.drop\n", |
| 320 | + "workflow[DspacingBins] = sc.linspace(\"dspacing\", 0.0, 2.3434, 201, unit=\"angstrom\")\n", |
| 321 | + "workflow[TofMask] = lambda x: (x < sc.scalar(0.0, unit=\"ns\")) | (\n", |
| 322 | + " x > sc.scalar(86e6, unit=\"ns\")\n", |
| 323 | + ")\n", |
| 324 | + "workflow[TwoThetaMask] = None\n", |
| 325 | + "workflow[WavelengthMask] = None\n", |
| 326 | + "workflow = powder.with_pixel_mask_filenames(workflow, [])" |
| 327 | + ] |
| 328 | + }, |
| 329 | + { |
| 330 | + "cell_type": "code", |
| 331 | + "execution_count": null, |
| 332 | + "id": "25", |
| 333 | + "metadata": {}, |
| 334 | + "outputs": [], |
| 335 | + "source": [ |
| 336 | + "workflow.visualize(IofDspacing, graph_attr={\"rankdir\": \"LR\"})" |
| 337 | + ] |
| 338 | + }, |
| 339 | + { |
| 340 | + "cell_type": "code", |
| 341 | + "execution_count": null, |
| 342 | + "id": "26", |
| 343 | + "metadata": {}, |
| 344 | + "outputs": [], |
| 345 | + "source": [ |
| 346 | + "results = workflow.compute((IofDspacing, WavelengthMonitor[SampleRun, CaveMonitor]))\n", |
| 347 | + "normalized_by_monitor = results[IofDspacing]\n", |
| 348 | + "monitor = results[WavelengthMonitor[SampleRun, CaveMonitor]]\n", |
| 349 | + "monitor" |
| 350 | + ] |
| 351 | + }, |
| 352 | + { |
| 353 | + "cell_type": "code", |
| 354 | + "execution_count": null, |
| 355 | + "id": "27", |
| 356 | + "metadata": {}, |
| 357 | + "outputs": [], |
| 358 | + "source": [ |
| 359 | + "monitor.plot()" |
| 360 | + ] |
| 361 | + }, |
| 362 | + { |
| 363 | + "cell_type": "markdown", |
| 364 | + "id": "28", |
| 365 | + "metadata": {}, |
| 366 | + "source": [ |
| 367 | + "Comparing the final, normalized result shows that it agrees with the data that was normalized by proton-charge:" |
| 368 | + ] |
| 369 | + }, |
| 370 | + { |
| 371 | + "cell_type": "code", |
| 372 | + "execution_count": null, |
| 373 | + "id": "29", |
| 374 | + "metadata": {}, |
| 375 | + "outputs": [], |
| 376 | + "source": [ |
| 377 | + "sc.plot({\n", |
| 378 | + " 'By proton charge': dspacing_histogram,\n", |
| 379 | + " 'By monitor': normalized_by_monitor.hist()\n", |
| 380 | + "})" |
| 381 | + ] |
288 | 382 | }
|
289 | 383 | ],
|
290 | 384 | "metadata": {
|
|
303 | 397 | "name": "python",
|
304 | 398 | "nbconvert_exporter": "python",
|
305 | 399 | "pygments_lexer": "ipython3",
|
306 |
| - "version": "3.10.13" |
| 400 | + "version": "3.10.14" |
307 | 401 | }
|
308 | 402 | },
|
309 | 403 | "nbformat": 4,
|
|
0 commit comments