Advanced geometry using the Union components

The Union components allow the user to construct advanced geometry from simple shapes. Each available shape has their own component, here are the currently available geometry components.

  • Union_box

  • Union_sphere

  • Union_cylinder

  • Union_cone

They differ in their parameters describing the geometry, but are otherwise identical. In this notebook we will show how to construct hollow geometries with several layers, and that multiple scattering between these quickly result in complex behavior.

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

Setting up some standard materials

Before setting up the geometry, we need some material definition, here we set up aluminium and a sample powder.

Al_inc = instrument.add_component("Al_inc", "Incoherent_process")
Al_inc.sigma = 4*0.0082 # 4 atoms per unit cell
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*4*0.231/66.4 # barns [m^2 E-28]*Å^3 [m^3 E-30]=[m E-2]

Sample_inc = instrument.add_component("Sample_inc", "Incoherent_process")
Sample_inc.sigma = 4*3.4176
Sample_inc.unit_cell_volume = 1079.1

Sample_pow = instrument.add_component("Sample_pow", "Powder_process")
Sample_pow.reflections = '"Na2Ca3Al2F14.laz"'

Sample = instrument.add_component("Sample", "Union_make_material")
Sample.process_string = '"Sample_inc,Sample_pow"'
Sample.my_absorption = 100*4*2.9464/1079.1

Set up source

We will also need a source, and allow the wavelength to be tuned with a instrument parameter.

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

src.xwidth = 0.01
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

Describing the geometry of a simple cryostat

A cryostat is a complex geometry with several layers to consider. The way geometry is described in the Union components aims to make it easy to describe such systems. This is aciheved by allowing the simple geometries to overlap, and having a value called the priority to determine which is active in a given volume. If two geometries overlap, the overlapping region gets the physics from the geometry with the highest priority. In that way a cryostat model can be created by having a high priority for the sample in the center, and decreasing the priority as we move out.

The ray tracing algorithm can however not handle if two geometries overlap perfectly, even with a single side. This could be two boxes sharing a side.

Let us look at the parameters for a Union geometry component.

instrument.component_help("Union_cylinder")
 ___ Help Union_cylinder ____________________________________________________________
|optional parameter|required parameter|default value|user specified value|
material_string = 0 [] // material name of this volume, defined using 
                          Union_make_material 
priority [1] // priotiry of the volume (can not be the same as another volume) 
                A high priority is on top of low. 
radius [m] // Outer radius volume in (x,z) plane
yheight [m] // Cylinder height in (y) direction
visualize = 1.0 [1] // set to 0 if you wish to hide this geometry in mcdisplay
target_index = 0 [1] // Relative index of component to focus at, e.g. next is +1
target_x = 0.0 [m]
target_y = 0.0 [m] // Position of target to focus at
target_z = 0.0 [m]
focus_aw = 0.0 [deg] // horiz. angular dimension of a rectangular area
focus_ah = 0.0 [deg] // vert. angular dimension of a rectangular area
focus_xw = 0.0 [m] // horiz. dimension of a rectangular area
focus_xh = 0.0 [m] // vert. dimension of a rectangular area
focus_r = 0.0 [m] // focusing on circle with this radius
p_interact = 0.0 [1] // probability to interact with this geometry [0-1]
mask_string = 0 [] // Comma seperated list of geometry names which this 
                      geometry should mask 
mask_setting = 0 [] // "All" or "Any", should the masked volume be simulated 
                       when the ray is in just one mask, or all. 
number_of_activations = 1.0 [1] // Number of subsequent Union_master components 
                                   that will simulate this geometry 
-------------------------------------------------------------------------------------

The geometry components have many parameters due to their flexibility, but only a few are needed for basic use.

  • material_string : string for selecting an available material

  • priority : number, in case of overlap the geometry with highest priority decides the material properties

  • geometrical parameters : Here radius and yheight

In addition there is a focusing system where scattering of physical processes that support this can be forced to a certain direction, this is controlled with these parameters, but are rarely used:

  • target_index : relative component index of target

  • target_x : if target_index not set, relative x coordinate of target

  • target_y : if target_index not set, relative y coordinate of target

  • target_z : if target_index not set, relative z coordinate of target

  • focus_aw : angular width of focusing cone (either specify angular, box or circular)

  • focus_ah : angular height of focusing cone

  • focus_xw : spatial width of focusing cone (box type focusing)

  • focus_xh : spatial height of focusing

  • focus_r : spatial radius of focusing cone (circular)

