The Union components

This tutorial is the first in a series showing how the Union components are used. This notebook focuses on setting up material definitions that are used to provide scattering physics to geometries. There are several kinds of Union components, and they need to be used in conjunction with one another to function.

  • Process components: Describe individual scattering phenomena, such as incoherent, powder, single crystal scattering

  • Make_material component: Joins several processes into a material definition

  • Geometry components: Describe geometry, each is assigned a material definition

  • Union logger components: Records information for each scattering event and plots it

  • Union abs logger components: Records information for each absorption event and plots it

  • Union conditional components: Modifies a logger or abs logger so it only records when certain final condition met

  • Union master component: Performs simulation described by previous Union components

In this notebook we will focus on setting up materials using process components and the Union_make_material component, but the Union components can not work individually, so it will also be necessary to add a geometry and the Union_master. First we import McStasScript and create a new instrument object.

In case of any issues with running the tutorial notebooks there is troubleshooting at the end of this notebook.

import mcstasscript as ms
instrument = ms.McStas_instr("python_tutorial", input_path="run_folder")

Differences between McStas versions

The Union components can be used in both McStas 2.X and McStas 3.X, but when used in McStas 3.X it is necessary to add an Union_init component named init before any other Union component and a Union_stop component after all other Union components. To make the notebooks compatible with both, the init and stop component can be added inside an if-statement that checks what version of McStas is used.

if instrument.mccode_version == 3:
    init = instrument.add_component("init", "Union_init") # This component has to be called init

Process components

In this notebook we will focus on exploring how to build different physical descriptions of materials, and checking that they behave as expected. We start by looking at the process component for incoherent scattering, Incoherent_process.

instrument.available_components("union")
Here are all components in the union category.
 AF_HB_1D_process                          Union_conditional_PSD
 IncoherentPhonon_process                  Union_conditional_standard
 Incoherent_process                        Union_cone
 NCrystal_process                          Union_cylinder
 PhononSimple_process                      Union_logger_1D
 Powder_process                            Union_logger_2DQ
 Single_crystal_process                    Union_logger_2D_kf
 Template_process                          Union_logger_2D_kf_time
 Texture_process                           Union_logger_2D_space
 Union_abs_logger_1D_space                 Union_logger_2D_space_time
 Union_abs_logger_1D_space_event           Union_logger_3D_space
 Union_abs_logger_1D_space_tof             Union_make_material
 Union_abs_logger_1D_space_tof_to_lambda   Union_master
 Union_abs_logger_2D_space                 Union_mesh
 Union_abs_logger_event                    Union_sphere
 Union_box                                 
instrument.component_help("Incoherent_process")
 ___ Help Incoherent_process ________________________________________________________
|optional parameter|required parameter|default value|user specified value|
sigma = 5.08 [barns] // Incoherent scattering cross section
f_QE = 0.0 [1] // Fraction of quasielastic scattering (rest is elastic)
gamma = 0.0 [1] // Lorentzian width of quasielastic broadening (HWHM)
packing_factor = 1.0 [1] // How dense is the material compared to optimal 0-1
unit_cell_volume = 13.8 [AA^3] // Unit_cell_volume
interact_fraction = -1.0 [1] // How large a part of the scattering events 
                                should use this process 0-1 (sum of all processes 
                                in material = 1) 
-------------------------------------------------------------------------------------

The process components in general have few parameters as they just describe a single physical phenomena. The incoherent process here is described adequately by just the cross section sigma and volume of the unit cell, unit_cell_volume.

Two parameters are available for all processes, packing_factor and interact_fraction. The packing factor describes how dense the material is, and can make it easier to mix for example different powders. It is implemented as a simple factor on the scattering strength. The interact fraction is used to balance many processes when they are used in one material. Normally processes are sampled according to they natural probability for scattering, but this can be overwritten using the interact_fraction, which provides the sampling probability directly, they just have to sum to 1 within a material.

incoherent = instrument.add_component("incoherent", "Incoherent_process")
incoherent.sigma = 2.5
incoherent.unit_cell_volume = 13.8

Making a material

In order to collect processes into a material, one uses the Union_make_material component. Here are the parameters.

instrument.component_help("Union_make_material")
 ___ Help Union_make_material _______________________________________________________
|optional parameter|required parameter|default value|user specified value|
process_string = "NULL" [string] // Comma seperated names of physical processes
my_absorption [1/m] // Inverse penetration depth from absorption at standard 
                       energy 
absorber = 0.0 [0/1] // Control parameter, if set to 1 the material will have 
                        no scattering processes 
-------------------------------------------------------------------------------------

A material definition thus consists of a number of processes given with the process_string parameter, and a description of the absorption in the material given with the inverse penetration depth at the standard neutron speed of 2200 m/s. For our first test material, lets just set absorption to zero and set our process_string to incoherent, referring to the process we created above.

The name of the material is now inc_material, which will be used in the future to refer to this material.

inc_material = instrument.add_component("inc_material", "Union_make_material")
inc_material.my_absorption = 0.0
inc_material.process_string = '"incoherent"'

If the material contains no physical processes, it is necessary to set the absorber parameter to 1, as it will just have an absorption description. Here we make a material called abs_material.

absorber = instrument.add_component("abs_material", "Union_make_material")
absorber.absorber = 1
absorber.my_absorption = 3.0

