Union tutorial on masks

There are some geometries that are impossible to build using only the priority based system geometry system, for example making part of a cylinder thinner, which is needed for a cryostat window. In many such cases, masks can be used to solve the problem.

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

Setting up an example without masks

First we set up an example with a thick and hollow Al cylinder and a logger to view the spatial distribution of scattering.

Al_inc = instrument.add_component("Al_inc", "Incoherent_process")
Al_inc.sigma = 0.0082
Al_inc.unit_cell_volume = 66.4

Al_pow = instrument.add_component("Al_pow", "Powder_process")
Al_pow.reflections = '"Al.laz"'

Al = instrument.add_component("Al", "Union_make_material")
Al.process_string = '"Al_inc,Al_pow"'
Al.my_absorption = 100*0.231/66.4 # barns [m^2 E-28]*Å^3 [m^3 E-30]=[m E-2], factor 100

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

src.xwidth = 0.2
src.yheight = 0.035
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.01*wavelength"
src.flux = 1E13

wall = instrument.add_component("wall", "Union_cylinder")
wall.set_AT([0,0,1], RELATIVE=src)
wall.yheight = 0.15
wall.radius = 0.1
wall.material_string='"Al"' 
wall.priority = 10

wall_vac = instrument.add_component("wall_vacuum", "Union_cylinder")
wall_vac.set_AT([0,0,0], RELATIVE=wall)
wall_vac.yheight = 0.15 + 0.01
wall_vac.radius = 0.1 - 0.02
wall_vac.material_string='"Vacuum"' 
wall_vac.priority = 50

logger_zx = instrument.add_component("logger_space_zx", "Union_logger_2D_space")
logger_zx.set_RELATIVE(wall)
logger_zx.D_direction_1 = '"z"'
logger_zx.D1_min = -0.12
logger_zx.D1_max = 0.12
logger_zx.n1 = 300
logger_zx.D_direction_2 = '"x"'
logger_zx.D2_min = -0.12
logger_zx.D2_max = 0.12
logger_zx.n2 = 300
logger_zx.filename = '"logger_zx.dat"'

master = instrument.add_component("master", "Union_master")

instrument.show_diagram()
../_images/Union_tutorial_5_masks_4_0.png ../_images/Union_tutorial_5_masks_4_1.png

In the above diagram it is clear that the wall is made of Al and the master simulates the wall and the wall_vacuum.

instrument.settings(ncount=2E6, output_path="data_folder/union_masks")

data = instrument.backengine()
INFO: Using directory: "/Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/data_folder/union_masks_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:11415:18: note: expanded from macro 'filename'
#define filename mcclogger_space_zx_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:11415:18: note: expanded from macro 'filename'
#define filename mcclogger_space_zx_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
                          ^~~~~
13 warnings generated.
INFO: ===
Opening input file '/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//data/Al.laz' (Table_Read_Offset)
Table from file 'Al.laz' (block 1) is 26 x 18 (x=1:8), constant step. interpolation: linear
  '# TITLE *Aluminum-Al-[FM3-M] Miller, H.P.jr.;DuMond, J.W.M.[1942] at 298 K; ...'
PowderN: Al_pow: Reading 26 rows from Al.laz
PowderN: Al_pow: Read 26 reflections from file 'Al.laz'
PowderN: Al_pow: Vc=66.4 [Angs] sigma_abs=0.924 [barn] sigma_inc=0.0328 [barn] reflections=Al.laz
---------------------------------------------------------------------
global_process_list.num_elements: 2
name of process [0]: Al_inc 
component index [0]: 1 
name of process [1]: Al_pow 
component index [1]: 2 
---------------------------------------------------------------------
global_material_list.num_elements: 1
name of material    [0]: Al 
component index     [0]: 3 
my_absoprtion       [0]: 0.347892 
number of processes [0]: 2 
---------------------------------------------------------------------
global_geometry_list.num_elements: 1

name of geometry    [0]: wall 
component index     [0]: 5 
Volume.name         [0]: wall 
Volume.p_physics.is_vacuum           [0]: 0 
Volume.p_physics.my_absorption       [0]: 0.347892 
Volume.p_physics.number of processes [0]: 2 
Volume.geometry.shape                [0]: cylinder 
Volume.geometry.center.x             [0]: 0.000000 
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.geometry_parameters.cyl_radius [0]: 0.100000 
Volume.geometry.geometry_parameters.height [0]: 0.150000 
Volume.geometry.focus_data_array.elements[0].Aim             [0]: [0.000000 0.000000 1.000000] 