Finally there is p_interact, which is used for controlling Monte Carlo sampling frequency of the geometry, as it controls the probability for scattering occurring for any path before or after scattering.

The remaining parameters including masks and number_of_activations are for advanced rules which will be described in a later tutorial.

First geometry, a sample in a container

We have defined the following materials that are available to us:

  • Al

  • Sample

Lets start by building a simple powder container with a lid.

sample_geometry = instrument.add_component("sample_geometry", "Union_cylinder")
sample_geometry.yheight = 0.03
sample_geometry.radius = 0.0075
sample_geometry.material_string='"Sample"' 
sample_geometry.priority = 100
sample_geometry.set_AT([0,0,1], RELATIVE=src)

container = instrument.add_component("sample_container", "Union_cylinder")
container.set_RELATIVE(sample_geometry)
container.yheight = 0.03+0.003 # 1.5 mm top and button
container.radius = 0.0075 + 0.0015 # 1.5 mm sides of container
container.material_string='"Al"' 
container.priority = 99

container_lid = instrument.add_component("sample_container_lid", "Union_cylinder")
container_lid.set_AT([0, 0.0155, 0], RELATIVE=container)
container_lid.yheight = 0.004
container_lid.radius = 0.013
container_lid.material_string='"Al"' 
container_lid.priority = 98

Set up loggers to check what is going on

In order to view what geometry we have set up, we set up three loggers that view the scattering projected onto three different planes. These record the spatail distribution of scattering events.

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

logger_zy = instrument.add_component("logger_space_zy", "Union_logger_2D_space")
logger_zy.set_RELATIVE(sample_geometry)
logger_zy.D_direction_1 = '"z"'
logger_zy.D1_min = -0.02
logger_zy.D1_max = 0.02
logger_zy.n1 = 300
logger_zy.D_direction_2 = '"y"'
logger_zy.D2_min = -0.02
logger_zy.D2_max = 0.02
logger_zy.n2 = 300
logger_zy.filename = '"logger_zy.dat"'

logger_xy = instrument.add_component("logger_space_xy", "Union_logger_2D_space")
logger_xy.set_RELATIVE(sample_geometry)
logger_xy.D_direction_1 = '"x"'
logger_xy.D1_min = -0.02
logger_xy.D1_max = 0.02
logger_xy.n1 = 300
logger_xy.D_direction_2 = '"y"'
logger_xy.D2_min = -0.02
logger_xy.D2_max = 0.02
logger_xy.n2 = 300
logger_xy.filename = '"logger_xy.dat"'

Add master component

We need to remember to add a master component to actually perform the simulation.

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

Add banana monitor

We are also interested in viewing some scattering data, here we add a banana monitor using the Monitor_nD component.

banana = instrument.add_component("banana", "Monitor_nD", RELATIVE=sample_geometry)
banana.xwidth = 1.5
banana.yheight = 0.4
banana.restore_neutron = 1
banana.options = '"theta limits=[5 175] bins=250, banana"'

Run simulation

Now we need to run the simulation to view the geometry we have built.

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

data = instrument.backengine()
Instrument settings:
  ncount:           3.00e+06
  output_path:      data_folder/union_geometry
  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_geometry_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:14851: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:14851: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: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
  sprintf(this_storage.Detector_2D.Filename,filename);
                                            ^~~~~~~~
./python_tutorial.c:15094:18: note: expanded from macro 'filename'
#define filename mcclogger_space_zy_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:15094:18: note: expanded from macro 'filename'
#define filename mcclogger_space_zy_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: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
  sprintf(this_storage.Detector_2D.Filename,filename);
                                            ^~~~~~~~
./python_tutorial.c:15337:18: note: expanded from macro 'filename'
#define filename mcclogger_space_xy_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:15337:18: note: expanded from macro 'filename'
#define filename mcclogger_space_xy_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
                          ^~~~~
15 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
Opening input file '/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//data/Na2Ca3Al2F14.laz' (Table_Read_Offset)
Table from file 'Na2Ca3Al2F14.laz' (block 1) is 841 x 18 (x=1:20), constant step. interpolation: linear
  '# TITLE *-Na2Ca3Al2F14-[I213] Courbion, G.;Ferey, G.[1988] Standard NAC cal ...'
