{ "cells": [ { "cell_type": "markdown", "id": "russian-transparency", "metadata": {}, "source": [ "# Data\n", "Data from simulations performed by McStasScript is returned as [McStasData](../_autosummary/mcstasscript.data.data.McStasData.rst) objects. This section will explore what these contain and how one can manipulate them. First a small instrument is written that will supply data to investigate.\n", "\n", "## Example instrument\n", "The instrument will consist of a source, a powder sample and some monitors that will record data." ] }, { "cell_type": "code", "execution_count": null, "id": "substantial-weekly", "metadata": { "tags": [ "hide-input" ] }, "outputs": [], "source": [ "import mcstasscript as ms\n", "\n", "instrument = ms.McStas_instr(\"data_example\")\n", "\n", "source = instrument.add_component(\"source\", \"Source_simple\")\n", "source.set_parameters(xwidth=0.05, yheight=0.03, dlambda=0.1,\n", " dist=5, focus_xw=0.015, focus_yh=0.03)\n", "source.lambda0 = instrument.add_parameter(\"wavelength\", value=1.2)\n", "\n", "sample = instrument.add_component(\"sample\", \"PowderN\")\n", "sample.set_parameters(radius=source.focus_xw, yheight=source.focus_yh,\n", " reflections='\"Na2Ca3Al2F14.laz\"', barns=0)\n", "sample.set_AT(source.dist, RELATIVE=source)" ] }, { "cell_type": "markdown", "id": "sized-henry", "metadata": {}, "source": [ "### Example monitors\n", "Here three monitors are defined, a 2D PSD monitor, a 1D banana monitor and an event monitor. Monitor_nD is used for the last two, where the option string describes the geometry and what is to be recorded." ] }, { "cell_type": "code", "execution_count": null, "id": "apart-duration", "metadata": {}, "outputs": [], "source": [ "banana = instrument.add_component(\"banana\", \"Monitor_nD\", RELATIVE=sample)\n", "banana.set_parameters(xwidth=1.5, yheight=0.4, restore_neutron=1, filename='\"banana.dat\"')\n", "banana.options = '\"theta limits=[5 175] bins=250, banana\"'" ] }, { "cell_type": "code", "execution_count": null, "id": "collaborative-police", "metadata": {}, "outputs": [], "source": [ "event = instrument.add_component(\"events\", \"Monitor_nD\")\n", "event.set_AT(0.1, RELATIVE=sample)\n", "event.set_parameters(xwidth=0.1, yheight=0.1, restore_neutron=1, filename='\"events.dat\"')\n", "event.options = '\"list all auto, x y z vx vy vz t\"'" ] }, { "cell_type": "code", "execution_count": null, "id": "urban-traffic", "metadata": {}, "outputs": [], "source": [ "mon = instrument.add_component(\"PSD\", \"PSD_monitor\")\n", "mon.set_AT(0.1, RELATIVE=sample)\n", "mon.set_parameters(nx=100, ny=100, filename='\"psd.dat\"',\n", " xwidth=3*sample.radius, yheight=2*sample.yheight, restore_neutron=1)" ] }, { "cell_type": "markdown", "id": "center-middle", "metadata": {}, "source": [ "## Generating data\n", "The simulation is executed using the *backengine* method with a low number of neutrons. The data is returned by the *backengine* method, but will contain None if the simulation failed. " ] }, { "cell_type": "code", "execution_count": null, "id": "finished-employment", "metadata": { "scrolled": true, "tags": [ "scroll-output" ] }, "outputs": [], "source": [ "instrument.settings(ncount=1E5, output_path=\"data_example\")\n", "data = instrument.backengine()" ] }, { "cell_type": "code", "execution_count": null, "id": "charged-recovery", "metadata": {}, "outputs": [], "source": [ "print(data)" ] }, { "cell_type": "markdown", "id": "interracial-lancaster", "metadata": {}, "source": [ "## McStasData objects\n", "The data retrieved from the instrument object is in the form of a list that contains [McStasDataBinned](../_autosummary/mcstasscript.data.data.McStasDataBinned.rst) and [McStasDataEvent](../_autosummary/mcstasscript.data.data.McStasDataEvent.rst) objects. McStasScript contains a function called [*name_search*](../_autosummary/mcstasscript.interface.functions.name_search.rst) which can be used to select a certain element of such a data list. It will match the component name first and if no match is found it will check for match with the filename. Here [*name_search*](../_autosummary/mcstasscript.interface.functions.name_search.rst) is used to retrieve the PSD [McStasDataBinned](../_autosummary/mcstasscript.data.data.McStasDataBinned.rst) object." ] }, { "cell_type": "code", "execution_count": null, "id": "knowing-schedule", "metadata": {}, "outputs": [], "source": [ "PSD = ms.name_search(\"PSD\", data)\n", "banana = ms.name_search(\"banana\", data)\n", "events = ms.name_search(\"events\", data)" ] }, { "cell_type": "markdown", "id": "competitive-conversion", "metadata": {}, "source": [ "### Accessing metadata\n", "Both McStasDataBinned and McStasDataEvent object carries relevant metadata in a *metadata* attribute. Using the python print function this object can display basic information on the contained data." ] }, { "cell_type": "code", "execution_count": null, "id": "official-major", "metadata": {}, "outputs": [], "source": [ "print(PSD.metadata)\n", "print(banana.metadata)\n", "print(events.metadata)" ] }, { "cell_type": "markdown", "id": "virgin-profit", "metadata": {}, "source": [ "The metadata object has attributes which can be accessed as well. The info attribute is a dict with the raw metadata read from the file.\n", "\n", "- component_name\n", "- dimension\n", "- filename\n", "- limits\n", "- parameters\n", "- info" ] }, { "cell_type": "code", "execution_count": null, "id": "previous-theme", "metadata": { "scrolled": true }, "outputs": [], "source": [ "PSD.metadata.info" ] }, { "cell_type": "markdown", "id": "balanced-spine", "metadata": {}, "source": [ "The total intensity, error or ncount is kept in the values are often of interest, so these are given their own attributes: *total_I*, *total_E* and *total_N*" ] }, { "cell_type": "code", "execution_count": null, "id": "weighted-pillow", "metadata": {}, "outputs": [], "source": [ "print(PSD.metadata.total_I)\n", "print(PSD.metadata.total_E)\n", "print(PSD.metadata.total_N)" ] }, { "cell_type": "markdown", "id": "acknowledged-orlando", "metadata": {}, "source": [ "### Accessing the data\n", "McStasData objects stores the data as [Numpy arrays](https://numpy.org/doc/stable/reference/generated/numpy.array.html), these can be accessed as attributes.\n", "\n", "- Intensity: Holds the intensity, sum of all ray weights\n", "- Error: Error on intensity\n", "- Ncount: Number of rays that reached " ] }, { "cell_type": "code", "execution_count": null, "id": "composite-property", "metadata": {}, "outputs": [], "source": [ "print(\"Intensity\")\n", "print(PSD.Intensity)\n", "\n", "print(\"Error\")\n", "print(PSD.Error)\n", "\n", "print(\"Ncount\")\n", "print(PSD.Ncount)" ] }, { "cell_type": "markdown", "id": "registered-vocabulary", "metadata": {}, "source": [ "The original path to the data is also contained within the McStasData object and can be returned with get_data_location." ] }, { "cell_type": "code", "execution_count": null, "id": "adverse-demonstration", "metadata": {}, "outputs": [], "source": [ "PSD.get_data_location()" ] }, { "cell_type": "markdown", "id": "central-democracy", "metadata": {}, "source": [ "### Event data\n", "McStasDataEvent objecst stores event data, and for this reason does not have *Error* or *Ncount*. The event information is contained in a 2D Numpy array in the *Intensity* and *Events* attributes. " ] }, { "cell_type": "code", "execution_count": null, "id": "north-adjustment", "metadata": {}, "outputs": [], "source": [ "print(events)" ] }, { "cell_type": "code", "execution_count": null, "id": "closed-tumor", "metadata": {}, "outputs": [], "source": [ "print(\"Events\", events.Events)" ] }, { "cell_type": "markdown", "id": "fancy-cooling", "metadata": {}, "source": [ "The [McStasDataEvent](../_autosummary/mcstasscript.data.data.McStasDataEvent.rst) objects have some help functions to work with the contained event data. The first is *get_data_column* that returns the data for a given axis. The available axis shown in the table below.\n", "\n", "| Axis string | Full name | Unit | Description |\n", "| --- | --- | --- | --- |\n", "| t | time | s | Particle time |\n", "| x | x position | m | Coordinate x of particle |\n", "| y | y position | m | Coordinate y of particle |\n", "| z | z position | m | Coordinate z of particle |\n", "| vx | x velocity | m/s | Velocity projected onto x |\n", "| vy | y velocity | m/s | Velocity projected onto y |\n", "| vz | z velocity | m/s | Velocity projected onto z |\n", "| p | weight | intensity | Particle weight McStas n/s |\n", "| l | lambda | AA | Wavelength |\n", "| e | energy | meV | Particle energy |\n", "| speed | speed | m/s | Speed (length of velocity vector) |\n", "| dx | x divergence | deg | Divergence from z axis along x axis |\n", "| dy | y divergence | deg | Divergence from z axis along y axis |\n", "| U1 | User1 | Userdefined | User defined flag in Monitor_nD |\n", "| U2 | User2 | Userdefined | User defined flag in Monitor_nD |\n", "| U3 | User3 | Userdefined | User defined flag in Monitor_nD |\n", "\n", "\n", "Here we get the wavelength information for each neutron in the event dataset." ] }, { "cell_type": "code", "execution_count": null, "id": "floating-chancellor", "metadata": {}, "outputs": [], "source": [ "events.get_data_column(\"l\")" ] }, { "cell_type": "markdown", "id": "ranking-booth", "metadata": {}, "source": [ "It is also possible to produce a McStasDataBinned dataset from a McStasDataEvent dataset by binning along one or two chosen dimensions using *make_1d* and *make_2d*. It supports all the same variables as above. For each method it is possible to choose how many bins should be used with the n_bins keyword argument." ] }, { "cell_type": "code", "execution_count": null, "id": "corresponding-baking", "metadata": {}, "outputs": [], "source": [ "speed_1d = events.make_1d(\"speed\", n_bins=60)\n", "divergence_2d = events.make_2d(\"dx\", \"dy\", n_bins=[120, 120])\n", "\n", "print(speed_1d)\n", "print(divergence_2d)" ] }, { "cell_type": "markdown", "id": "dated-heritage", "metadata": {}, "source": [ "### Plotting \n", "[McStasData](../_autosummary/mcstasscript.data.data.McStasData.rst) objects contain information on how the data should be plotted, including for example if it should be on a logarithmic axis. This information is contained in the *plot_options* attribute of a [McStasData](../_autosummary/mcstasscript.data.data.McStasData.rst) object. The plotting are described in more detail on the [plotting page](plotting.ipynb)." ] }, { "cell_type": "code", "execution_count": null, "id": "furnished-juice", "metadata": {}, "outputs": [], "source": [ "PSD.plot_options" ] }, { "cell_type": "markdown", "id": "educated-template", "metadata": {}, "source": [ "McStasScript can plot a McStasData object directly using for example *make_plot*." ] }, { "cell_type": "code", "execution_count": null, "id": "religious-chambers", "metadata": {}, "outputs": [], "source": [ "ms.make_plot(PSD)" ] }, { "cell_type": "markdown", "id": "green-nancy", "metadata": {}, "source": [ "The *plot_options* can be updated with *set_plot_options* that takes keyword arguments." ] }, { "cell_type": "code", "execution_count": null, "id": "blessed-sandwich", "metadata": {}, "outputs": [], "source": [ "PSD.set_plot_options(log=True, top_lim=1.5, bottom_lim=-1.5, colormap=\"hot\", orders_of_mag=2)\n", "ms.make_plot(PSD)" ] }, { "cell_type": "markdown", "id": "northern-ethernet", "metadata": {}, "source": [ "The *set_plot_options* takes the following keyword arguments. Some will only apply for 2D data, for example *orders_of_mag*.\n", "\n", "| Keyword argument | Type | Default | Description |\n", "| --- | --- | --- | --- |\n", "| log | bool | False | Logarithmic axis for y in 1D or z in 2D |\n", "| orders_of_mag | float | 300 | Maximum orders of magnitude to plot in 2D |\n", "| colormap | str | \"jet\" | Matplotlib colormap to use |\n", "| show_colorbar | bool | True | Show the colorbar |\n", "| x_axis_multiplier | float | 1 | Multiplier for x axis data |\n", "| y_axis_multiplier | float | 1 | Multiplier for y axis data |\n", "| cut_min | float | 0 | Unitless lower limit normalized to data range |\n", "| cut_max | float | 1 | Unitless upper limit normalized to data range |\n", "| left_lim | float | | Lower limit to plot range of x axis |\n", "| right_lim | float | | Upper limit to plot range of x axis|\n", "| bottom_lim | float | | Lower limit to plot range of y axis|\n", "| top_lim | float | | Upper limit to plot range of y axis|" ] }, { "cell_type": "markdown", "id": "binding-joining", "metadata": {}, "source": [ "McStasDataBinned generated from Event files can be plotted in the same manner." ] }, { "cell_type": "code", "execution_count": null, "id": "banner-fitting", "metadata": {}, "outputs": [], "source": [ "ms.make_sub_plot([speed_1d, divergence_2d], log=True)" ] }, { "cell_type": "code", "execution_count": null, "id": "greatest-spanking", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "celltoolbar": "Tags", "kernelspec": { "display_name": "Python 3", "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", "version": "3.8.8" } }, "nbformat": 4, "nbformat_minor": 5 }