name of geometry    [1]: wall_vacuum 
component index     [1]: 6 
Volume.name         [1]: wall_vacuum 
Volume.p_physics.is_vacuum           [1]: 1 
Volume.p_physics.my_absorption       [1]: 0.000000 
Volume.p_physics.number of processes [1]: 0 
Volume.geometry.shape                [1]: cylinder 
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.geometry_parameters.cyl_radius [1]: 0.080000 
Volume.geometry.geometry_parameters.height [1]: 0.160000 
Volume.geometry.focus_data_array.elements[0].Aim             [1]: [0.000000 0.000000 1.000000] 
---------------------------------------------------------------------
number_of_volumes = 3
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]
LIST: Direct_children for Volume           0 = [1,2]
LIST: Intersect_check_list for Volume      0 = [1,2]
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]
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 wall with cylinder shape made of Al
LIST: Children for Volume                  1 = []
LIST: Direct_children for Volume           1 = []
LIST: Intersect_check_list for Volume      1 = [2]
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,2]
      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 wall_vacuum with cylinder shape made of Vacuum
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,1]
LIST: Reduced_destinations_list for Volume 2 = [1]
LIST: Next_volume_list for Volume          2 = [0,1]
      Is_vacuum for Volume                 2 = 1
      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

Union_master component master initialized sucessfully
Detector: logger_space_zx_I=1440.56 logger_space_zx_ERR=4.3992 logger_space_zx_N=111295 "logger_zx.dat"
INFO: Placing instr file copy python_tutorial.instr in dataset /Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/data_folder/union_masks_2
loading system configuration
ms.make_sub_plot(data)
../_images/Union_tutorial_5_masks_7_0.png

Masks

All Union geometries can act as a mask for a list of other already defined geometries. The geometries affected by a mask will only exist inside the mask, while the parts outside will not have any effect on this simulation. This provides some interesting geometrical capabilities, for example by defining two spheres with some overlap and making one a mask of the other, a classical lens shape can be created.

The relevant parameters of all geometry components are:

  • mask_string : comma separated list of geometry names the mask should be applied to

  • mask_setting : selects between “ANY” or “ALL” mode. Default mode is “ALL”.

The mask mode is only important if several masks affect the same geometry, per default just having any of the masks overlap the target geometry allow it to exists, which correspond to the “ANY” mode. If the “ALL” mode is selected, the target geometry will only exists in regions where all the masks and itself overlap.

Note that a unique priority is still necessary, but it is not used.

Adding a window using masks

Here we add a window to one side of the cylinder by inserting a larger vacuum cylinder, but mask it so that it is only active in the area around the window. In this way we get a nice curved window. We chose a box shape for the mask, but we could also have chosen a cylinder to get a round window.

window = instrument.add_component("window", "Union_cylinder", before="master")
window.set_AT([0,0,0], RELATIVE=wall)
window.yheight = 0.15 + 0.02
window.radius = 0.1 - 0.01
window.material_string='"Vacuum"' 
window.priority = 25

mask = instrument.add_component("mask", "Union_box", before="master")
mask.xwidth = 0.1
mask.yheight = 0.2
mask.zdepth = 0.09
mask.priority = 1
mask.mask_string='"window"'
mask.set_AT([0,0,-0.1], RELATIVE=wall)

instrument.show_diagram()
../_images/Union_tutorial_5_masks_10_0.png ../_images/Union_tutorial_5_masks_10_1.png

The windows was added to the diagram and is connected to the master as expected. The mask shows up as a component that only acts on the window geometry, as the mask itself is not simulated, it just modifies the window.

data = instrument.backengine()
INFO: Using directory: "/Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/data_folder/union_masks_3"
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:11875:18: note: expanded from macro 'filename'
#define filename mcclogger_space_zx_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:11875:18: note: expanded from macro 'filename'
#define filename mcclogger_space_zx_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
                          ^~~~~
13 warnings generated.
INFO: ===
Opening input file '/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//data/Al.laz' (Table_Read_Offset)
Table from file 'Al.laz' (block 1) is 26 x 18 (x=1:8), constant step. interpolation: linear
  '# TITLE *Aluminum-Al-[FM3-M] Miller, H.P.jr.;DuMond, J.W.M.[1942] at 298 K; ...'
PowderN: Al_pow: Reading 26 rows from Al.laz
PowderN: Al_pow: Read 26 reflections from file 'Al.laz'
PowderN: Al_pow: Vc=66.4 [Angs] sigma_abs=0.924 [barn] sigma_inc=0.0328 [barn] reflections=Al.laz
---------------------------------------------------------------------
global_process_list.num_elements: 2
name of process [0]: Al_inc 
component index [0]: 1 
name of process [1]: Al_pow 
component index [1]: 2 
---------------------------------------------------------------------
global_material_list.num_elements: 1
name of material    [0]: Al 
component index     [0]: 3 
my_absoprtion       [0]: 0.347892 
number of processes [0]: 2 
---------------------------------------------------------------------
global_geometry_list.num_elements: 1

