instrument - Reflectivity instrument definition

Monochromatic Instrument representation for scanning reflectometers.
Pulsed Instrument representation for pulsed reflectometers.

Reflectometry instrument definitions.

An instrument definition contains all the information necessary to compute the resolution for a measurement. See resolution for details.

This module is intended to help define new instrument loaders

Scanning Reflectometers

refl1d.instrument (this module) defines two instrument types: Monochromatic and Pulsed. These represent generic scanning and time of flight instruments, respectively.

To perform a simulation or load a data set, a measurement geometry must be defined. In the following example, we set up the geometry for a pretend instrument SP:2. The complete geometry needs to include information to calculate wavelength resolution (wavelength and wavelength dispersion) as well as angular resolution (slit distances and openings, and perhaps sample size and sample warp). In this case, we are using a scanning monochromatic instrument with slits of 0.1 mm below 0.5° and opening slits above 0.5° starting at 0.2 mm. The monochromatic instrument assumes a fixed \(\Delta \theta / \theta\) while opening.

>>> from refl1d.names import *
>>> geometry = Monochromatic(instrument="SP:2", radiation="neutron",
...    wavelength=5.0042, dLoL=0.009, d_s1=230+1856, d_s2=230,
...    Tlo=0.5, slits_at_Tlo=0.2, slits_below=0.1)

This instrument can be used to a data file, or generate a measurement probe for use in modeling or to read in a previously measured data set or generate a probe for simulation:

>>> from numpy import linspace, loadtxt
>>> datafile = sample_data('10ndt001.refl')
>>> Q,R,dR = loadtxt(datafile).T
>>> probe = geometry.probe(Q=Q, data=(R,dR))
>>> simulation = geometry.probe(T=linspace(0,5,51))

All instrument parameters can be specified when constructing the probe, replacing the defaults that are associated with the instrument. For example, to include sample broadening effects in the resolution:

>>> probe2 = geometry.probe(Q=Q, data=(R,dR), sample_broadening=0.1,
...    name="probe2")

For magnetic systems a polarized beam probe is needed:

>>> magnetic_probe = geometry.magnetic_probe(T=numpy.linspace(0,5,100),)

The string representation of the geometry prints a multi-line description of the default instrument configuration:

>>> print(geometry)
== Instrument SP:2 ==
radiation = neutron at 5.0042 Angstrom with 0.9% resolution
slit distances = 2086 mm and 230 mm
fixed region below 0.5 and above 90 degrees
slit openings at Tlo are 0.2 mm
sample width = 1e+10 mm
sample broadening = 0 degrees

Predefined Instruments

Specific instruments can be defined for each facility. This saves the users having to remember details of the instrument geometry.

For example, the above SP:2 instrument could be defined as follows:

>>> class SP2(Monochromatic):
...    instrument = "SP:2"
...    radiation = "neutron"
...    wavelength = 5.0042   # Angstroms
...    dLoL = 0.009          # FWHM
...    d_s1 = 230.0 + 1856.0 # mm
...    d_s2 = 230.0          # mm
...    def load(self, filename, **kw):
...        Q,R,dR = loadtxt(datafile).T
...        probe = self.probe(Q=Q, data=(R,dR), **kw)
...        return probe

This definition can then be used to define the measurement geometry. We have added a load method which knows about the facility file format (in this case, three column ASCII data Q, R, dR) so that we can load a datafile in a couple of lines of code:

>>> geometry = SP2(Tlo=0.5, slits_at_Tlo=0.2, slits_below=0.1)
>>> probe3 = geometry.load(datafile)

The defaults() method prints the static components of the geometry:

>>> print(SP2.defaults())
== Instrument class SP:2 ==
radiation = neutron at 5.0042 Angstrom with 0.9% resolution
slit distances = 2086 mm and 230 mm

GUI Usage

Graphical user interfaces follow different usage patterns from scripts. Here the emphasis will be on selecting a data set to process, displaying its default metadata and allowing the user to override it.

File loading should follow the pattern established in reflectometry reduction, with an extension registry and a fallback scheme whereby files can be checked in a predefined order. If the file cannot be loaded, then the next loader is tried. This should be extended with the concept of a magic signature such as those used by graphics and sound file applications: read the first block and run it through the signature check before trying to load it. For unrecognized extensions, all loaders can be tried.

The file loader should return an instrument instance with metadata initialized from the file header. This metadata can be displayed to the user along with a plot of the data and the resolution. When metadata values are changed, the resolution can be recomputed and the display updated. When the data set is accepted, the final resolution calculation can be performed.