PowderN: Sample_pow: Reading 841 rows from Na2Ca3Al2F14.laz
PowderN: Sample_pow: Read 841 reflections from file 'Na2Ca3Al2F14.laz'
PowderN: Sample_pow: Vc=1079.1 [Angs] sigma_abs=11.7856 [barn] sigma_inc=13.6704 [barn] reflections=Na2Ca3Al2F14.laz
---------------------------------------------------------------------
global_process_list.num_elements: 4
name of process [0]: Al_inc 
component index [0]: 1 
name of process [1]: Al_pow 
component index [1]: 2 
name of process [2]: Sample_inc 
component index [2]: 4 
name of process [3]: Sample_pow 
component index [3]: 5 
---------------------------------------------------------------------
global_material_list.num_elements: 2
name of material    [0]: Al 
component index     [0]: 3 
my_absoprtion       [0]: 1.391570 
number of processes [0]: 2 
name of material    [1]: Sample 
component index     [1]: 6 
my_absoprtion       [1]: 1.092170 
number of processes [1]: 2 
---------------------------------------------------------------------
global_geometry_list.num_elements: 2

name of geometry    [0]: sample_geometry 
component index     [0]: 8 
Volume.name         [0]: sample_geometry 
Volume.p_physics.is_vacuum           [0]: 0 
Volume.p_physics.my_absorption       [0]: 1.092170 
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.007500 
Volume.geometry.geometry_parameters.height [0]: 0.030000 
Volume.geometry.focus_data_array.elements[0].Aim             [0]: [0.000000 0.000000 1.000000] 

name of geometry    [1]: sample_container 
component index     [1]: 9 
Volume.name         [1]: sample_container 
Volume.p_physics.is_vacuum           [1]: 0 
Volume.p_physics.my_absorption       [1]: 1.391570 
Volume.p_physics.number of processes [1]: 2 
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.009000 
Volume.geometry.geometry_parameters.height [1]: 0.033000 
Volume.geometry.focus_data_array.elements[0].Aim             [1]: [0.000000 0.000000 1.000000] 