name of geometry    [0]: wall 
component index     [0]: 5 
Volume.name         [0]: wall 
Volume.p_physics.is_vacuum           [0]: 0 
Volume.p_physics.my_absorption       [0]: 0.347892 
Volume.p_physics.number of processes [0]: 2 
Volume.geometry.shape                [0]: cylinder 
Volume.geometry.center.x             [0]: 0.000000 
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.geometry_parameters.cyl_radius [0]: 0.100000 
Volume.geometry.geometry_parameters.height [0]: 0.150000 
Volume.geometry.focus_data_array.elements[0].Aim             [0]: [0.000000 0.000000 1.000000] 

name of geometry    [1]: wall_vacuum 
component index     [1]: 6 
Volume.name         [1]: wall_vacuum 
Volume.p_physics.is_vacuum           [1]: 1 
Volume.p_physics.my_absorption       [1]: 0.000000 
Volume.p_physics.number of processes [1]: 0 
Volume.geometry.shape                [1]: cylinder 
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.geometry_parameters.cyl_radius [1]: 0.080000 
Volume.geometry.geometry_parameters.height [1]: 0.160000 
Volume.geometry.focus_data_array.elements[0].Aim             [1]: [0.000000 0.000000 1.000000] 

name of geometry    [2]: window 
component index     [2]: 8 
Volume.name         [2]: window 
Volume.p_physics.is_vacuum           [2]: 1 
Volume.p_physics.my_absorption       [2]: 0.000000 
Volume.p_physics.number of processes [2]: 0 
Volume.geometry.shape                [2]: cylinder 
Volume.geometry.center.x             [2]: 0.000000 
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.geometry_parameters.cyl_radius [2]: 0.090000 
Volume.geometry.geometry_parameters.height [2]: 0.170000 
Volume.geometry.focus_data_array.elements[0].Aim             [2]: [0.000000 0.000000 1.000000] 

name of geometry    [3]: mask 
component index     [3]: 9 
Volume.name         [3]: mask 
Volume.geometry.shape                [3]: box 
Volume.geometry.center.x             [3]: 0.000000 
Volume.geometry.center.y             [3]: 0.000000 
Volume.geometry.center.z             [3]: 0.900000 
Volume.geometry.rotation_matrix[0]           [3]: [1.000000 0.000000 0.000000] 
Volume.geometry.rotation_matrix[1]           [3]: [0.000000 1.000000 0.000000] 
Volume.geometry.rotation_matrix[2]           [3]: [0.000000 0.000000 1.000000] 
Volume.geometry.focus_data_array.elements[0].Aim             [3]: [0.000000 0.000000 1.000000] 
---------------------------------------------------------------------
number_of_volumes = 5
number_of_masks = 1
number_of_masked_volumes = 1

 ---- Overview of the lists generated for each volume ---- 
List overview for surrounding vacuum
LIST: Children for Volume                  0 = [1,2,3,4]
LIST: Direct_children for Volume           0 = [1,3,4]
LIST: Intersect_check_list for Volume      0 = [1,2,4]
LIST: Mask_intersect_list for Volume       0 = [3]
LIST: Destinations_list for Volume         0 = []
LIST: Reduced_destinations_list for Volume 0 = []
LIST: Next_volume_list for Volume          0 = [3,1,2]
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 wall with cylinder shape made of Al
LIST: Children for Volume                  1 = []
LIST: Direct_children for Volume           1 = []
LIST: Intersect_check_list for Volume      1 = [2,4]
LIST: Mask_intersect_list for Volume       1 = [3]
LIST: Destinations_list for Volume         1 = [0]
LIST: Reduced_destinations_list for Volume 1 = []
LIST: Next_volume_list for Volume          1 = [0,3,2]
      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 wall_vacuum with cylinder shape made of Vacuum
LIST: Children for Volume                  2 = []
LIST: Direct_children for Volume           2 = []
LIST: Intersect_check_list for Volume      2 = [4]
LIST: Mask_intersect_list for Volume       2 = []
LIST: Destinations_list for Volume         2 = [0,1,3]
LIST: Reduced_destinations_list for Volume 2 = [1,3]
LIST: Next_volume_list for Volume          2 = [0,1,3]
      Is_vacuum for Volume                 2 = 1
      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 window with cylinder shape made of Vacuum
LIST: Children for Volume                  3 = [2]
LIST: Direct_children for Volume           3 = [2]
LIST: Intersect_check_list for Volume      3 = [2,4]
LIST: Mask_intersect_list for Volume       3 = []
LIST: Destinations_list for Volume         3 = [0,1]
LIST: Reduced_destinations_list for Volume 3 = [1]
LIST: Next_volume_list for Volume          3 = [0,1,2]
      Is_vacuum for Volume                 3 = 1
      is_mask_volume for Volume            3 = 0
      is_masked_volume for Volume          3 = 1
      is_exit_volume for Volume            3 = 0
