from typing import Dict
from typing import Mapping
from typing import Sequence
from typing import Tuple
from ewokscore import missing_data
from pyFAI.calibrant import ALL_CALIBRANTS
from pyFAI.detectors import ALL_DETECTORS
from . import serialize
_GEOMETRY_KEYS = "dist", "poni1", "poni2", "rot1", "rot2", "rot3"
_ENERGY_GEOMETRY_KEYS = ("energy",) + _GEOMETRY_KEYS
_PARAMETRIZATION_KEYS = (
"dist_expr",
"param_names",
"poni1_expr",
"poni2_expr",
"pos_names",
"rot1_expr",
"rot2_expr",
"rot3_expr",
"wavelength_expr",
)
_PARAMETERS_KEYS = (
"arot1",
"arot2",
"arot3",
"dist_offset",
"dist_scale",
"energy",
"poni1_offset",
"poni1_scale",
"poni2_offset",
"poni2_scale",
)
[docs]
def output_parameters_calibratesingle() -> dict:
parameters = dict()
_add_energy_geometry(parameters, dict())
return parameters
[docs]
def output_parameters_calibratemulti() -> dict:
parameters = dict()
_add_parametrization(parameters, dict())
return parameters
[docs]
def output_parameters_calculategeometry() -> dict:
parameters = dict()
_add_energy_geometry(parameters, dict())
return parameters
[docs]
def output_parameters_pyfai_config() -> dict:
parameters = dict()
_add_energy_geometry(parameters, dict())
_add_detector_output(parameters)
_add_calibrant_output(parameters)
return parameters
def _add_diagnostics_output(parameters: dict) -> None:
parameters["filename"] = {
"label": "Output file",
"value_for_type": "",
"select": "newfile",
}
def _add_energy_geometry(parameters: dict, values: Mapping) -> None:
values = _unpack(values, _GEOMETRY_KEYS, "geometry")
parameters["energy"] = {
"label": "Energy (keV)",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["dist"] = {
"label": "Distance (cm)",
"value_for_type": "",
"serialize": serialize.cm_serialize,
"deserialize": serialize.cm_deserialize,
}
parameters["poni1"] = {
"label": "Poni1 (cm)",
"value_for_type": "",
"serialize": serialize.cm_serialize,
"deserialize": serialize.cm_deserialize,
}
parameters["poni2"] = {
"label": "Poni2 (cm)",
"value_for_type": "",
"serialize": serialize.cm_serialize,
"deserialize": serialize.cm_deserialize,
}
parameters["rot1"] = {
"label": "Rot1 (deg)",
"value_for_type": "",
"serialize": serialize.degrees_serialize,
"deserialize": serialize.degrees_deserialize,
}
parameters["rot2"] = {
"label": "Rot2 (deg)",
"value_for_type": "",
"serialize": serialize.degrees_serialize,
"deserialize": serialize.degrees_deserialize,
}
parameters["rot3"] = {
"label": "Rot3 (deg)",
"value_for_type": "",
"serialize": serialize.degrees_serialize,
"deserialize": serialize.degrees_deserialize,
}
def _add_calib_energy_geometry(parameters: dict, values: Mapping):
values = _unpack(values, _GEOMETRY_KEYS, "geometry")
fixed = values.pop("fixed", None)
if not fixed:
fixed = list()
for name in _ENERGY_GEOMETRY_KEYS:
parameters[name].update(
{
"checked": name not in fixed,
"checkbox_label": "refine",
}
)
parameters["robust"] = {
"label": "Robust",
"value_for_type": True,
}
def _add_parametrization(parameters: dict, values: Mapping) -> None:
values = _unpack(values, _PARAMETRIZATION_KEYS, "parametrization")
values = _unpack(values, _PARAMETERS_KEYS, "parameters")
parameters["energy"] = {
"label": "energy (keV)",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["wavelength_expr"] = {
"label": "wavelength (m) =",
"value_for_type": "",
}
parameters["dist_offset"] = {
"label": "dist_offset (cm)",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["dist_scale"] = {
"label": "dist_scal",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["dist_expr"] = {
"label": "dist (m) =",
"value_for_type": "",
}
parameters["poni1_offset"] = {
"label": "poni1_offset (cm)",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["poni1_scale"] = {
"label": "poni1_scale",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["poni1_expr"] = {
"label": "poni1 (m) =",
"value_for_type": "",
}
parameters["poni2_offset"] = {
"label": "poni2_offset (cm)",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["poni2_scale"] = {
"label": "poni2_scale",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["poni2_expr"] = {
"label": "poni2 (m) =",
"value_for_type": "",
}
parameters["arot1"] = {
"label": "arot1 (rad)",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["rot1_expr"] = {
"label": "rot1 (rad) =",
"value_for_type": "",
}
parameters["arot2"] = {
"label": "arot2 (rad)",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["rot2_expr"] = {
"label": "rot2 (rad) =",
"value_for_type": "",
}
parameters["arot3"] = {
"label": "arot3 (drad)",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["rot3_expr"] = {
"label": "rot3 (rad) =",
"value_for_type": "",
}
def _add_detector_input(parameters: dict) -> None:
parameters["detector"] = {
"label": "Detector",
"value_for_type": list(ALL_DETECTORS),
"serialize": str.lower,
}
parameters["detector_config"] = {
"label": "Detector parameters",
"value_for_type": "",
"serialize": serialize.json_dumps,
"deserialize": serialize.json_loads,
}
def _add_detector_output(parameters: dict) -> None:
parameters["detector"] = {
"label": "Detector",
"value_for_type": "",
"serialize": str.lower,
}
parameters["detector_config"] = {
"label": "Detector parameters",
"value_for_type": "",
"serialize": serialize.json_dumps,
"deserialize": serialize.json_loads,
}
def _add_calibrant_input(parameters: dict) -> None:
parameters["calibrant"] = {
"label": "Calibrant",
"value_for_type": list(ALL_CALIBRANTS.all),
}
def _add_calibrant_output(parameters: dict) -> None:
parameters["calibrant"] = {
"label": "Calibrant",
"value_for_type": "",
}
[docs]
def output_parameters_calib(parameters: dict):
_add_energy_geometry(parameters, dict())
def _add_data_singlecalib(parameters: dict) -> None:
parameters["image"] = {
"label": "Pattern",
"value_for_type": "",
"select": "h5dataset",
}
def _add_data_multicalib(parameters: dict) -> None:
parameters["images"] = {
"label": "Patterns",
"value_for_type": "",
"select": "h5datasets",
"serialize": serialize.json_dumps,
"deserialize": serialize.json_loads,
}
parameters["positions"] = {
"label": "Positions",
"value_for_type": "",
"select": "h5datasets",
"serialize": serialize.json_dumps,
"deserialize": serialize.json_loads,
}
parameters["reference_position"] = {
"label": "Reference Position",
"value_for_type": "",
"select": "h5dataset",
}
parameters["sample_position"] = {
"label": "Sample position",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["positionunits_in_meter"] = {
"label": "Position Units (meter)",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
def _add_data_integrate1d(parameters: dict) -> None:
parameters["image"] = {
"label": "Pattern",
"value_for_type": "",
"select": "h5dataset",
}
parameters["monitor"] = {
"label": "Monitor",
"value_for_type": "",
"select": "h5dataset",
}
parameters["reference"] = {
"label": "Reference",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["mask"] = {"label": "Mask", "value_for_type": "", "select": "h5dataset"}
_add_detector_input(parameters)
def _add_data_integrateblissscan(parameters: dict) -> None:
parameters["filename"] = {
"label": "Bliss filename",
"value_for_type": "",
"select": "file",
}
parameters["scan"] = {"label": "Scan number", "value_for_type": 0}
parameters["subscan"] = {"label": "Sub scan number", "value_for_type": 0}
parameters["detector_name"] = {"label": "Detector name", "value_for_type": ""}
parameters["counter_names"] = {
"label": "Counter names",
"value_for_type": "",
"serialize": serialize.json_dumps,
"deserialize": serialize.json_loads,
}
parameters["monitor"] = {
"label": "Monitor",
"value_for_type": "",
"select": "h5dataset",
}
parameters["reference"] = {
"label": "Reference",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["mask"] = {"label": "Mask", "value_for_type": "", "select": "h5dataset"}
_add_detector_input(parameters)
parameters["retry_timeout"] = {
"label": "retry_timeout",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["retry_period"] = {
"label": "retry_period",
"value_for_type": "",
"serialize": serialize.float_serialize,
"deserialize": serialize.float_deserialize,
}
parameters["demo"] = {"label": "demo", "value_for_type": False}
return parameters
def _apply_values(parameters: dict, values: Mapping) -> None:
for k, v in values.items():
if k in parameters:
parameters[k]["value"] = v
[docs]
def unpack_geometry(values: Mapping) -> Tuple[Mapping, Dict[str, bool]]:
values = _unpack(values, _GEOMETRY_KEYS, "geometry")
fixed = values.pop("fixed", None)
if fixed:
checked = {name: name not in fixed for name in _ENERGY_GEOMETRY_KEYS}
else:
checked = dict()
return values, checked
[docs]
def unpack_enabled_geometry(enabled: Dict[str, bool]) -> Dict[str, bool]:
values = _unpack_enabled(enabled, _GEOMETRY_KEYS, "geometry")
return values
[docs]
def pack_geometry(values: Mapping, checked: Dict[str, bool]) -> dict:
values = _pack(values, _GEOMETRY_KEYS, "geometry")
if checked:
values["fixed"] = [k for k, v in checked.items() if not v]
else:
values["fixed"] = missing_data.MISSING_DATA
return values
[docs]
def unpack_parametrization(values: Mapping) -> dict:
values = _unpack(values, _PARAMETRIZATION_KEYS, "parametrization")
values = _unpack(values, _PARAMETERS_KEYS, "parameters")
return values
[docs]
def unpack_enabled_parametrization(enabled: Dict[str, bool]) -> Dict[str, bool]:
values = _unpack_enabled(enabled, _PARAMETRIZATION_KEYS, "parametrization")
values = _unpack_enabled(enabled, _PARAMETERS_KEYS, "parameters")
return values
[docs]
def pack_parametrization(values: Mapping) -> dict:
values = _pack(values, _PARAMETRIZATION_KEYS, "parametrization")
values = _pack(values, _PARAMETERS_KEYS, "parameters")
return values
def _pack(values: Mapping, keys: Sequence[str], pack_key: str) -> dict:
result = {k: v for k, v in values.items() if k not in keys}
packed = {
k: v
for k, v in values.items()
if k in keys and not missing_data.is_missing_data(v)
}
if len(packed) == len(keys):
result[pack_key] = packed
else:
result[pack_key] = missing_data.MISSING_DATA
return result
def _unpack(values: Mapping, keys: Sequence[str], pack_key: str) -> dict:
result = dict(values)
packed = result.pop(pack_key, None)
if packed:
result.update(packed)
else:
result.update({k: missing_data.MISSING_DATA for k in keys})
return result
def _unpack_enabled(
enabled: Dict[str, bool], keys: Sequence[str], pack_key: str
) -> Dict[str, bool]:
result = dict(enabled)
packed = result.pop(pack_key, None)
if packed is not None:
result.update({k: packed for k in keys})
return result