Skip to content

Commit

Permalink
Continue adapting amor to sciline
Browse files Browse the repository at this point in the history
  • Loading branch information
jokasimr committed Oct 19, 2023
1 parent b3426ad commit be891e0
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 62 deletions.
26 changes: 17 additions & 9 deletions docs/examples/amor.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,34 @@
"from essreflectometry.amor.load import load\n",
"from essreflectometry.amor.beamline import make_beamline\n",
"from essreflectometry.amor.conversions import specular_reflection\n",
"from essreflectometry.amor.resolution import add_resolutions, compute_resolution\n",
"from essreflectometry.amor.normalize import normalize_by_supermirror\n",
"from essreflectometry.amor.calibrations import supermirror_calibration\n",
"from essreflectometry.reflectometry.corrections import footprint_correction, normalize_by_counts\n",
"from essreflectometry.reflectometry.conversions import providers\n",
"from essreflectometry.reflectometry.types import (\n",
" ThetaBins, WavelengthBins, Sample, SampleRotation, Filename,\n",
" ThetaData, WavelengthData,\n",
" ThetaBins, WavelengthBins, Sample, Reference, Sample, SampleRotation, Filename,\n",
" ThetaData, WavelengthData, HistogrammedByQ, QDataWithResolutions, QData, QBins, NormalizedIOverQ\n",
")\n",
"\n",
"\n",
"\n",
"\n",
"pipeline = sciline.Pipeline(\n",
" [load, make_beamline, specular_reflection] + providers,\n",
" [load, make_beamline, specular_reflection, footprint_correction,\n",
" add_resolutions, compute_resolution, normalize_by_counts, supermirror_calibration, normalize_by_supermirror]\n",
" + providers,\n",
" params={\n",
" ThetaBins: sc.linspace(dim='theta', start=0, stop=np.pi/2, num=200, unit='rad'),\n",
" ThetaBins: sc.linspace(dim='theta', start=0, stop=np.pi/2, num=2, unit='rad'),\n",
" WavelengthBins: sc.array(dims=['wavelength'], values=[2.4, 16.0], unit='angstrom'),\n",
" QBins: sc.geomspace(dim='Q', start=0.008, stop=0.075, num=200, unit='1/angstrom'),\n",
"\n",
" SampleRotation[Sample]: sc.scalar(0.7989, unit='deg'),\n",
" Filename[Sample]: \"sample.nxs\",\n",
" SampleRotation[Reference]: sc.scalar(0.8389, unit='deg'),\n",
" Filename[Reference]: \"reference.nxs\",\n",
" }\n",
")\n",
"\n",
"pipeline.visualize(ThetaData[Sample])"
"pipeline.visualize(NormalizedIOverQ)"
]
},
{
Expand All @@ -41,7 +49,7 @@
"metadata": {},
"outputs": [],
"source": [
"pipeline.compute(WavelengthData[Sample])"
"pipeline.compute(HistogrammedByQ[QData[Reference]])"
]
},
{
Expand All @@ -50,7 +58,7 @@
"metadata": {},
"outputs": [],
"source": [
"(pipeline.compute(WavelengthData[Sample])\n",
"(pipeline.compute(WithResolution)\n",
" .bins.concat('detector_number').hist(wavelength=200)\n",
" .plot())"
]
Expand Down
29 changes: 16 additions & 13 deletions src/essreflectometry/amor/calibrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
# Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
import scipp as sc

from ..reflectometry import orso
# from ..reflectometry import orso
from ..reflectometry.types import CalibratedReference, HistogrammedByQ, QData, Reference


def supermirror_calibration(
data_array: sc.DataArray,
m_value: sc.Variable = None,
critical_edge: sc.Variable = None,
alpha: sc.Variable = None,
) -> sc.Variable:
data_array: HistogrammedByQ[QData[Reference]],
) -> CalibratedReference:
# TODO
m_value: sc.Variable = None
critical_edge: sc.Variable = None
alpha: sc.Variable = None
"""
Calibrate supermirror measurements
Expand Down Expand Up @@ -38,13 +40,14 @@ def supermirror_calibration(
alpha = sc.scalar(0.25 / 0.088, unit=sc.units.angstrom)
calibration = calibration_factor(data_array, m_value, critical_edge, alpha)
data_array_cal = data_array * calibration
try:
data_array_cal.attrs['orso'].value.reduction.corrections += [
'supermirror calibration'
]
except KeyError:
orso.not_found_warning()
return data_array_cal
# TODO
# try:
# data_array_cal.attrs['orso'].value.reduction.corrections += [
# 'supermirror calibration'
# ]
# except KeyError:
# orso.not_found_warning()
return CalibratedReference(data_array_cal)


def calibration_factor(
Expand Down
45 changes: 27 additions & 18 deletions src/essreflectometry/amor/normalize.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@
# Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
import scipp as sc

from ..reflectometry import orso
# from ..reflectometry import orso
from ..reflectometry.types import (
CalibratedReference,
HistogrammedByQ,
NormalizedData,
NormalizedIOverQ,
QDataWithResolutions,
)


def normalize_by_supermirror(
sample: sc.DataArray, supermirror: sc.DataArray
) -> sc.DataArray:
sample: NormalizedData[HistogrammedByQ[QDataWithResolutions]],
supermirror: NormalizedData[CalibratedReference],
) -> NormalizedIOverQ:
"""
Normalize the sample measurement by the (ideally calibrated) supermirror.
Expand All @@ -26,19 +34,20 @@ def normalize_by_supermirror(
"""
normalized = sample / supermirror
normalized.masks['no_reference_neutrons'] = (supermirror == sc.scalar(0)).data
try:
normalized.attrs['orso'] = sample.attrs['orso']
normalized.attrs['orso'].value.reduction.corrections = list(
set(
sample.attrs['orso'].value.reduction.corrections
+ supermirror.attrs['orso'].value.reduction.corrections
)
)
normalized.attrs[
'orso'
].value.data_source.measurement.reference = supermirror.attrs[
'orso'
].value.data_source.measurement.data_files
except KeyError:
orso.not_found_warning()
# TODO
# try:
# normalized.attrs['orso'] = sample.attrs['orso']
# normalized.attrs['orso'].value.reduction.corrections = list(
# set(
# sample.attrs['orso'].value.reduction.corrections
# + supermirror.attrs['orso'].value.reduction.corrections
# )
# )
# normalized.attrs[
# 'orso'
# ].value.data_source.measurement.reference = supermirror.attrs[
# 'orso'
# ].value.data_source.measurement.data_files
# except KeyError:
# orso.not_found_warning()
return normalized
36 changes: 36 additions & 0 deletions src/essreflectometry/amor/resolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,45 @@
# Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
import scipp as sc

from ..reflectometry.types import (
FootprintCorrected,
QData,
QDataWithResolutions,
Resolutions,
Sample,
)
from .tools import fwhm_to_std


def compute_resolution(da: FootprintCorrected[Sample]) -> Resolutions:
return Resolutions(
{
'wavelength_resolution': wavelength_resolution(
chopper_1_position=da.coords['source_chopper_1'].value['position'],
chopper_2_position=da.coords['source_chopper_2'].value['position'],
pixel_position=da.coords['position'],
),
'angular_resolution': angular_resolution(
pixel_position=da.coords['position'],
theta=da.bins.coords['theta'],
detector_spatial_resolution=da.coords['detector_spatial_resolution'],
),
'sample_size_resolution': sample_size_resolution(
pixel_position=da.coords['position'],
sample_size=da.coords['sample_size'],
),
}
)


def add_resolutions(
da: QData[Sample], resolutions: Resolutions
) -> QDataWithResolutions:
for coord, value in resolutions.items():
da.coords[coord] = value
return QDataWithResolutions(da)


def wavelength_resolution(
chopper_1_position: sc.Variable,
chopper_2_position: sc.Variable,
Expand Down
21 changes: 13 additions & 8 deletions src/essreflectometry/reflectometry/conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

# from . import orso
from .types import (
CorrectedQData,
FootprintCorrected,
HistogrammedByQ,
QBins,
QData,
Raw,
Run,
SpecularReflectionCoordTransformGraph,
Expand Down Expand Up @@ -213,8 +218,10 @@ def wavelength_to_theta(


def theta_to_q(
data_array: sc.DataArray, q_edges: sc.Variable = None, graph: dict = None
) -> sc.DataArray:
data_array: FootprintCorrected[Run],
q_edges: QBins,
graph: SpecularReflectionCoordTransformGraph,
) -> QData[Run]:
"""
Convert from theta to Q and if necessary bin in Q.
Expand All @@ -233,14 +240,12 @@ def theta_to_q(
:
New data array with theta coordinate.
"""
graph = graph if graph is not None else specular_reflection()
data_array_q = data_array.transform_coords(["Q"], graph=graph)
if q_edges is not None:
data_array_q = data_array_q.bin({q_edges.dim: q_edges})
return data_array_q
data_array_q = data_array_q.bin({q_edges.dim: q_edges})
return QData[Run](data_array_q)


def sum_bins(data_array: sc.DataArray):
def sum_bins(data_array: CorrectedQData) -> HistogrammedByQ[CorrectedQData]:
"""
Sum the event bins and propagate the maximum resolution, where available.
Expand All @@ -262,4 +267,4 @@ def sum_bins(data_array: sc.DataArray):
return data_array_summed


providers = [tof_to_wavelength, wavelength_to_theta]
providers = [tof_to_wavelength, wavelength_to_theta, theta_to_q, sum_bins]
19 changes: 10 additions & 9 deletions src/essreflectometry/reflectometry/corrections.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

from ..amor.tools import fwhm_to_std
from . import orso
from .types import FootprintCorrected, Normalizable, NormalizedData, Run, ThetaData


def footprint_correction(data_array: sc.DataArray) -> sc.DataArray:
def footprint_correction(data_array: ThetaData[Run]) -> FootprintCorrected[Run]:
"""
Perform the footprint correction on the data array that has a :code:`beam_size` and
binned :code:`theta` values.
Expand All @@ -29,16 +30,16 @@ def footprint_correction(data_array: sc.DataArray) -> sc.DataArray:
fwhm_to_std(data_array.coords['sample_size'] / size_of_beam_on_sample)
)
data_array_fp_correction = data_array / footprint_scale.squeeze()
try:
data_array_fp_correction.attrs['orso'].value.reduction.corrections += [
'footprint correction'
]
except KeyError:
orso.not_found_warning()
return data_array_fp_correction
# try:
# data_array_fp_correction.attrs['orso'].value.reduction.corrections += [
# 'footprint correction'
# ]
# except KeyError:
# orso.not_found_warning()
return FootprintCorrected[Run](data_array_fp_correction)


def normalize_by_counts(data_array: sc.DataArray) -> sc.DataArray:
def normalize_by_counts(data_array: Normalizable) -> NormalizedData[Normalizable]:
"""
Normalize the bin-summed data by the total number of counts.
If the data has variances, a check is performed to ensure that the counts in each
Expand Down
28 changes: 23 additions & 5 deletions src/essreflectometry/reflectometry/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,21 @@ class ThetaData(sciline.Scope[Run, sc.DataArray], sc.DataArray):
"""Wavelength data transformed to theta"""


class Experiment(sciline.Scope[Run, sc.DataArray], sc.DataArray):
"""Experiment data with added coordinates:
wavelength, incidence angle, and momentum transfer"""
class QData(sciline.Scope[Run, sc.DataArray], sc.DataArray):
"""Theta data transformed to momentum transfer"""


class FootprintCorrected(sciline.Scope[Run, sc.DataArray], sc.DataArray):
"""Experiment data corrected by footprint on sample"""


CalibratedReference = NewType('CalibratedReference', sc.DataArray)
WithQResolution = NewType('WithQResolution', sc.DataArray)
Resolutions = NewType('Resolutions', dict)
Normalized = NewType('Normalized', sc.DataArray)
CountsByMomentumTransfer = NewType('CountsByMomentumTransfer', sc.DataArray)

''' Parameters for the workflow '''
MomentumTransferBins = NewType('MomentumTransferBins', sc.Variable)
QBins = NewType('QBins', sc.Variable)
WavelengthBins = NewType('WavelengthBins', sc.Variable)
ThetaBins = NewType('ThetaBins', sc.Variable)

Expand All @@ -55,3 +54,22 @@ class BeamlineParams(sciline.Scope[Run, dict], dict):
SpecularReflectionCoordTransformGraph = NewType(
'SpecularReflectionCoordTransformGraph', dict
)

QDataWithResolutions = NewType('QDataWithResolutions', sc.DataArray)
CorrectedQData = TypeVar('CorrectedQData', QData[Reference], QDataWithResolutions)


class HistogrammedByQ(sciline.Scope[CorrectedQData, sc.DataArray], sc.DataArray):
"""Histogrammmed by Q. Either reference data or sample data with resolutions."""


Normalizable = TypeVar(
'Normalizable', HistogrammedByQ[QDataWithResolutions], CalibratedReference
)


class NormalizedData(sciline.Scope[Normalizable, sc.DataArray], sc.DataArray):
"""Normalized histogramm by Q."""


NormalizedIOverQ = NewType('NormalizedIOverQ', sc.DataArray)

0 comments on commit be891e0

Please sign in to comment.