LIST: mask_list for Volume                 3 = []
LIST: masked_by_list for Volume            3 = [4]
LIST: masked_by_mask_index_list for Volume 3 = [0]
      mask_mode for Volume                 3 = 1

List overview for mask with box shape made of Mask
LIST: Children for Volume                  4 = []
LIST: Direct_children for Volume           4 = []
LIST: Intersect_check_list for Volume      4 = []
LIST: Mask_intersect_list for Volume       4 = []
LIST: Destinations_list for Volume         4 = [0,1,2]
LIST: Reduced_destinations_list for Volume 4 = [1,2]
LIST: Next_volume_list for Volume          4 = [0,1,2]
      Is_vacuum for Volume                 4 = 0
      is_mask_volume for Volume            4 = 1
      is_masked_volume for Volume          4 = 0
      is_exit_volume for Volume            4 = 0
LIST: mask_list for Volume                 4 = [3]
LIST: masked_by_list for Volume            4 = []
LIST: masked_by_mask_index_list for Volume 4 = []
      mask_mode for Volume                 4 = 1

Union_master component master initialized sucessfully
Detector: logger_space_zx_I=1305.83 logger_space_zx_ERR=4.18847 logger_space_zx_N=100678 "logger_zx.dat"
INFO: Placing instr file copy python_tutorial.instr in dataset /Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/data_folder/union_masks_3
loading system configuration
ms.make_sub_plot(data)
../_images/Union_tutorial_5_masks_13_0.png

Adding an external window using a mask

It is also possible to create a thinner section where the material is reduced from the outside. Here we need to add both a vacuum and an aluminium geometry, both of which need to have a priority lower than the original inner vacuum. One mask can handle several geometries, just include both names in the mask_string parameter.

o_window = instrument.add_component("outer_window", "Union_cylinder", before="master")
o_window.set_AT([0,0,0], RELATIVE=wall)
o_window.yheight = 0.15 + 0.03
o_window.radius = 0.1 + 0.01
o_window.material_string='"Vacuum"' 
o_window.priority = 30

o_window_al = instrument.add_component("outer_window_Al", "Union_cylinder", before="master")
o_window_al.set_AT([0,0,0], RELATIVE=wall)
o_window_al.yheight = 0.15 + 0.04
o_window_al.radius = 0.1 - 0.01
o_window_al.material_string='"Al"' 
o_window_al.priority = 31

mask = instrument.add_component("mask_outer", "Union_box", before="master")
mask.xwidth = 0.12
mask.yheight = 0.2
mask.zdepth = 0.09
mask.priority = 2
mask.mask_string='"outer_window,outer_window_Al"'
mask.set_AT([0,0,0.1], RELATIVE=wall)

instrument.show_diagram()
../_images/Union_tutorial_5_masks_15_0.png ../_images/Union_tutorial_5_masks_15_1.png

For the outer window the mask_outer acts on two geometries, outer_window and outer_window_Al. Notice that both the arrow for Al and mask_outer go to outer_window_Al as they both impact that component, one as a material and the other as a mask.

data = instrument.backengine()
INFO: Using directory: "/Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/data_folder/union_masks_4"
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:12367:18: note: expanded from macro 'filename'
#define filename mcclogger_space_zx_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:12367:18: note: expanded from macro 'filename'
#define filename mcclogger_space_zx_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
                          ^~~~~
13 warnings generated.
INFO: ===
Opening input file '/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//data/Al.laz' (Table_Read_Offset)
Table from file 'Al.laz' (block 1) is 26 x 18 (x=1:8), constant step. interpolation: linear
  '# TITLE *Aluminum-Al-[FM3-M] Miller, H.P.jr.;DuMond, J.W.M.[1942] at 298 K; ...'
PowderN: Al_pow: Reading 26 rows from Al.laz
PowderN: Al_pow: Read 26 reflections from file 'Al.laz'
PowderN: Al_pow: Vc=66.4 [Angs] sigma_abs=0.924 [barn] sigma_inc=0.0328 [barn] reflections=Al.laz
---------------------------------------------------------------------
global_process_list.num_elements: 2
name of process [0]: Al_inc 
component index [0]: 1 
name of process [1]: Al_pow 
component index [1]: 2 
---------------------------------------------------------------------
global_material_list.num_elements: 1
name of material    [0]: Al 
component index     [0]: 3 
my_absoprtion       [0]: 0.347892 
number of processes [0]: 2 
---------------------------------------------------------------------
global_geometry_list.num_elements: 1

name of geometry    [0]: wall 
component index     [0]: 5 
Volume.name         [0]: wall 
Volume.p_physics.is_vacuum           [0]: 0 
Volume.p_physics.my_absorption       [0]: 0.347892 
Volume.p_physics.number of processes [0]: 2 
Volume.geometry.shape                [0]: cylinder 
Volume.geometry.center.x             [0]: 0.000000 
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.geometry_parameters.cyl_radius [0]: 0.100000 
Volume.geometry.geometry_parameters.height [0]: 0.150000 
Volume.geometry.focus_data_array.elements[0].Aim             [0]: [0.000000 0.000000 1.000000] 