name of geometry    [2]: sample_container_lid 
component index     [2]: 10 
Volume.name         [2]: sample_container_lid 
Volume.p_physics.is_vacuum           [2]: 0 
Volume.p_physics.my_absorption       [2]: 1.391570 
Volume.p_physics.number of processes [2]: 2 
Volume.geometry.shape                [2]: cylinder 
Volume.geometry.center.x             [2]: 0.000000 
Volume.geometry.center.y             [2]: 0.015500 
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.013000 
Volume.geometry.geometry_parameters.height [2]: 0.004000 
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 = [2,3]
LIST: Intersect_check_list for Volume      0 = [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 = [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 sample_geometry with cylinder shape made of Sample
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 = [2,3]
LIST: Reduced_destinations_list for Volume 1 = [2,3]
LIST: Next_volume_list for Volume          1 = [2,3]
      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 sample_container with cylinder shape made of Al
LIST: Children for Volume                  2 = [1]
LIST: Direct_children for Volume           2 = [1]
LIST: Intersect_check_list for Volume      2 = [1]
LIST: Mask_intersect_list for Volume       2 = []
LIST: Destinations_list for Volume         2 = [0,3]
LIST: Reduced_destinations_list for Volume 2 = [3]
LIST: Next_volume_list for Volume          2 = [0,3,1]
      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 sample_container_lid with cylinder shape made of Al
LIST: Children for Volume                  3 = []
LIST: Direct_children for Volume           3 = []
LIST: Intersect_check_list for Volume      3 = [2]
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,2]
      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_zx_I=17695.4 logger_space_zx_ERR=32.5854 logger_space_zx_N=949569 "logger_zx.dat"
Detector: logger_space_zy_I=17695.4 logger_space_zy_ERR=32.5854 logger_space_zy_N=949569 "logger_zy.dat"
Detector: logger_space_xy_I=17695.4 logger_space_xy_ERR=32.5854 logger_space_xy_N=949569 "logger_xy.dat"
Detector: banana_I=1969.4 banana_ERR=14.8549 banana_N=108504 "banana_1682427726.th"
INFO: Placing instr file copy python_tutorial.instr in dataset /Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/data_folder/union_geometry_1
loading system configuration

Plotting the data

Due to the large differences between the scattered intensity from parts in the direct beam and outside, we use a logarithmic axis to display scattered intensity. We limit it to 4 orders of magnitude below the maximum intensity, otherwise a single very low intensity event can draw the intensity axis out to a large interval making it difficult to see the important nuances.

ms.name_plot_options("logger_space_zx", data, log=True, orders_of_mag=4)
ms.name_plot_options("logger_space_zy", data, log=True, orders_of_mag=4)
ms.name_plot_options("logger_space_xy", data, log=True, orders_of_mag=4)
ms.make_sub_plot(data)
../_images/Union_tutorial_2_geometry_21_0.png

Interpretation of results

The beam is narrower than the sample, but taller than the can, so some parts of the sample powder are not directly illuminated, and can thus be seen as a intensity area especially on the zx logger image. The aluminum scatters less, and so lower intensity still.

Adding a cryostat around the sample can

We can add a crude model of a cryostat around our sample can by adding more Union geometry components. They have to be before the Union_master in the McStas instrument file, so we use the keyword argument before in the add_component method to specify this when adding the components.

We also need to designate areas as empty, this is done using the default material Vacuum which has no absorption or scattering processes. In this way we can create several layers by decreasing the priority when going out.

inner_wall = instrument.add_component("cryostat_wall", "Union_cylinder",
                                      before="master")
inner_wall.set_AT([0,0,0], RELATIVE=sample_geometry)
inner_wall.yheight = 0.12
inner_wall.radius = 0.03
inner_wall.material_string='"Al"' 
inner_wall.priority = 80

inner_wall_vac = instrument.add_component("cryostat_wall_vacuum", "Union_cylinder",
                                          before="master")
inner_wall_vac.set_AT([0,0,0], RELATIVE=sample_geometry)
inner_wall_vac.yheight = 0.12 - 0.008
inner_wall_vac.radius = 0.03 - 0.002
inner_wall_vac.material_string='"Vacuum"' 
inner_wall_vac.priority = 81

outer_wall = instrument.add_component("outer_cryostat_wall", "Union_cylinder",
                                      before="master")
outer_wall.set_AT([0,0,0], RELATIVE=sample_geometry)
outer_wall.yheight = 0.15
outer_wall.radius = 0.1
outer_wall.material_string='"Al"' 
outer_wall.priority = 60

outer_wall_vac = instrument.add_component("outer_cryostat_wall_vacuum", "Union_cylinder",
                                          before="master")
outer_wall_vac.set_AT([0,0,0], RELATIVE=sample_geometry)
outer_wall_vac.yheight = 0.15 - 0.01
outer_wall_vac.radius = 0.1 - 0.003
outer_wall_vac.material_string='"Vacuum"' 
outer_wall_vac.priority = 61

Adjusting the logger view to see the larger cryostat area

The loggers were only viewing a small area around the sample can, but this can be expanded as we still have access to the component objects.

logger_zx.set_parameters(D1_min=-0.12, D1_max=0.12, D2_min=-0.12, D2_max=0.12)
logger_zy.set_parameters(D1_min=-0.12, D1_max=0.12, D2_min=-0.12, D2_max=0.12)
logger_xy.set_parameters(D1_min=-0.12, D1_max=0.12, D2_min=-0.12, D2_max=0.12)

Viewing the instrument

The instrument can be viewed with the show_instrument method. The mock cryostat and detector can be seen in a 3D view.

instrument.show_instrument()

Run the updated instrument file

Run the simulation with the added cryostat, since no parameters or settings are changed it is enough to just call the backengine function and grab the new data.

data_cryo = instrument.backengine()
INFO: Using directory: "/Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/data_folder/union_geometry_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:15483: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:15483: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: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
  sprintf(this_storage.Detector_2D.Filename,filename);
                                            ^~~~~~~~
./python_tutorial.c:15726:18: note: expanded from macro 'filename'
#define filename mcclogger_space_zy_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:15726:18: note: expanded from macro 'filename'
#define filename mcclogger_space_zy_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: warning: format string is not a string literal (potentially insecure) [-Wformat-security]
  sprintf(this_storage.Detector_2D.Filename,filename);
                                            ^~~~~~~~
./python_tutorial.c:15969:18: note: expanded from macro 'filename'
#define filename mcclogger_space_xy_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:15969:18: note: expanded from macro 'filename'
#define filename mcclogger_space_xy_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
                          ^~~~~
15 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
Opening input file '/Applications/McStas-2.7.1.app/Contents/Resources/mcstas/2.7.1//data/Na2Ca3Al2F14.laz' (Table_Read_Offset)
Table from file 'Na2Ca3Al2F14.laz' (block 1) is 841 x 18 (x=1:20), constant step. interpolation: linear
  '# TITLE *-Na2Ca3Al2F14-[I213] Courbion, G.;Ferey, G.[1988] Standard NAC cal ...'
PowderN: Sample_pow: Reading 841 rows from Na2Ca3Al2F14.laz
PowderN: Sample_pow: Read 841 reflections from file 'Na2Ca3Al2F14.laz'
PowderN: Sample_pow: Vc=1079.1 [Angs] sigma_abs=11.7856 [barn] sigma_inc=13.6704 [barn] reflections=Na2Ca3Al2F14.laz
---------------------------------------------------------------------
global_process_list.num_elements: 4
name of process [0]: Al_inc 
component index [0]: 1 
name of process [1]: Al_pow 
component index [1]: 2 
name of process [2]: Sample_inc 
component index [2]: 4 
name of process [3]: Sample_pow 
component index [3]: 5 
---------------------------------------------------------------------
global_material_list.num_elements: 2
name of material    [0]: Al 
component index     [0]: 3 
my_absoprtion       [0]: 1.391570 
number of processes [0]: 2 
name of material    [1]: Sample 
component index     [1]: 6 
my_absoprtion       [1]: 1.092170 
number of processes [1]: 2 
---------------------------------------------------------------------
global_geometry_list.num_elements: 2

name of geometry    [0]: sample_geometry 
component index     [0]: 8 
Volume.name         [0]: sample_geometry 
Volume.p_physics.is_vacuum           [0]: 0 
Volume.p_physics.my_absorption       [0]: 1.092170 
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.007500 
Volume.geometry.geometry_parameters.height [0]: 0.030000 
Volume.geometry.focus_data_array.elements[0].Aim             [0]: [0.000000 0.000000 1.000000] 

name of geometry    [1]: sample_container 
component index     [1]: 9 
Volume.name         [1]: sample_container 
Volume.p_physics.is_vacuum           [1]: 0 
Volume.p_physics.my_absorption       [1]: 1.391570 
Volume.p_physics.number of processes [1]: 2 
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.009000 
Volume.geometry.geometry_parameters.height [1]: 0.033000 
Volume.geometry.focus_data_array.elements[0].Aim             [1]: [0.000000 0.000000 1.000000] 

name of geometry    [2]: sample_container_lid 
component index     [2]: 10 
Volume.name         [2]: sample_container_lid 
Volume.p_physics.is_vacuum           [2]: 0 
Volume.p_physics.my_absorption       [2]: 1.391570 
Volume.p_physics.number of processes [2]: 2 
Volume.geometry.shape                [2]: cylinder 
Volume.geometry.center.x             [2]: 0.000000 
Volume.geometry.center.y             [2]: 0.015500 
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.013000 
Volume.geometry.geometry_parameters.height [2]: 0.004000 
Volume.geometry.focus_data_array.elements[0].Aim             [2]: [0.000000 0.000000 1.000000] 

name of geometry    [3]: cryostat_wall 
component index     [3]: 14 
Volume.name         [3]: cryostat_wall 
Volume.p_physics.is_vacuum           [3]: 0 
Volume.p_physics.my_absorption       [3]: 1.391570 
Volume.p_physics.number of processes [3]: 2 
Volume.geometry.shape                [3]: cylinder 
Volume.geometry.center.x             [3]: 0.000000 
Volume.geometry.center.y             [3]: 0.000000 
Volume.geometry.center.z             [3]: 1.000000 
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.geometry_parameters.cyl_radius [3]: 0.030000 
Volume.geometry.geometry_parameters.height [3]: 0.120000 
Volume.geometry.focus_data_array.elements[0].Aim             [3]: [0.000000 0.000000 1.000000] 

name of geometry    [4]: cryostat_wall_vacuum 
component index     [4]: 15 
Volume.name         [4]: cryostat_wall_vacuum 
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.028000 
Volume.geometry.geometry_parameters.height [4]: 0.112000 
Volume.geometry.focus_data_array.elements[0].Aim             [4]: [0.000000 0.000000 1.000000] 

name of geometry    [5]: outer_cryostat_wall 
component index     [5]: 16 
Volume.name         [5]: outer_cryostat_wall 
Volume.p_physics.is_vacuum           [5]: 0 
Volume.p_physics.my_absorption       [5]: 1.391570 
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.100000 
Volume.geometry.geometry_parameters.height [5]: 0.150000 
Volume.geometry.focus_data_array.elements[0].Aim             [5]: [0.000000 0.000000 1.000000] 

name of geometry    [6]: outer_cryostat_wall_vacuum 
component index     [6]: 17 
Volume.name         [6]: outer_cryostat_wall_vacuum 
Volume.p_physics.is_vacuum           [6]: 1 
Volume.p_physics.my_absorption       [6]: 0.000000 
Volume.p_physics.number of processes [6]: 0 
Volume.geometry.shape                [6]: cylinder 
Volume.geometry.center.x             [6]: 0.000000 
Volume.geometry.center.y             [6]: 0.000000 
Volume.geometry.center.z             [6]: 1.000000 
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.geometry_parameters.cyl_radius [6]: 0.097000 
Volume.geometry.geometry_parameters.height [6]: 0.140000 
Volume.geometry.focus_data_array.elements[0].Aim             [6]: [0.000000 0.000000 1.000000] 
---------------------------------------------------------------------
number_of_volumes = 8
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,4,5,6,7]
LIST: Direct_children for Volume           0 = [6]
LIST: Intersect_check_list for Volume      0 = [6]
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 = [6]
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 sample_geometry with cylinder shape made of Sample
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 = [2,3]
LIST: Reduced_destinations_list for Volume 1 = [2,3]
LIST: Next_volume_list for Volume          1 = [2,3]
      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 sample_container with cylinder shape made of Al
