Source code for nexgen.beamlines.GDAtools.GDAjson2params

"""
Tools to extract goniometer and detector parameters from GDA JSON files.
"""

from __future__ import annotations

import json
from pathlib import Path
from typing import Dict, List, Tuple

from nexgen.nxs_utils import Axis, EigerDetector, TransformationType, TristanDetector
from nexgen.nxs_utils.detector import DetectorType, UnknownDetectorTypeError
from nexgen.utils import Point3D


[docs] class JSONParamsIO: """Read JSON file and exctract parameters.""" def __init__(self, json_file: Path | str): self.json_file = json_file self.params = self._read_file() def _read_file(self) -> Dict: with open(self.json_file, "r") as fh: params = json.load(fh) return params def _find_axis_depends_on(self, dep_val: str) -> str: depends = dep_val.split("_")[1] if "_" in dep_val else dep_val if depends in ["x", "y", "z"]: depends = f"sam_{depends}" return depends
[docs] def get_coordinate_frame(self) -> str: """Get the coordinate frame from geometry json file.""" return self.params["geometry"]
[docs] def get_goniometer_axes_from_file(self) -> List[Axis]: """Read the axes information from the GDA-supplied json file.""" axes_list = [] for v in self.params.values(): if isinstance(v, dict) and v["location"] == "sample": ax_depends = self._find_axis_depends_on(v["depends_on"]) ax_type = ( TransformationType.ROTATION if v["type"] == "rotation" else TransformationType.TRANSLATION ) axes_list.append( Axis(v["ds_name"], ax_depends, ax_type, tuple(v["vector"])) ) return axes_list
[docs] def get_detector_axes_from_file(self) -> List[Axis]: """Read the detector axes information from the GDA-supplied json file.""" axes_list = [] for v in self.params.values(): if isinstance(v, dict) and v["location"] == "detector": ax_type = ( TransformationType.ROTATION if v["type"] == "rotation" else TransformationType.TRANSLATION ) axes_list.append( Axis(v["ds_name"], v["depends_on"], ax_type, tuple(v["vector"])) ) return axes_list
[docs] def get_detector_params_from_file(self) -> DetectorType: """Read the detector parameters from the GDA-supplied json file.""" if "tristan" in self.params.keys(): tristan_params = self.params["tristan"] material = ( "Si" if tristan_params["sensor_material"] == "Silicon" else tristan_params["sensor_material"] ) thickness = ( str(tristan_params["sensor_thickness"]) + tristan_params["sensor_thickness_units"] ) pix = [ str(i) + tristan_params["pixel_size_units"] for i in tristan_params["pixel_size_sf"][::-1] ] det_params = TristanDetector( description=tristan_params["description"], image_size=tristan_params["data_size_sf"][::-1], sensor_material=material, sensor_thickness=thickness, pixel_size=pix, detector_type=tristan_params["detector_type"], ) elif "eiger" in self.params.keys(): eiger_params = self.params["eiger"] material = eiger_params["sensor_material"] pix = [ str(i) + eiger_params["pixel_size_units"] for i in eiger_params["pixel_size"] ] if material == "Silicon": material = "Si" det_params = EigerDetector( description=eiger_params["description"], image_size=eiger_params["size"], sensor_material=material, overload=50649, underload=-1, pixel_size=pix, ) else: raise UnknownDetectorTypeError("Unknown detector in GDA JSON file.") return det_params
[docs] def get_fast_and_slow_direction_vectors_from_file( self, det_type: str, ) -> Tuple[Point3D, Point3D]: """Read detector fast and slow axes from the GDA-supplied json file.""" det_name = "eiger" if "eiger" in det_type.lower() else "tristan" det_params = self.params[det_name] fast_axis = Point3D( x=det_params["fast_dir"][0], y=det_params["fast_dir"][1], z=det_params["fast_dir"][2], ) slow_axis = Point3D( x=det_params["slow_dir"][0], y=det_params["slow_dir"][1], z=det_params["slow_dir"][2], ) return fast_axis, slow_axis