name of geometry    [1]: wall_vacuum 
component index     [1]: 6 
Volume.name         [1]: wall_vacuum 
Volume.p_physics.is_vacuum           [1]: 1 
Volume.p_physics.my_absorption       [1]: 0.000000 
Volume.p_physics.number of processes [1]: 0 
Volume.geometry.shape                [1]: cylinder 
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.geometry_parameters.cyl_radius [1]: 0.080000 
Volume.geometry.geometry_parameters.height [1]: 0.160000 
Volume.geometry.focus_data_array.elements[0].Aim             [1]: [0.000000 0.000000 1.000000] 

name of geometry    [2]: window 
component index     [2]: 8 
Volume.name         [2]: window 
Volume.p_physics.is_vacuum           [2]: 1 
Volume.p_physics.my_absorption       [2]: 0.000000 
Volume.p_physics.number of processes [2]: 0 
Volume.geometry.shape                [2]: cylinder 
Volume.geometry.center.x             [2]: 0.000000 
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.geometry_parameters.cyl_radius [2]: 0.090000 
Volume.geometry.geometry_parameters.height [2]: 0.170000 
Volume.geometry.focus_data_array.elements[0].Aim             [2]: [0.000000 0.000000 1.000000] 

name of geometry    [3]: mask 
component index     [3]: 9 
Volume.name         [3]: mask 
Volume.geometry.shape                [3]: box 
Volume.geometry.center.x             [3]: 0.000000 
Volume.geometry.center.y             [3]: 0.000000 
Volume.geometry.center.z             [3]: 0.900000 
Volume.geometry.rotation_matrix[0]           [3]: [1.000000 0.000000 0.000000] 
Volume.geometry.rotation_matrix[1]           [3]: [0.000000 1.000000 0.000000] 
Volume.geometry.rotation_matrix[2]           [3]: [0.000000 0.000000 1.000000] 
Volume.geometry.focus_data_array.elements[0].Aim             [3]: [0.000000 0.000000 1.000000] 

name of geometry    [4]: outer_window 
component index     [4]: 10 
Volume.name         [4]: outer_window 
Volume.p_physics.is_vacuum           [4]: 1 
Volume.p_physics.my_absorption       [4]: 0.000000 
Volume.p_physics.number of processes [4]: 0 
Volume.geometry.shape                [4]: cylinder 
Volume.geometry.center.x             [4]: 0.000000 
Volume.geometry.center.y             [4]: 0.000000 
Volume.geometry.center.z             [4]: 1.000000 
Volume.geometry.rotation_matrix[0]           [4]: [1.000000 0.000000 0.000000] 
Volume.geometry.rotation_matrix[1]           [4]: [0.000000 1.000000 0.000000] 
Volume.geometry.rotation_matrix[2]           [4]: [0.000000 0.000000 1.000000] 
Volume.geometry.geometry_parameters.cyl_radius [4]: 0.110000 
Volume.geometry.geometry_parameters.height [4]: 0.180000 
Volume.geometry.focus_data_array.elements[0].Aim             [4]: [0.000000 0.000000 1.000000] 

name of geometry    [5]: outer_window_Al 
component index     [5]: 11 
Volume.name         [5]: outer_window_Al 
Volume.p_physics.is_vacuum           [5]: 0 
Volume.p_physics.my_absorption       [5]: 0.347892 
Volume.p_physics.number of processes [5]: 2 
Volume.geometry.shape                [5]: cylinder 
Volume.geometry.center.x             [5]: 0.000000 
Volume.geometry.center.y             [5]: 0.000000 
Volume.geometry.center.z             [5]: 1.000000 
Volume.geometry.rotation_matrix[0]           [5]: [1.000000 0.000000 0.000000] 
Volume.geometry.rotation_matrix[1]           [5]: [0.000000 1.000000 0.000000] 
Volume.geometry.rotation_matrix[2]           [5]: [0.000000 0.000000 1.000000] 
Volume.geometry.geometry_parameters.cyl_radius [5]: 0.090000 
Volume.geometry.geometry_parameters.height [5]: 0.190000 
Volume.geometry.focus_data_array.elements[0].Aim             [5]: [0.000000 0.000000 1.000000] 

