Instrument reader

When McStasScript performs a McStas simulation, a traditional instrument file is generated and used for the simulation. In that way a user can easily go from a McStasScript instrument description to a regular instrument file. McStasScript does contain an instrument reader that can attempt to do the reverse, read a regular instrument file and create the McStasScript object or even a file with the python code that would create such an object. The instrument reader contains the interface, but the system is not yet finished and can be somewhat unreliable.

The instrument reader is a good way to transfer a project to McStasScript, but may require fixing of a few issues created in the transfer process.

Create a reader object

The first step is to create a reader object with McStas_file, this requires just a path to the instrument file.

import mcstasscript as ms
instrument_reader = ms.McStas_file("data_example.instr")

Create instrument object

The McStas_file object contains a method called add_to_instr that can add the instrument information to an instrument object. Here a McStas_instr object is initialized, and then the information to the instrument file is added with the instrument reader object.

instrument = ms.McStas_instr("reader_test")
instrument_reader.add_to_instr(instrument)

instrument.show_parameters()
instrument.show_variables()
instrument.show_components()
double wavelength  = 1.2  // 
DECLARE VARIABLES 
type  variable name  array length  value  
----------------------------------------

source Source_simple AT (0, 0, 0)   ABSOLUTE       
sample PowderN       AT (0, 0, 5)   RELATIVE source
banana Monitor_nD    AT (0, 0, 0)   RELATIVE sample
events Monitor_nD    AT (0, 0, 0.1) RELATIVE sample
PSD    PSD_monitor   AT (0, 0, 0.1) RELATIVE sample

If the instrument file used is for McStas 3.X and uses the USERVARS feature, it will fail when being executed with McStas 2.X. McStasScript includes a method to move any USERVARS to declare, which may allow the instrument to run with a McStas 2.X backend.

instrument.move_user_vars_to_declare()

Create a python script file

It is also possible to get a script file from the McStas_file object. A name for the script needs to be provided. The force keyword can be used to overwrite the file.

instrument_reader.write_python_file("generated_python_script.py", force=True)

The generated file is loaded and displayed to show that the python script is of reasonable quality, but still has room for improvement.

with open("generated_python_script.py") as file:
    script = file.read()
print(script)
"""
This McStasScript file was generated from a
McStas instrument file. It is advised to check
the content to ensure it is as expected.
"""
from mcstasscript.interface import instr, plotter, functions

data_example = instr.McStas_instr("data_example_generated")
data_example.add_parameter("double", "wavelength", value=1.2)

source = data_example.add_component("source", "Source_simple")
source.yheight = 0.03
source.xwidth = 0.05
source.dist = 5
source.focus_xw = 0.015
source.focus_yh = 0.03
source.lambda0 = "wavelength"
source.dlambda = 0.1
source.set_AT(['0', '0', '0'], RELATIVE="ABSOLUTE")

sample = data_example.add_component("sample", "PowderN")
sample.reflections = "\"Na2Ca3Al2F14.laz\""
sample.radius = 0.015
sample.yheight = 0.03
sample.barns = 0
sample.set_AT(['0', '0', '5'], RELATIVE="source")

banana = data_example.add_component("banana", "Monitor_nD")
banana.xwidth = 1.5
banana.yheight = 0.4
banana.restore_neutron = 1
banana.options = "\"theta limits=[5 175] bins=250, banana\""
banana.filename = "\"banana.dat\""
banana.set_AT(['0', '0', '0'], RELATIVE="sample")

events = data_example.add_component("events", "Monitor_nD")
events.xwidth = 0.1
events.yheight = 0.1
events.restore_neutron = 1
events.options = "\"list all auto, x y z vx vy vz t\""
events.filename = "\"events.dat\""
events.set_AT(['0', '0', '0.1'], RELATIVE="sample")

PSD = data_example.add_component("PSD", "PSD_monitor")
PSD.nx = 100
PSD.ny = 100
PSD.filename = "\"psd.dat\""
PSD.xwidth = 0.045
PSD.yheight = 0.06
PSD.restore_neutron = 1
PSD.set_AT(['0', '0', '0.1'], RELATIVE="sample")