class refl1d.instrument.Monochromatic(**kw)[source]

Bases: object

Instrument representation for scanning reflectometers.

Parameters:
instrument : string

name of the instrument

radiation : string | xray or neutron

source radiation type

d_s1, d_s2 : float | mm

distance from sample to pre-sample slits 1 and 2; post-sample slits are ignored

wavelength : float | Å

wavelength of the instrument

dLoL : float

constant relative wavelength dispersion; wavelength range and dispersion together determine the bins

slits : float OR (float,float) | mm

fixed slits

slits_at_Tlo : float OR (float,float) | mm

slit 1 and slit 2 openings at Tlo; this can be a scalar if both slits are open by the same amount, otherwise it is a pair (s1,s2).

slits_at_Qlo : float OR (float,float) | mm

equivalent to slits_at_Tlo, for instruments that are controlled by Q rather than theta

Tlo, Thi : float | °

range of opening slits, or inf if slits are fixed.

Qlo, Qhi : float | Å-1

range of opening slits when instrument is controlled by Q.

slits_below, slits_above : float OR (float,float) | mm

slit 1 and slit 2 openings below Tlo and above Thi; again, these can be scalar if slit 1 and slit 2 are the same, otherwise they are each a pair (s1,s2). Below and above default to the values of the slits at Tlo and Thi respectively.

sample_width : float | mm

width of sample; at low angle with tiny samples, stray neutrons miss the sample and are not reflected onto the detector, so the sample itself acts as a slit, therefore the width of the sample may be needed to compute the resolution correctly

sample_broadening : float | ° FWHM

amount of angular divergence (+) or focusing (-) introduced by the sample; this is caused by sample warp, and may be read off of the rocking curve by subtracting (s1+s2)/2/(d_s1-d_s2) from the FWHM width of the rocking curve

Thi = 90
Tlo = 90
calc_dT(**kw)[source]

Compute the angular divergence for given slits and angles

Parameters:
T OR Q : [float] | ° OR Å-1

measurement angles

slits : float OR (float,float) | mm

total slit opening from edge to edge, not beam center to edge

d_s1, d_s2 : float | mm

distance from sample to slit 1 and slit 2

sample_width : float | mm

size of sample

sample_broadening : float | ° FWHM

resolution changes from sample warp

Returns:
dT : [float] | ° FWHM

angular divergence

sample_broadening can be estimated from W, the full width at half maximum of a rocking curve measured in degrees:

sample_broadening = W - degrees( 0.5*(s1+s2) / (d1-d2))
calc_slits(**kw)[source]

Determines slit openings from measurement pattern.

If slits are fixed simply return the same slits for every angle, otherwise use an opening range [Tlo,Thi] and the value of the slits at the start of the opening to define the slits. Slits below Tlo and above Thi can be specified separately.

T OR Q incident angle or Q Tlo, Thi angle range over which slits are opening slits_at_Tlo openings at the start of the range, or fixed opening slits_below, slits_above openings below and above the range

Use fixed_slits is available, otherwise use opening slits.

dLoL = None
d_s1 = None
d_s2 = None
classmethod defaults()[source]

Return default instrument properties as a printable string.

fixed_slits = None
instrument = 'monochromatic'
magnetic_probe(Aguide=270, shared_beam=True, H=0, **kw)[source]

Simulate a polarized measurement probe.

Returns a probe with Q, angle, wavelength and the associated uncertainties, but not any data.

Guide field angle Aguide can be specified, as well as keyword arguments for the geometry of the probe cross sections such as slits_at_Tlo, Tlo, Thi, slits_below, and slits_above to define the angular divergence.

probe(**kw)[source]

Return a probe for use in simulation.

Parameters:
Q : [float] | Å

Q values to be measured.

T : [float] | °

Angles to be measured.

Additional keyword parameters

Returns:
probe : Probe

Measurement probe with complete resolution information. The probe will not have any data.

If both Q and T are specified then Q takes precedents.

You can override instrument parameters using key=value. In particular, settings for slits_at_Tlo, Tlo, Thi, slits_below, and slits_above are used to define the angular divergence.

radiation = 'unknown'
resolution(**kw)[source]

Calculate resolution at each angle.

Return:
T, dT : [float] | °

Angles and angular divergence.

L, dL : [float] | Å

Wavelengths and wavelength dispersion.