name of geometry    [6]: mask_outer 
component index     [6]: 12 
Volume.name         [6]: mask_outer 
Volume.geometry.shape                [6]: box 
Volume.geometry.center.x             [6]: 0.000000 
Volume.geometry.center.y             [6]: 0.000000 
Volume.geometry.center.z             [6]: 1.100000 
Volume.geometry.rotation_matrix[0]           [6]: [1.000000 0.000000 0.000000] 
Volume.geometry.rotation_matrix[1]           [6]: [0.000000 1.000000 0.000000] 
Volume.geometry.rotation_matrix[2]           [6]: [0.000000 0.000000 1.000000] 
Volume.geometry.focus_data_array.elements[0].Aim             [6]: [0.000000 0.000000 1.000000] 
---------------------------------------------------------------------
number_of_volumes = 8
number_of_masks = 2
number_of_masked_volumes = 3

 ---- Overview of the lists generated for each volume ---- 
List overview for surrounding vacuum
LIST: Children for Volume                  0 = [1,2,3,4,5,6,7]
LIST: Direct_children for Volume           0 = [4,5,6,7]
LIST: Intersect_check_list for Volume      0 = [1,2,4,7]
LIST: Mask_intersect_list for Volume       0 = [3,5,6]
LIST: Destinations_list for Volume         0 = []
LIST: Reduced_destinations_list for Volume 0 = []
LIST: Next_volume_list for Volume          0 = [3,5,6,1,2]
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 wall with cylinder shape made of Al
LIST: Children for Volume                  1 = []
LIST: Direct_children for Volume           1 = []
LIST: Intersect_check_list for Volume      1 = [2,4,7]
LIST: Mask_intersect_list for Volume       1 = [3,6]
LIST: Destinations_list for Volume         1 = [0,5]
LIST: Reduced_destinations_list for Volume 1 = [5]
LIST: Next_volume_list for Volume          1 = [0,5,3,6,2]
      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 wall_vacuum with cylinder shape made of Vacuum
LIST: Children for Volume                  2 = []
LIST: Direct_children for Volume           2 = []
LIST: Intersect_check_list for Volume      2 = [4,7]
LIST: Mask_intersect_list for Volume       2 = []
LIST: Destinations_list for Volume         2 = [0,1,3,5,6]
LIST: Reduced_destinations_list for Volume 2 = [1,3,5,6]
LIST: Next_volume_list for Volume          2 = [0,1,3,5,6]
      Is_vacuum for Volume                 2 = 1
      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 window with cylinder shape made of Vacuum
LIST: Children for Volume                  3 = [2]
LIST: Direct_children for Volume           3 = [2]
LIST: Intersect_check_list for Volume      3 = [2,4]
LIST: Mask_intersect_list for Volume       3 = []
LIST: Destinations_list for Volume         3 = [0,1]
LIST: Reduced_destinations_list for Volume 3 = [1]
LIST: Next_volume_list for Volume          3 = [0,1,2]
      Is_vacuum for Volume                 3 = 1
      is_mask_volume for Volume            3 = 0
      is_masked_volume for Volume          3 = 1
      is_exit_volume for Volume            3 = 0
LIST: mask_list for Volume                 3 = []
LIST: masked_by_list for Volume            3 = [4]
LIST: masked_by_mask_index_list for Volume 3 = [0]
      mask_mode for Volume                 3 = 1

List overview for mask with box shape made of Mask
LIST: Children for Volume                  4 = []
LIST: Direct_children for Volume           4 = []
LIST: Intersect_check_list for Volume      4 = []
LIST: Mask_intersect_list for Volume       4 = []
LIST: Destinations_list for Volume         4 = [0,1,2]
LIST: Reduced_destinations_list for Volume 4 = [1,2]
LIST: Next_volume_list for Volume          4 = [0,1,2]
      Is_vacuum for Volume                 4 = 0
      is_mask_volume for Volume            4 = 1
      is_masked_volume for Volume          4 = 0
      is_exit_volume for Volume            4 = 0
LIST: mask_list for Volume                 4 = [3]
LIST: masked_by_list for Volume            4 = []
LIST: masked_by_mask_index_list for Volume 4 = []
      mask_mode for Volume                 4 = 1

List overview for outer_window with cylinder shape made of Vacuum
LIST: Children for Volume                  5 = [1,2,3]
LIST: Direct_children for Volume           5 = [1,3]
LIST: Intersect_check_list for Volume      5 = [2,7]
LIST: Mask_intersect_list for Volume       5 = [6]
LIST: Destinations_list for Volume         5 = [0,1]
LIST: Reduced_destinations_list for Volume 5 = [1]
LIST: Next_volume_list for Volume          5 = [0,1,6,2]
      Is_vacuum for Volume                 5 = 1
      is_mask_volume for Volume            5 = 0
      is_masked_volume for Volume          5 = 1
      is_exit_volume for Volume            5 = 0
LIST: mask_list for Volume                 5 = []
LIST: masked_by_list for Volume            5 = [7]
LIST: masked_by_mask_index_list for Volume 5 = [1]
      mask_mode for Volume                 5 = 1