The primary reason for having both process components and a make_material component is that it is possible to add as many processes in one material as necessary. Here we create a powder process, and then make a material using the powder and previously defined incoherent processes.

powder = instrument.add_component("powder", "Powder_process")
powder.reflections = '"Cu.laz"'

inc_material = instrument.add_component("powder_material", "Union_make_material")
inc_material.my_absorption = 1.2
inc_material.process_string = '"incoherent,powder"'

At this point we have three materials defined

Material name

Description

inc_material

Has one incoherent process and no absorption

abs_material

Only has absorption

powder_material

Has both incoherent and powder process in addition to absorption

The instrument diagram can show the components and their underlying connections. Connections between Union components are shown on the right side. From the diagram it is clear the same incoherent process is used in both inc_material and powder_material. In most cases a user would make individual incoherent processes for each material to set independent incoherent cross sections. It is also visible that powder_material contains two processes and abs_material contains none.

instrument.show_diagram()
../_images/Union_tutorial_1_processes_and_materials_19_0.png ../_images/Union_tutorial_1_processes_and_materials_19_1.png

Let us defined a quick test instrument to see these materials are behaving as expected. First we add a source.

src = instrument.add_component("source", "Source_div")

source_width = instrument.add_parameter("source_width", value=0.15,
                                        comment="Width of source in [m]")
src.xwidth = source_width
src.yheight = 0.03
src.focus_aw = 0.01
src.focus_ah = 0.01

src.lambda0 = instrument.add_parameter("wavelength", value=5.0,
                                       comment="Wavelength in [Ang]")
src.dlambda = "0.001*wavelength"

Adding geometries that use the material definitions

Here we add three boxes, each using a different material definition and placed next to one another. The material_string parameter is used to specify the material name. The priority parameter will be explained later, as it is only important when geometries overlap, here they are spatially separated, yet the priorities must still be unique.

It is important to note that these three boxes will be simulated simultaneously in the McStas simulation flow, so no need for GROUP statements to have these in parallel. Because they are simulated simultaneously, a ray can go from one to another, which would not be possible with a standard GROUP.

box_inc = instrument.add_component("box_inc", "Union_box", AT=[0.04,0,1], RELATIVE=src)
box_inc.xwidth = 0.03
box_inc.yheight = 0.03
box_inc.zdepth = 0.03
box_inc.material_string = '"inc_material"'
box_inc.priority = 10

box_inc = instrument.add_component("box_powder", "Union_box", AT=[0,0,1], RELATIVE=src)
box_inc.xwidth = 0.03
box_inc.yheight = 0.03
box_inc.zdepth = 0.01
box_inc.material_string = '"powder_material"'
box_inc.priority = 11

box_inc = instrument.add_component("box_abs", "Union_box", AT=[-0.04,0,1], RELATIVE=src)
box_inc.xwidth = 0.03
box_inc.yheight = 0.03
box_inc.zdepth = 0.03
box_inc.material_string = '"abs_material"'
box_inc.priority = 12

Let us take another look at how this changed the instrument diagram. The three geometries have been added, and each have a line to their material component.

instrument.show_diagram()
../_images/Union_tutorial_1_processes_and_materials_25_0.png ../_images/Union_tutorial_1_processes_and_materials_25_1.png

Adding loggers that show scattering and absorption

In order to check the three materials behave as expected, we add spatial loggers for scattering and absorption. These are called loggers and abs_loggers, here is the parameters for a logger.

instrument.component_help("Union_logger_2D_space")
 ___ Help Union_logger_2D_space _____________________________________________________
|optional parameter|required parameter|default value|user specified value|
target_geometry = "NULL" [string] // Comma seperated list of geometry names 
                                     that will be logged, leave empty for all 
                                     volumes (even not defined yet) 
target_process = "NULL" [string] // Comma seperated names of physical 
                                    processes, if volumes are selected, one can 
                                    select Union_process names 
D_direction_1 = "x" [string] // Direction for first axis ("x", "y" or "z")
D1_min = -5.0 [1] // histogram boundery, min position value for first axis
D1_max = 5.0 [1] // histogram boundery, max position value for first axis
n1 = 90.0 [1] // number of bins for first axis
D_direction_2 = "z" [string] // Direction for second axis ("x", "y" or "z")
D2_min = -5.0 [1] // histogram boundery, min position value for second axis
D2_max = 5.0 [1] // histogram boundery, max position value for second axis
n2 = 90.0 [1] // number of bins for second axis
filename = "NULL" [string] // Filename for logging output
order_total = 0.0 [1] // Only log rays that scatter for the n'th time, 0 for 
                         all orders 
order_volume = 0.0 [1] // Only log rays that scatter for the n'th time in the 
                          same geometry 
order_volume_process = 0.0 [1] // Only log rays that scatter for the n'th time 
                                  in the same geometry, using the same process 
logger_conditional_extend_index = -1.0 [1] // If a conditional is used with 
                                              this logger, the result of each 
                                              conditional calculation can be made 
                                              available in extend as a array called 
                                              "logger_conditional_extend", and one 
                                              would then acces 
                                              logger_conditional_extend[n] if 
                                              logger_conditional_extend_index is 
                                              set to n 
-------------------------------------------------------------------------------------

The parameters for the abs_logger are very similar, so the two are added here.

