{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Advanced McStas features: JUMP\n", "In this notebook we will look at JUMP and how it can be used to control the sequence of execution of components. One instance where this is useful is if a guide splits into two. Consider an instrument with the following components:\n", "\n", "- source\n", "- main guide\n", "- guide1\n", "- sample1\n", "- detector1\n", "- guide2\n", "- sample2\n", "- detector2\n", "\n", "After the main guide, if the ray hits the opening of guide1 the ray will continue to sample1 and detector1 as expected, but if it misses the opening of guide1, it will just be absorbed and never reach guide2 later in the component sequence. One possible solution is to use a JUMP statement, which jumps to another place in the component sequence. The target component must be an Arm, and no coordinate transformations are done, so the simplest solution is to have the Arm conincide with the component with the JUMP statement.\n", "\n", "- source\n", "- main guide\n", "- arm A JUMP arm B WHEN ray hits guide2 entrance \n", "- guide1\n", "- sample1\n", "- detector1\n", "- arm B (same position and rotation of arm A)\n", "- guide2\n", "- sample2\n", "- detector2\n", "\n", "Here we build such an instrument with a few notes on the syntax along the way." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import mcstasscript as ms" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "instrument = ms.McStas_instr(\"python_tutorial\", input_path=\"run_folder\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "src = instrument.add_component(\"source\", \"Source_simple\")\n", "\n", "src.xwidth = 0.12\n", "src.yheight = 0.12\n", "src.focus_xw = guide_opening_w = 0.1\n", "src.focus_yh = guide_opening_h = 0.06\n", "src.dist = 1.5\n", "src.flux = 1E13\n", "\n", "src.lambda0 = instrument.add_parameter(\"wavelength\", value=5.0,\n", " comment=\"Wavelength in [Ang]\")\n", "src.dlambda = \"0.001*wavelength\"\n", "\n", "guide = instrument.add_component(\"guide\", \"Guide_gravity\", AT=[0,0,1.5], RELATIVE=src)\n", "guide.w1 = guide_opening_w\n", "guide.h1 = guide_opening_h\n", "guide.w2 = guide_opening_w\n", "guide.h2 = guide_opening_h\n", "guide.l = guide_length = 15\n", "guide.m = 4.0\n", "guide.G = -9.82" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Adding the reference arm\n", "We here add an arm just after the exit of the main guide which will be the component that performs the JUMP under certain circumstances. The McStas syntax for such a JUMP statement would be:\n", "\n", "JUMP *reference* WHEN *condition*\n", "\n", "We will call the arm we jump to for *target_arm*, and our condition is that the neutron is on the left side, so x<0. That means our JUMP statement would be:\n", "\n", "JUMP target_arm WHEN (x<0)\n", "\n", "In McStasScript this is added with the *set_JUMP* method, that takes a string for what to set after JUMP." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "start_arm = instrument.add_component(\"split_arm\", \"Arm\")\n", "start_arm.set_AT([0,0, guide_length + 3E-3], RELATIVE=guide)\n", "start_arm.set_JUMP(\"target_arm WHEN (x<0)\")\n", "\n", "print(start_arm)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Adding the first daughter instrument\n", "We then add the left side, which correspond to x>0, so this is the case where no jump was performed and the sequence of components runs as normal." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "guide1 = instrument.add_component(\"guide1\", \"Guide_gravity\")\n", "guide1.set_AT([0.25*guide_opening_w,0,0], RELATIVE=start_arm)\n", "guide1.set_ROTATED([0, 1, 0], RELATIVE=start_arm)\n", "guide1.w1 = 0.5*guide_opening_w\n", "guide1.h1 = 0.5*guide_opening_h\n", "guide1.w2 = 0.5*guide_opening_w\n", "guide1.h2 = 0.5*guide_opening_h\n", "guide1.l = guide1_length = 10\n", "guide1.m = 2.5\n", "guide1.G = -9.82\n", "\n", "sample1 = instrument.add_component(\"sample1\", \"PowderN\")\n", "sample1.set_AT([0,0,guide1_length+0.5], RELATIVE=guide1)\n", "sample1.radius = 0.015\n", "sample1.yheight = 0.05\n", "sample1.reflections = '\"Na2Ca3Al2F14.laz\"'\n", "\n", "banana1 = instrument.add_component(\"banana1\", \"Monitor_nD\", RELATIVE=sample1)\n", "banana1.xwidth = 2.0\n", "banana1.yheight = 0.3\n", "banana1.filename = '\"banana1.dat\"'\n", "banana1.options = '\"theta limits=[5 175] bins=150, banana\"'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Adding the second daughter instrument\n", "Now we need to add the target_arm that rays jump to when they go to the right side of the guide split. This is in the exact same position of the previous arm, to avoid the need for a coordinate transformation which is not performed automatically when using JUMP statements.\n", "\n", "After that we add a second daughter instrument with a different sample." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "target_arm = instrument.add_component(\"target_arm\", \"Arm\")\n", "target_arm.set_AT([0,0,0], RELATIVE=start_arm)\n", "\n", "guide2 = instrument.add_component(\"guide2\", \"Guide_gravity\")\n", "guide2.set_AT([-0.25*guide_opening_w,0,0], RELATIVE=target_arm)\n", "guide2.set_ROTATED([0, -1, 0], RELATIVE=target_arm)\n", "guide2.w1 = 0.5*guide_opening_w\n", "guide2.h1 = 0.5*guide_opening_h\n", "guide2.w2 = 0.5*guide_opening_w\n", "guide2.h2 = 0.5*guide_opening_h\n", "guide2.l = guide1_length = 15\n", "guide2.m = 2.5\n", "guide2.G = -9.82\n", "\n", "sample2 = instrument.add_component(\"sample2\", \"PowderN\")\n", "sample2.set_AT([0,0,guide1_length+0.5], RELATIVE=guide2)\n", "sample2.radius = 0.015\n", "sample2.yheight = 0.05\n", "sample2.reflections = '\"Cu.laz\"'\n", "\n", "banana2 = instrument.add_component(\"banana2\", \"Monitor_nD\", RELATIVE=sample2)\n", "banana2.xwidth = 2.0\n", "banana2.yheight = 0.3\n", "banana2.filename = '\"banana2.dat\"'\n", "banana2.options = '\"theta limits=[5 175] bins=150, banana\"'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Instrument diagram showing JUMP\n", "The instrument diagram helps visualize what happens with a JUMP statement, as JUMPS are visualized. From the diagram, it can be seen that the two daughter instruments exist in parallel after the \"split_arm\" component." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "instrument.show_diagram()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Running the simulation" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [ "scroll-output" ] }, "outputs": [], "source": [ "instrument.set_parameters(wavelength=2.8)\n", "instrument.settings(ncount=5E6, output_path=\"data_folder/mcstas_JUMP\")\n", "data = instrument.backengine()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ms.make_sub_plot(data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Interpretation of the data\n", "We see that each daughter instrument have beam and show the different powder patterns as expected." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The McStas instrument file\n", "We here show the generated McStas instrument file in order to clarify how this would be accomplished without the McStasScript API." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "instrument.show_instrument_file()" ] }, { "cell_type": "code", "execution_count": null, "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": 2 }