LIST: Children for Volume                  2 = [1]
LIST: Direct_children for Volume           2 = [1]
LIST: Intersect_check_list for Volume      2 = [1]
LIST: Mask_intersect_list for Volume       2 = []
LIST: Destinations_list for Volume         2 = [3,5]
LIST: Reduced_destinations_list for Volume 2 = [5]
LIST: Next_volume_list for Volume          2 = [3,5,1]
      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 sample_container_lid with cylinder shape made of Al
LIST: Children for Volume                  3 = []
LIST: Direct_children for Volume           3 = []
LIST: Intersect_check_list for Volume      3 = [2]
LIST: Mask_intersect_list for Volume       3 = []
LIST: Destinations_list for Volume         3 = [5]
LIST: Reduced_destinations_list for Volume 3 = [5]
LIST: Next_volume_list for Volume          3 = [5,2]
      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

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

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

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

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

Union_master component master initialized sucessfully
Detector: logger_space_zx_I=20805.6 logger_space_zx_ERR=31.186 logger_space_zx_N=1.17927e+06 "logger_zx.dat"
Detector: logger_space_zy_I=20805.6 logger_space_zy_ERR=31.186 logger_space_zy_N=1.17927e+06 "logger_zy.dat"
Detector: logger_space_xy_I=20805.6 logger_space_xy_ERR=31.186 logger_space_xy_N=1.17927e+06 "logger_xy.dat"
Detector: banana_I=1904.67 banana_ERR=9.58372 banana_N=113140 "banana_1682427746.th"
INFO: Placing instr file copy python_tutorial.instr in dataset /Users/madsbertelsen/PaNOSC/McStasScript/github/McStasScript/docs/source/tutorial/data_folder/union_geometry_2
loading system configuration