logger = instrument.add_component("logger_space", "Union_logger_2D_space")
logger.set_RELATIVE("box_powder")
logger.D_direction_1 = '"z"'
logger.D1_min = -0.04
logger.D1_max = 0.04
logger.n1 = 250
logger.D_direction_2 = '"x"'
logger.D2_min = -0.075
logger.D2_max = 0.075
logger.n2 = 400
logger.filename = '"logger.dat"'

logger = instrument.add_component("abs_logger_space", "Union_abs_logger_2D_space")
logger.set_RELATIVE("box_powder")
logger.D_direction_1 = '"z"'
logger.D1_min = -0.04
logger.D1_max = 0.04
logger.n1 = 250
logger.D_direction_2 = '"x"'
logger.D2_min = -0.075
logger.D2_max = 0.075
logger.n2 = 400
logger.filename = '"abs_logger.dat"'

Adding the Union master component

The Union master component is what actually executes the simulation, and so it takes information from all Union components defined before and performs the described simulation. This is the component that matters in terms of order of execution within the sequence of McStas components. As all the previous components have described the what the master component should simulate, it has no required parameters. It also does not matter where it is located in space, as it will grab the locations described by all previous Union components that need a spatial location, such as the geometries and loggers.

instrument.component_help("Union_master")
 ___ Help Union_master ______________________________________________________________
|optional parameter|required parameter|default value|user specified value|
verbal = 1.0 [bool] // Toogles terminal output describing the defined simulation
list_verbal = 0.0 [bool] // Toogles information of all internal lists in 
                            intersection network 
finally_verbal = 0.0 [bool] // Toogles information about cleanup performed in 
                               finally section 
allow_inside_start = 0.0 [bool] // Set to 1 to allow rays to start inside the 
                                   defined geometry 
enable_tagging = 0.0 [bool] // Enable tagging of ray history (geometry, 
                               scattering process) 
history_limit = 300000.0 [bool] // Limit the number of unique histories that 
                                   are saved 
enable_conditionals = 1.0 [bool] // Use conditionals with this master
inherit_number_of_scattering_events = 0.0 [bool] // Inherit the number of 
                                                    scattering events from last 
                                                    master 
record_absorption = 0.0 [bool] // Toggles logging of absorption
-------------------------------------------------------------------------------------
master = instrument.add_component("master", "Union_master")

McStas 3.X compatability

As mentioned at the start of the notebook it is necessary to add a Union_stop component after all Union coponents in the instrument, this is typically after the last master.

if instrument.mccode_version == 3:
    stop = instrument.add_component("stop", "Union_stop")

Although the Union_master component is not told specifically what geometry components to simulate, it picks up the relevant information from the components added before it. The instrument diagram shows these hidden connections.

instrument.show_diagram()
../_images/Union_tutorial_1_processes_and_materials_36_0.png ../_images/Union_tutorial_1_processes_and_materials_36_1.png

Running the simulation

Here the McStas simulation is executed as normal.

instrument.set_parameters(wavelength=8.0)
instrument.settings(ncount=3E6, output_path="data_folder/union_materials")
instrument.show_settings()

data = instrument.backengine()
Instrument settings:
  ncount:           3.00e+06
  output_path:      data_folder/union_materials
  run_path:         run_folder
  package_path:     /Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1
  executable_path:  /Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1/bin/
  executable:       mcrun
  force_compile:    True
INFO: Using directory: "/Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/data_folder/union_materials_1"
INFO: Regenerating c-file: python_tutorial.c
CFLAGS= -I@MCCODE_LIB@/share/ -I@MCCODE_LIB@/share/
    INFO: Recompiling: ./python_tutorial.out
mccode-r.c:2837:3: warning: expression result unused [-Wunused-value]
  *t0;
  ^~~
In file included from /Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Incoherent_process.comp:66:
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Union_functions.c:1604:105: warning: incompatible function pointer types passing 'int (const struct saved_history_struct *, const struct saved_history_struct *)' to parameter of type 'int (* _Nonnull)(const void *, const void *)' [-Wincompatible-function-pointer-types]
  qsort(total_history.saved_histories,total_history.used_elements,sizeof (struct saved_history_struct), Sample_compare_history_intensities);
                                                                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stdlib.h:161:22: note: passing argument to parameter '__compar' here
            int (* _Nonnull __compar)(const void *, const void *));
                            ^
In file included from /Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Incoherent_process.comp:66:
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Union_functions.c:1613:20: warning: incompatible pointer types passing 'struct saved_history_struct *' to parameter of type 'struct dynamic_history_list *' [-Wincompatible-pointer-types]
    printf_history(&total_history.saved_histories[history_iterate]);
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mccode-r.h:219:27: note: expanded from macro 'MPI_MASTER'
#define MPI_MASTER(instr) instr
                          ^~~~~
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Union_functions.c:1434:50: note: passing argument to parameter 'history' here
void printf_history(struct dynamic_history_list *history) {
                                                 ^
In file included from /Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Incoherent_process.comp:66:
In file included from /Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Union_functions.c:2030:
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:839:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
};
^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:883:1: warning: non-void function does not return a value [-Wreturn-type]
};
^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3274:42: warning: if statement has empty body [-Wempty-body]
    if (dist_to_corner > sphere_2_radius); { sphere_2_radius = dist_to_corner ; }
                                         ^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3274:42: note: put the semicolon on a separate line to silence this warning
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3276:42: warning: if statement has empty body [-Wempty-body]
    if (dist_to_corner > sphere_2_radius); { sphere_2_radius = dist_to_corner ; }
                                         ^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3276:42: note: put the semicolon on a separate line to silence this warning
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3278:42: warning: if statement has empty body [-Wempty-body]
    if (dist_to_corner > sphere_2_radius); { sphere_2_radius = dist_to_corner ; }
                                         ^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3278:42: note: put the semicolon on a separate line to silence this warning
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3280:42: warning: if statement has empty body [-Wempty-body]
    if (dist_to_corner > sphere_2_radius); { sphere_2_radius = dist_to_corner ; }
                                         ^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3280:42: note: put the semicolon on a separate line to silence this warning
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_logger_2D_space.comp:574:45: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
  sprintf(this_storage.Detector_2D.Filename,filename);
                                            ^~~~~~~~