List overview for outer_window_Al with cylinder shape made of Al
LIST: Children for Volume                  6 = [2,3]
LIST: Direct_children for Volume           6 = [3]
LIST: Intersect_check_list for Volume      6 = [2,7]
LIST: Mask_intersect_list for Volume       6 = []
LIST: Destinations_list for Volume         6 = [0,1,5]
LIST: Reduced_destinations_list for Volume 6 = [1,5]
LIST: Next_volume_list for Volume          6 = [0,1,5,2]
      Is_vacuum for Volume                 6 = 0
      is_mask_volume for Volume            6 = 0
      is_masked_volume for Volume          6 = 1
      is_exit_volume for Volume            6 = 0
LIST: mask_list for Volume                 6 = []
LIST: masked_by_list for Volume            6 = [7]
LIST: masked_by_mask_index_list for Volume 6 = [1]
      mask_mode for Volume                 6 = 1

List overview for mask_outer with box shape made of Mask
LIST: Children for Volume                  7 = []
LIST: Direct_children for Volume           7 = []
LIST: Intersect_check_list for Volume      7 = []
LIST: Mask_intersect_list for Volume       7 = []
LIST: Destinations_list for Volume         7 = [0,1,2]
LIST: Reduced_destinations_list for Volume 7 = [1,2]
LIST: Next_volume_list for Volume          7 = [0,1,2]
      Is_vacuum for Volume                 7 = 0
      is_mask_volume for Volume            7 = 1
      is_masked_volume for Volume          7 = 0
      is_exit_volume for Volume            7 = 0
LIST: mask_list for Volume                 7 = [5,6]
LIST: masked_by_list for Volume            7 = []
LIST: masked_by_mask_index_list for Volume 7 = []
      mask_mode for Volume                 7 = 1

Union_master component master initialized sucessfully
Detector: logger_space_zx_I=1141.64 logger_space_zx_ERR=3.91643 logger_space_zx_N=94844 "logger_zx.dat"
INFO: Placing instr file copy python_tutorial.instr in dataset /Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/data_folder/union_masks_4
loading system configuration
ms.make_sub_plot(data)
../_images/Union_tutorial_5_masks_18_0.png

Masks are flexible

Masks can be used to create many interesting shapes with few geometries. Below we create a octagon with rounded corners using just three geometries, two of these being masks. Using masks expands the space of possible geometries greatly, and in many cases can also be a performance advantage when they reduce the number of geometries needed to describe the desired geometry.

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

Al_inc = instrument.add_component("Al_inc", "Incoherent_process")
Al_inc.sigma = 0.0082
Al_inc.unit_cell_volume = 66.4

Al_pow = instrument.add_component("Al_pow", "Powder_process")
Al_pow.reflections = '"Al.laz"'

Al = instrument.add_component("Al", "Union_make_material")
Al.process_string = '"Al_inc,Al_pow"'
Al.my_absorption = 100*0.231/66.4 # barns [m^2 E-28]*Å^3 [m^3 E-30]=[m E-2], factor 100

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

src.xwidth = 0.2
src.yheight = 0.035
src.focus_aw = 0.01
src.focus_ah = 0.01

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

box = instrument.add_component("box", "Union_box")
box.set_AT([0,0,1], RELATIVE=src)
box.xwidth = 0.2
box.yheight = 0.1
box.zdepth = 0.2
box.material_string='"Al"' 
box.priority = 10

# Cut the corners by using an identical box rotated 45 deg around y
box_mask = instrument.add_component("box_mask", "Union_box")
box_mask.set_AT([0,0,0], RELATIVE=box)
box_mask.set_ROTATED([0,45,0], RELATIVE=box)
box_mask.xwidth = 0.2
box_mask.yheight = 0.11 # Have to increase yheight to avoid perfect overlap
box_mask.zdepth = 0.2
box_mask.mask_string='"box"' 
box_mask.priority = 50

# Round the corners with a cylinder mask
cyl_mask = instrument.add_component("cylinder_mask", "Union_cylinder")
cyl_mask.set_AT([0,0,0], RELATIVE=box)
cyl_mask.radius = 0.105
cyl_mask.yheight = 0.12
cyl_mask.mask_string='"box"' 
cyl_mask.priority = 51

logger_zx = instrument.add_component("logger_space_zx", "Union_logger_2D_space")
logger_zx.set_RELATIVE(box)
logger_zx.D_direction_1 = '"z"'
logger_zx.D1_min = -0.12
logger_zx.D1_max = 0.12
logger_zx.n1 = 300
logger_zx.D_direction_2 = '"x"'
logger_zx.D2_min = -0.12
logger_zx.D2_max = 0.12
logger_zx.n2 = 300
logger_zx.filename = '"logger_zx.dat"'

master = instrument.add_component("master", "Union_master")