sample_broadening = 0
sample_width = 10000000000.0
slits_above = None
slits_at_Tlo = None
slits_below = None
wavelength = None
class refl1d.instrument.Pulsed(**kw)[source]

Bases: object

Instrument representation for pulsed reflectometers.

Parameters:
instrument : string

name of the instrument

radiation : string | xray, neutron

source radiation type

TOF_range : (float, float)

usabe range of times for TOF data

T : float | °

sample angle

d_s1, d_s2 : float | mm

distance from sample to pre-sample slits 1 and 2; post-sample slits are ignored

wavelength : (float,float) | Å

wavelength range for the measurement

dLoL : float

constant relative wavelength dispersion; wavelength range and dispersion together determine the bins

slits : float OR (float,float) | mm

fixed slits

slits_at_Tlo : float OR (float,float) | mm

slit 1 and slit 2 openings at Tlo; this can be a scalar if both slits are open by the same amount, otherwise it is a pair (s1,s2).

Tlo, Thi : float | °

range of opening slits, or inf if slits are fixed.

slits_below, slits_above : float OR (float,float) | mm

slit 1 and slit 2 openings below Tlo and above Thi; again, these can be scalar if slit 1 and slit 2 are the same, otherwise they are each a pair (s1,s2). Below and above default to the values of the slits at Tlo and Thi respectively.

sample_width : float | mm

width of sample; at low angle with tiny samples, stray neutrons miss the sample and are not reflected onto the detector, so the sample itself acts as a slit, therefore the width of the sample may be needed to compute the resolution correctly

sample_broadening : float | ° FWHM

amount of angular divergence (+) or focusing (-) introduced by the sample; this is caused by sample warp, and may be read off of the rocking curve by subtracting 0.5*(s1+s2)/(d_s1-d_s2) from the FWHM width of the rocking curve

T = None
TOF_range = (0, inf)
Thi = 90
Tlo = 90
calc_dT(T, slits, **kw)[source]
calc_slits(**kw)[source]

Determines slit openings from measurement pattern.

If slits are fixed simply return the same slits for every angle, otherwise use an opening range [Tlo,Thi] and the value of the slits at the start of the opening to define the slits. Slits below Tlo and above Thi can be specified separately.

T incident angle Tlo, Thi angle range over which slits are opening slits_at_Tlo openings at the start of the range, or fixed opening slits_below, slits_above openings below and above the range

Use fixed_slits is available, otherwise use opening slits.

dLoL = None
d_s1 = None
d_s2 = None
classmethod defaults()[source]

Return default instrument properties as a printable string.

fixed_slits = None
instrument = 'pulsed'
magnetic_probe(Aguide=270, shared_beam=True, **kw)[source]

Simulate a polarized measurement probe.

Returns a probe with Q, angle, wavelength and the associated uncertainties, but not any data.

Guide field angle Aguide can be specified, as well as keyword arguments for the geometry of the probe cross sections such as slit settings slits and T to define the angular divergence and dLoL to define the wavelength resolution.

probe(**kw)[source]

Simulate a measurement probe.

Returns a probe with Q, angle, wavelength and the associated uncertainties, but not any data.

You can override instrument parameters using key=value. In particular, slit settings slits and T define the angular divergence and dLoL defines the wavelength resolution.

radiation = 'neutron'
resolution(L, dL, **kw)[source]

Return the resolution of the measurement. Needs T, L, dL specified as keywords.

sample_broadening = 0
sample_width = 10000000000.0
simulate(sample, uncertainty=1, **kw)[source]

Simulate a run with a particular sample.

Parameters:
sample : Stack

Reflectometry model

T : [float] | °

List of angles to be measured, such as [0.15,0.4,1,2].

slits : [float] or [(float,float)] | mm

Slit settings for each angle.

uncertainty = 1 : float or [float] | %

Incident intensity is set so that the median dR/R is equal to uncertainty, where R is the idealized reflectivity of the sample.

dLoL = 0.02: float

Wavelength resolution

normalize = True : boolean

Whether to normalize the intensities

theta_offset = 0 : float | °

Sample alignment error

background = 0 : float

Background counts per incident neutron (background is assumed to be independent of measurement geometry).

back_reflectivity = False : boolean

Whether beam travels through incident medium or through substrate.

back_absorption = 1 : float

Absorption factor for beam traveling through substrate. Only needed for back reflectivity measurements.

slits = None
slits_above = None
slits_at_Tlo = None
slits_below = None
wavelength = None