./python_tutorial.c:17318:18: note: expanded from macro 'filename'
#define filename mcclogger_space_filename
                 ^~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
  __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
                                                       ^~~~~~~~~~~
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_logger_2D_space.comp:574:45: note: treat the string as an argument to avoid this
  sprintf(this_storage.Detector_2D.Filename,filename);
                                            ^
                                            "%s", 
./python_tutorial.c:17318:18: note: expanded from macro 'filename'
#define filename mcclogger_space_filename
                 ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
  __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
                                                       ^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_abs_logger_2D_space.comp:543:49: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
  sprintf(this_abs_storage.Detector_2D.Filename,filename);
                                                ^~~~~~~~
./python_tutorial.c:17560:18: note: expanded from macro 'filename'
#define filename mccabs_logger_space_filename
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
  __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
                                                       ^~~~~~~~~~~
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_abs_logger_2D_space.comp:543:49: note: treat the string as an argument to avoid this
  sprintf(this_abs_storage.Detector_2D.Filename,filename);
                                                ^
                                                "%s", 
./python_tutorial.c:17560:18: note: expanded from macro 'filename'
#define filename mccabs_logger_space_filename
                 ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
  __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
                                                       ^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_master.comp:788:15: warning: left operand of comma operator has no effect [-Wunused-value]
          if (volume_index_main,Volumes[volume_index_main]->geometry.is_mask_volume == 0 ||
              ^~~~~~~~~~~~~~~~~
mccode-r.h:219:27: note: expanded from macro 'MPI_MASTER'
#define MPI_MASTER(instr) instr
                          ^~~~~
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_master.comp:788:90: warning: left operand of comma operator has no effect [-Wunused-value]
          if (volume_index_main,Volumes[volume_index_main]->geometry.is_mask_volume == 0 ||
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
mccode-r.h:219:27: note: expanded from macro 'MPI_MASTER'
#define MPI_MASTER(instr) instr
                          ^~~~~
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_master.comp:789:92: warning: left operand of comma operator has no effect [-Wunused-value]
              volume_index_main,Volumes[volume_index_main]->geometry.is_masked_volume == 0 ||
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
mccode-r.h:219:27: note: expanded from macro 'MPI_MASTER'
#define MPI_MASTER(instr) instr
                          ^~~~~
14 warnings generated.
INFO: ===
Opening input file '/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//data/Cu.laz' (Table_Read_Offset)
Table from file 'Cu.laz' (block 1) is 19 x 18 (x=1:6), constant step. interpolation: linear
  '# TITLE *-Cu-[FM3-M] Otte, H.M.[1961];# CELL 3.615050 3.615050 3.615050 90. ...'
PowderN: powder: Reading 19 rows from Cu.laz
PowderN: powder: Read 19 reflections from file 'Cu.laz'
PowderN: powder: Vc=47.24 [Angs] sigma_abs=15.12 [barn] sigma_inc=2.2 [barn] reflections=Cu.laz
---------------------------------------------------------------------
global_process_list.num_elements: 2
name of process [0]: incoherent 
component index [0]: 1 
name of process [1]: powder 
component index [1]: 4 
---------------------------------------------------------------------
global_material_list.num_elements: 3
name of material    [0]: inc_material 
component index     [0]: 2 
my_absoprtion       [0]: 0.000000 
number of processes [0]: 1 
name of material    [1]: abs_material 
component index     [1]: 3 
my_absoprtion       [1]: 3.000000 
number of processes [1]: 0 
name of material    [2]: powder_material 
component index     [2]: 5 
my_absoprtion       [2]: 1.200000 
number of processes [2]: 2 
---------------------------------------------------------------------
global_geometry_list.num_elements: 3

name of geometry    [0]: box_inc 
component index     [0]: 7 
Volume.name         [0]: box_inc 
Volume.p_physics.is_vacuum           [0]: 0 
Volume.p_physics.my_absorption       [0]: 0.000000 
Volume.p_physics.number of processes [0]: 1 
Volume.geometry.shape                [0]: box 
Volume.geometry.center.x             [0]: 0.040000 
Volume.geometry.center.y             [0]: 0.000000 
Volume.geometry.center.z             [0]: 1.000000 
Volume.geometry.rotation_matrix[0]           [0]: [1.000000 0.000000 0.000000] 
Volume.geometry.rotation_matrix[1]           [0]: [0.000000 1.000000 0.000000] 
Volume.geometry.rotation_matrix[2]           [0]: [0.000000 0.000000 1.000000] 
Volume.geometry.focus_data_array.elements[0].Aim             [0]: [0.000000 0.000000 1.000000] 

name of geometry    [1]: box_powder 
component index     [1]: 8 
Volume.name         [1]: box_powder 
Volume.p_physics.is_vacuum           [1]: 0 
Volume.p_physics.my_absorption       [1]: 1.200000 
Volume.p_physics.number of processes [1]: 2 
Volume.geometry.shape                [1]: box 
Volume.geometry.center.x             [1]: 0.000000 
Volume.geometry.center.y             [1]: 0.000000 
Volume.geometry.center.z             [1]: 1.000000 
Volume.geometry.rotation_matrix[0]           [1]: [1.000000 0.000000 0.000000] 
Volume.geometry.rotation_matrix[1]           [1]: [0.000000 1.000000 0.000000] 
Volume.geometry.rotation_matrix[2]           [1]: [0.000000 0.000000 1.000000] 
Volume.geometry.focus_data_array.elements[0].Aim             [1]: [0.000000 0.000000 1.000000] 

name of geometry    [2]: box_abs 
component index     [2]: 9 
Volume.name         [2]: box_abs 
Volume.p_physics.is_vacuum           [2]: 0 
Volume.p_physics.my_absorption       [2]: 3.000000 
Volume.p_physics.number of processes [2]: 0 
Volume.geometry.shape                [2]: box 
Volume.geometry.center.x             [2]: -0.040000 
Volume.geometry.center.y             [2]: 0.000000 
Volume.geometry.center.z             [2]: 1.000000 
Volume.geometry.rotation_matrix[0]           [2]: [1.000000 0.000000 0.000000] 
Volume.geometry.rotation_matrix[1]           [2]: [0.000000 1.000000 0.000000] 
Volume.geometry.rotation_matrix[2]           [2]: [0.000000 0.000000 1.000000] 
Volume.geometry.focus_data_array.elements[0].Aim             [2]: [0.000000 0.000000 1.000000] 
---------------------------------------------------------------------
number_of_volumes = 4
number_of_masks = 0
number_of_masked_volumes = 0

 ---- Overview of the lists generated for each volume ---- 
List overview for surrounding vacuum
LIST: Children for Volume                  0 = [1,2,3]
LIST: Direct_children for Volume           0 = [1,2,3]
LIST: Intersect_check_list for Volume      0 = [1,2,3]
LIST: Mask_intersect_list for Volume       0 = []
LIST: Destinations_list for Volume         0 = []
LIST: Reduced_destinations_list for Volume 0 = []
LIST: Next_volume_list for Volume          0 = [1,2,3]
LIST: mask_list for Volume                 0 = []
LIST: masked_by_list for Volume            0 = []
LIST: masked_by_mask_index_list for Volume 0 = []
      mask_mode for Volume                 0 = 0

List overview for box_inc with box shape made of inc_material
LIST: Children for Volume                  1 = []
LIST: Direct_children for Volume           1 = []
LIST: Intersect_check_list for Volume      1 = []
LIST: Mask_intersect_list for Volume       1 = []
LIST: Destinations_list for Volume         1 = [0]
LIST: Reduced_destinations_list for Volume 1 = []
LIST: Next_volume_list for Volume          1 = [0]
      Is_vacuum for Volume                 1 = 0
      is_mask_volume for Volume            1 = 0
      is_masked_volume for Volume          1 = 0
      is_exit_volume for Volume            1 = 0
LIST: mask_list for Volume                 1 = []
LIST: masked_by_list for Volume            1 = []
LIST: masked_by_mask_index_list for Volume 1 = []
      mask_mode for Volume                 1 = 0

List overview for box_powder with box shape made of powder_material
LIST: Children for Volume                  2 = []
LIST: Direct_children for Volume           2 = []
LIST: Intersect_check_list for Volume      2 = []
LIST: Mask_intersect_list for Volume       2 = []
LIST: Destinations_list for Volume         2 = [0]
LIST: Reduced_destinations_list for Volume 2 = []
LIST: Next_volume_list for Volume          2 = [0]
      Is_vacuum for Volume                 2 = 0
      is_mask_volume for Volume            2 = 0
      is_masked_volume for Volume          2 = 0
      is_exit_volume for Volume            2 = 0
LIST: mask_list for Volume                 2 = []
LIST: masked_by_list for Volume            2 = []
LIST: masked_by_mask_index_list for Volume 2 = []
      mask_mode for Volume                 2 = 0

List overview for box_abs with box shape made of abs_material
LIST: Children for Volume                  3 = []
LIST: Direct_children for Volume           3 = []
LIST: Intersect_check_list for Volume      3 = []
LIST: Mask_intersect_list for Volume       3 = []
LIST: Destinations_list for Volume         3 = [0]
LIST: Reduced_destinations_list for Volume 3 = []
LIST: Next_volume_list for Volume          3 = [0]
      Is_vacuum for Volume                 3 = 0
      is_mask_volume for Volume            3 = 0
      is_masked_volume for Volume          3 = 0
      is_exit_volume for Volume            3 = 0
LIST: mask_list for Volume                 3 = []
LIST: masked_by_list for Volume            3 = []
LIST: masked_by_mask_index_list for Volume 3 = []
      mask_mode for Volume                 3 = 0

Union_master component master initialized sucessfully
Detector: logger_space_I=3.16457e-09 logger_space_ERR=4.64376e-12 logger_space_N=474113 "logger.dat"
Detector: abs_logger_space_I=1.70439e-09 abs_logger_space_ERR=1.97552e-12 abs_logger_space_N=1.08687e+06 "abs_logger.dat"
INFO: Placing instr file copy python_tutorial.instr in dataset /Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/data_folder/union_materials_1
loading system configuration

Interpreting the results

The first logger shows scattering, and since the top box has incoherent, and the middle both powder and incoherent, we expect those to show up. We can see the beam attenuation, as the beam originates from the left side.

The second logger shows absorption, and here the top box is absent as it has no absorption cross section. The bottom box is however visible now, as it has absorption but no scattering. As the absorber is quite strong, we see the attenuation here as well.

ms.make_sub_plot(data)
../_images/Union_tutorial_1_processes_and_materials_40_0.png

Alternative run to show powder properties

In order to see the scattering from the powder sample, we restrict the source size to only illuminate the center box with a powder material. A wavelength with powder lines close to 90 deg is selected to ensure the scattering from the center box hits the surrounding boxes.

We choose to show the data with logarithmic colorscale using the name_plot_options method on functions.

instrument.set_parameters(wavelength=2.8, source_width=0.03)
instrument.settings(ncount=5E6, output_path="data_folder/union_materials")
instrument.show_settings()

data = instrument.backengine()
Instrument settings:
  ncount:           5.00e+06
  output_path:      data_folder/union_materials
  run_path:         run_folder
  package_path:     /Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1
  executable_path:  /Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1/bin/
  executable:       mcrun
  force_compile:    True
INFO: Using directory: "/Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/data_folder/union_materials_2"
INFO: Regenerating c-file: python_tutorial.c
CFLAGS= -I@MCCODE_LIB@/share/ -I@MCCODE_LIB@/share/
    INFO: Recompiling: ./python_tutorial.out
mccode-r.c:2837:3: warning: expression result unused [-Wunused-value]
  *t0;
  ^~~
In file included from /Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Incoherent_process.comp:66:
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Union_functions.c:1604:105: warning: incompatible function pointer types passing 'int (const struct saved_history_struct *, const struct saved_history_struct *)' to parameter of type 'int (* _Nonnull)(const void *, const void *)' [-Wincompatible-function-pointer-types]
  qsort(total_history.saved_histories,total_history.used_elements,sizeof (struct saved_history_struct), Sample_compare_history_intensities);
                                                                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stdlib.h:161:22: note: passing argument to parameter '__compar' here
            int (* _Nonnull __compar)(const void *, const void *));
                            ^
In file included from /Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Incoherent_process.comp:66:
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Union_functions.c:1613:20: warning: incompatible pointer types passing 'struct saved_history_struct *' to parameter of type 'struct dynamic_history_list *' [-Wincompatible-pointer-types]
    printf_history(&total_history.saved_histories[history_iterate]);
                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mccode-r.h:219:27: note: expanded from macro 'MPI_MASTER'
#define MPI_MASTER(instr) instr
                          ^~~~~
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Union_functions.c:1434:50: note: passing argument to parameter 'history' here
void printf_history(struct dynamic_history_list *history) {
                                                 ^
In file included from /Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Incoherent_process.comp:66:
In file included from /Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Union_functions.c:2030:
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:839:1: warning: non-void function does not return a value in all control paths [-Wreturn-type]
};
^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:883:1: warning: non-void function does not return a value [-Wreturn-type]
};
^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3274:42: warning: if statement has empty body [-Wempty-body]
    if (dist_to_corner > sphere_2_radius); { sphere_2_radius = dist_to_corner ; }
                                         ^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3274:42: note: put the semicolon on a separate line to silence this warning
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3276:42: warning: if statement has empty body [-Wempty-body]
    if (dist_to_corner > sphere_2_radius); { sphere_2_radius = dist_to_corner ; }
                                         ^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3276:42: note: put the semicolon on a separate line to silence this warning
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3278:42: warning: if statement has empty body [-Wempty-body]
    if (dist_to_corner > sphere_2_radius); { sphere_2_radius = dist_to_corner ; }
                                         ^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3278:42: note: put the semicolon on a separate line to silence this warning
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3280:42: warning: if statement has empty body [-Wempty-body]
    if (dist_to_corner > sphere_2_radius); { sphere_2_radius = dist_to_corner ; }
                                         ^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//share/Geometry_functions.c:3280:42: note: put the semicolon on a separate line to silence this warning
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_logger_2D_space.comp:574:45: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
  sprintf(this_storage.Detector_2D.Filename,filename);
                                            ^~~~~~~~