Plot the data from the new simulation

Here we increase the orders of magnitude of intensity plotted on the log plots. Try to play with these values to see how it changes the plots.

ms.make_sub_plot(data_cryo, log=[True, True, True, False], orders_of_mag=5)
../_images/Union_tutorial_2_geometry_32_0.png

Interpreting the data

The different layers of the cryostat both result in scattering from the aluminium the beam has to move through, but also some increase intensity where it illuminated by scattering from the sample.

Comparing situation with and without cryostat

It could be interesting to see what difference adding the cryostat did to the measured signal in the banana monitor, here we extract the numpy arrays and plot them manually with matplotlib for at direct comparison. Ensure you run the two simulations with the same wavelength in order for a comparison to be meaningful.

banana_can = ms.name_search("banana", data)
banana_cryo = ms.name_search("banana", data_cryo)

import copy
import numpy as np
banana_diff = copy.deepcopy(banana_cryo)
banana_diff.Intensity = banana_cryo.Intensity - banana_can.Intensity
banana_diff.Error = np.sqrt(banana_cryo.Error**2 + banana_can.Error**2)

import matplotlib.pyplot as plt
plt.figure(figsize=(14,6))
plt.plot(banana_can.xaxis, banana_can.Intensity, "r",
         banana_cryo.xaxis, banana_cryo.Intensity, "b",
         banana_diff.xaxis, banana_diff.Intensity-10.0, "k")
plt.xlabel("2Theta [deg]")
plt.ylabel("Intensity [n/s]")
l = plt.legend(["Sample in can", "Sample in can in cryostat", "Difference displaced to -10"])
../_images/Union_tutorial_2_geometry_34_0.png