instrument.show_diagram()
../_images/Union_tutorial_5_masks_20_0.png ../_images/Union_tutorial_5_masks_20_1.png
data = instrument.backengine()
INFO: Using directory: "/Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/python_tutorial_data_5"
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:12065:18: note: expanded from macro 'filename'
#define filename mcclogger_space_zx_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:12065:18: note: expanded from macro 'filename'
#define filename mcclogger_space_zx_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
                          ^~~~~
13 warnings generated.
INFO: ===
Opening input file '/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//data/Al.laz' (Table_Read_Offset)
Table from file 'Al.laz' (block 1) is 26 x 18 (x=1:8), constant step. interpolation: linear
  '# TITLE *Aluminum-Al-[FM3-M] Miller, H.P.jr.;DuMond, J.W.M.[1942] at 298 K; ...'
PowderN: Al_pow: Reading 26 rows from Al.laz
PowderN: Al_pow: Read 26 reflections from file 'Al.laz'
PowderN: Al_pow: Vc=66.4 [Angs] sigma_abs=0.924 [barn] sigma_inc=0.0328 [barn] reflections=Al.laz
---------------------------------------------------------------------
global_process_list.num_elements: 2
name of process [0]: Al_inc 
component index [0]: 1 
name of process [1]: Al_pow 
component index [1]: 2 
---------------------------------------------------------------------
global_material_list.num_elements: 1
name of material    [0]: Al 
component index     [0]: 3 
my_absoprtion       [0]: 0.347892 
number of processes [0]: 2 
---------------------------------------------------------------------
global_geometry_list.num_elements: 1

name of geometry    [0]: box 
component index     [0]: 5 
Volume.name         [0]: box 
Volume.p_physics.is_vacuum           [0]: 0 
Volume.p_physics.my_absorption       [0]: 0.347892 
Volume.p_physics.number of processes [0]: 2 
Volume.geometry.shape                [0]: box 
Volume.geometry.center.x             [0]: 0.000000 
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_mask 
component index     [1]: 6 
Volume.name         [1]: box_mask 
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]: [0.707107 0.000000 -0.707107] 
Volume.geometry.rotation_matrix[1]           [1]: [-0.000000 1.000000 0.000000] 
Volume.geometry.rotation_matrix[2]           [1]: [0.707107 -0.000000 0.707107] 
Volume.geometry.focus_data_array.elements[0].Aim             [1]: [0.000000 0.000000 1.000000] 

name of geometry    [2]: cylinder_mask 
component index     [2]: 7 
Volume.name         [2]: cylinder_mask 
Volume.geometry.shape                [2]: cylinder 
Volume.geometry.center.x             [2]: 0.000000 
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.geometry_parameters.cyl_radius [2]: 0.105000 
Volume.geometry.geometry_parameters.height [2]: 0.120000 
Volume.geometry.focus_data_array.elements[0].Aim             [2]: [0.000000 0.000000 1.000000] 
---------------------------------------------------------------------
number_of_volumes = 4
number_of_masks = 2
number_of_masked_volumes = 1

 ---- 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 = [2,3]
LIST: Mask_intersect_list for Volume       0 = [1]
LIST: Destinations_list for Volume         0 = []
LIST: Reduced_destinations_list for Volume 0 = []
LIST: Next_volume_list for Volume          0 = [1]
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 with box shape made of Al
LIST: Children for Volume                  1 = []
LIST: Direct_children for Volume           1 = []
LIST: Intersect_check_list for Volume      1 = [2,3]
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 = 1
      is_exit_volume for Volume            1 = 0
LIST: mask_list for Volume                 1 = []
LIST: masked_by_list for Volume            1 = [2,3]
LIST: masked_by_mask_index_list for Volume 1 = [0,1]
      mask_mode for Volume                 1 = 1

List overview for box_mask with box shape made of Mask
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 = 1
      is_masked_volume for Volume          2 = 0
      is_exit_volume for Volume            2 = 0
LIST: mask_list for Volume                 2 = [1]
LIST: masked_by_list for Volume            2 = []
LIST: masked_by_mask_index_list for Volume 2 = []
      mask_mode for Volume                 2 = 1

List overview for cylinder_mask with cylinder shape made of Mask
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 = 1
      is_masked_volume for Volume          3 = 0
      is_exit_volume for Volume            3 = 0
LIST: mask_list for Volume                 3 = [1]
LIST: masked_by_list for Volume            3 = []
LIST: masked_by_mask_index_list for Volume 3 = []
      mask_mode for Volume                 3 = 1

Union_master component master initialized sucessfully
Detector: logger_space_zx_I=3985.32 logger_space_zx_ERR=10.346 logger_space_zx_N=158912 "logger_zx.dat"
INFO: Placing instr file copy python_tutorial.instr in dataset /Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/python_tutorial_data_5
loading system configuration
ms.make_sub_plot(data)
../_images/Union_tutorial_5_masks_22_0.png