./python_tutorial.c:17318:18: note: expanded from macro 'filename'
#define filename mcclogger_space_filename
                 ^~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
  __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
                                                       ^~~~~~~~~~~
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_logger_2D_space.comp:574:45: note: treat the string as an argument to avoid this
  sprintf(this_storage.Detector_2D.Filename,filename);
                                            ^
                                            "%s", 
./python_tutorial.c:17318:18: note: expanded from macro 'filename'
#define filename mcclogger_space_filename
                 ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
  __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
                                                       ^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_abs_logger_2D_space.comp:543:49: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
  sprintf(this_abs_storage.Detector_2D.Filename,filename);
                                                ^~~~~~~~
./python_tutorial.c:17560:18: note: expanded from macro 'filename'
#define filename mccabs_logger_space_filename
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
  __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
                                                       ^~~~~~~~~~~
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_abs_logger_2D_space.comp:543:49: note: treat the string as an argument to avoid this
  sprintf(this_abs_storage.Detector_2D.Filename,filename);
                                                ^
                                                "%s", 
./python_tutorial.c:17560:18: note: expanded from macro 'filename'
#define filename mccabs_logger_space_filename
                 ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf'
  __builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
                                                       ^
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_master.comp:788:15: warning: left operand of comma operator has no effect [-Wunused-value]
          if (volume_index_main,Volumes[volume_index_main]->geometry.is_mask_volume == 0 ||
              ^~~~~~~~~~~~~~~~~
mccode-r.h:219:27: note: expanded from macro 'MPI_MASTER'
#define MPI_MASTER(instr) instr
                          ^~~~~
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_master.comp:788:90: warning: left operand of comma operator has no effect [-Wunused-value]
          if (volume_index_main,Volumes[volume_index_main]->geometry.is_mask_volume == 0 ||
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
mccode-r.h:219:27: note: expanded from macro 'MPI_MASTER'
#define MPI_MASTER(instr) instr
                          ^~~~~
/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//contrib/union/Union_master.comp:789:92: warning: left operand of comma operator has no effect [-Wunused-value]
              volume_index_main,Volumes[volume_index_main]->geometry.is_masked_volume == 0 ||
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
mccode-r.h:219:27: note: expanded from macro 'MPI_MASTER'
#define MPI_MASTER(instr) instr
                          ^~~~~
14 warnings generated.
INFO: ===
Opening input file '/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//data/Cu.laz' (Table_Read_Offset)
Table from file 'Cu.laz' (block 1) is 19 x 18 (x=1:6), constant step. interpolation: linear
  '# TITLE *-Cu-[FM3-M] Otte, H.M.[1961];# CELL 3.615050 3.615050 3.615050 90. ...'
PowderN: powder: Reading 19 rows from Cu.laz
PowderN: powder: Read 19 reflections from file 'Cu.laz'
PowderN: powder: Vc=47.24 [Angs] sigma_abs=15.12 [barn] sigma_inc=2.2 [barn] reflections=Cu.laz
---------------------------------------------------------------------
global_process_list.num_elements: 2
name of process [0]: incoherent 
component index [0]: 1 
name of process [1]: powder 
component index [1]: 4 
---------------------------------------------------------------------
global_material_list.num_elements: 3
name of material    [0]: inc_material 
component index     [0]: 2 
my_absoprtion       [0]: 0.000000 
number of processes [0]: 1 
name of material    [1]: abs_material 
component index     [1]: 3 
my_absoprtion       [1]: 3.000000 
number of processes [1]: 0 
name of material    [2]: powder_material 
component index     [2]: 5 
my_absoprtion       [2]: 1.200000 
number of processes [2]: 2 
---------------------------------------------------------------------
global_geometry_list.num_elements: 3

name of geometry    [0]: box_inc 
component index     [0]: 7 
Volume.name         [0]: box_inc 
Volume.p_physics.is_vacuum           [0]: 0 
Volume.p_physics.my_absorption       [0]: 0.000000 
Volume.p_physics.number of processes [0]: 1 
Volume.geometry.shape                [0]: box 
Volume.geometry.center.x             [0]: 0.040000 
Volume.geometry.center.y             [0]: 0.000000 
Volume.geometry.center.z             [0]: 1.000000 
Volume.geometry.rotation_matrix[0]           [0]: [1.000000 0.000000 0.000000] 
Volume.geometry.rotation_matrix[1]           [0]: [0.000000 1.000000 0.000000] 
Volume.geometry.rotation_matrix[2]           [0]: [0.000000 0.000000 1.000000] 
Volume.geometry.focus_data_array.elements[0].Aim             [0]: [0.000000 0.000000 1.000000] 

name of geometry    [1]: box_powder 
component index     [1]: 8 
Volume.name         [1]: box_powder 
Volume.p_physics.is_vacuum           [1]: 0 
Volume.p_physics.my_absorption       [1]: 1.200000 
Volume.p_physics.number of processes [1]: 2 
Volume.geometry.shape                [1]: box 
Volume.geometry.center.x             [1]: 0.000000 
Volume.geometry.center.y             [1]: 0.000000 
Volume.geometry.center.z             [1]: 1.000000 
Volume.geometry.rotation_matrix[0]           [1]: [1.000000 0.000000 0.000000] 
Volume.geometry.rotation_matrix[1]           [1]: [0.000000 1.000000 0.000000] 
Volume.geometry.rotation_matrix[2]           [1]: [0.000000 0.000000 1.000000] 
Volume.geometry.focus_data_array.elements[0].Aim             [1]: [0.000000 0.000000 1.000000] 

name of geometry    [2]: box_abs 
component index     [2]: 9 
Volume.name         [2]: box_abs 
Volume.p_physics.is_vacuum           [2]: 0 
Volume.p_physics.my_absorption       [2]: 3.000000 
Volume.p_physics.number of processes [2]: 0 
Volume.geometry.shape                [2]: box 
Volume.geometry.center.x             [2]: -0.040000 
Volume.geometry.center.y             [2]: 0.000000 
Volume.geometry.center.z             [2]: 1.000000 
Volume.geometry.rotation_matrix[0]           [2]: [1.000000 0.000000 0.000000] 
Volume.geometry.rotation_matrix[1]           [2]: [0.000000 1.000000 0.000000] 
Volume.geometry.rotation_matrix[2]           [2]: [0.000000 0.000000 1.000000] 
Volume.geometry.focus_data_array.elements[0].Aim             [2]: [0.000000 0.000000 1.000000] 
---------------------------------------------------------------------
number_of_volumes = 4
number_of_masks = 0
number_of_masked_volumes = 0

 ---- Overview of the lists generated for each volume ---- 
List overview for surrounding vacuum
LIST: Children for Volume                  0 = [1,2,3]
LIST: Direct_children for Volume           0 = [1,2,3]
LIST: Intersect_check_list for Volume      0 = [1,2,3]
LIST: Mask_intersect_list for Volume       0 = []
LIST: Destinations_list for Volume         0 = []
LIST: Reduced_destinations_list for Volume 0 = []
LIST: Next_volume_list for Volume          0 = [1,2,3]
LIST: mask_list for Volume                 0 = []
LIST: masked_by_list for Volume            0 = []
LIST: masked_by_mask_index_list for Volume 0 = []
      mask_mode for Volume                 0 = 0

List overview for box_inc with box shape made of inc_material
LIST: Children for Volume                  1 = []
LIST: Direct_children for Volume           1 = []
LIST: Intersect_check_list for Volume      1 = []
LIST: Mask_intersect_list for Volume       1 = []
LIST: Destinations_list for Volume         1 = [0]
LIST: Reduced_destinations_list for Volume 1 = []
LIST: Next_volume_list for Volume          1 = [0]
      Is_vacuum for Volume                 1 = 0
      is_mask_volume for Volume            1 = 0
      is_masked_volume for Volume          1 = 0
      is_exit_volume for Volume            1 = 0
LIST: mask_list for Volume                 1 = []
LIST: masked_by_list for Volume            1 = []
LIST: masked_by_mask_index_list for Volume 1 = []
      mask_mode for Volume                 1 = 0

List overview for box_powder with box shape made of powder_material
LIST: Children for Volume                  2 = []
LIST: Direct_children for Volume           2 = []
LIST: Intersect_check_list for Volume      2 = []
LIST: Mask_intersect_list for Volume       2 = []
LIST: Destinations_list for Volume         2 = [0]
LIST: Reduced_destinations_list for Volume 2 = []
LIST: Next_volume_list for Volume          2 = [0]
      Is_vacuum for Volume                 2 = 0
      is_mask_volume for Volume            2 = 0
      is_masked_volume for Volume          2 = 0
      is_exit_volume for Volume            2 = 0
LIST: mask_list for Volume                 2 = []
LIST: masked_by_list for Volume            2 = []
LIST: masked_by_mask_index_list for Volume 2 = []
      mask_mode for Volume                 2 = 0

List overview for box_abs with box shape made of abs_material
LIST: Children for Volume                  3 = []
LIST: Direct_children for Volume           3 = []
LIST: Intersect_check_list for Volume      3 = []
LIST: Mask_intersect_list for Volume       3 = []
LIST: Destinations_list for Volume         3 = [0]
LIST: Reduced_destinations_list for Volume 3 = []
LIST: Next_volume_list for Volume          3 = [0]
      Is_vacuum for Volume                 3 = 0
      is_mask_volume for Volume            3 = 0
      is_masked_volume for Volume          3 = 0
      is_exit_volume for Volume            3 = 0
LIST: mask_list for Volume                 3 = []
LIST: masked_by_list for Volume            3 = []
LIST: masked_by_mask_index_list for Volume 3 = []
      mask_mode for Volume                 3 = 0

Union_master component master initialized sucessfully
Detector: logger_space_I=1.13138e-09 logger_space_ERR=5.90325e-13 logger_space_N=3.86154e+06 "logger.dat"
Detector: abs_logger_space_I=4.15433e-11 abs_logger_space_ERR=2.36423e-14 abs_logger_space_N=4.11857e+06 "abs_logger.dat"
INFO: Placing instr file copy python_tutorial.instr in dataset /Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/data_folder/union_materials_2
loading system configuration
ms.name_plot_options("logger_space", data, log=True)
ms.name_plot_options("abs_logger_space", data, log=True)
ms.make_sub_plot(data)
../_images/Union_tutorial_1_processes_and_materials_43_0.png

Interpretation of the data

Now that the direct beam only hits the center box, all rays that enter the surrounding boxes are scattered from that center box. Since the center box contains a powder, the scattered beam is not homogeneous and most of it is in the form of Bragg peaks with certain scattering angles, and we can see two of these intersecting the surrounding geometries.

Troubleshooting

In case of issues with the notebooks concerning the Union components or McStasScript it is recommended to:

  • Update McStasScript with python -m pip install –upgrade mcstasscript

  • Get newest version of Union components (Both library files and components themselves)

Since the Union components need to collaborate, it is important to have the same version of the libraries and components. The newest version of the components can be found here: https://github.com/McStasMcXtrace/McCode/tree/master/mcstas-comps/contrib/union All libraries for McStas are found here: https://github.com/McStasMcXtrace/McCode/tree/master/mcstas-comps/share but only a few are needed for the Union components:

  • Union_initialization.c

  • Union_functions.c

  • Geometry_functions.c

  • Union_last_functions.c (if on McStas 3.X)

If using McStas 3.X, it could be that the Union_init component and Union_stop component was not added.