Source code for ewoksscxrd.tests.test_createxdsinp

from os import PathLike
from textwrap import dedent

import pytest

from ewoksscxrd.tasks.createxdsinp import CreateXDSInp


def _task_inputs(output):
    return {
        "output": str(output),
        "detector": "EIGER",
        "nx": 2068,
        "ny": 2162,
        "qx": 0.075,
        "qy": 0.075,
        "beam": [1052, 1102],
        "distance": 151.8,
        "data_range": [1, 2],
        "oscillation_range": 0.5,
        "wavelength": 0.2846,
    }


[docs] def test_create_xds_inp_success(tmp_path: PathLike): task = CreateXDSInp(inputs=_task_inputs(tmp_path / "cbf" / "frame_{index}.cbf")) task.execute() result = task.get_output_values() expected_file = tmp_path / "cbf" / "XDS.INP" assert result["saved_files_path"] == [str(expected_file)] content = expected_file.read_text(encoding="ascii") assert content == dedent( """\ !JOB= XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT !JOB= XYCORR INIT COLSPOT IDXREF JOB= XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT NAME_TEMPLATE_OF_DATA_FRAMES= frame_?.cbf SPACE_GROUP_NUMBER=0 ! 0 if unknown !UNIT_CELL_CONSTANTS= 10.317 10.317 7.3378 90 90 120 ! put correct values if known FRIEDEL'S_LAW=FALSE ! This acts only on the CORRECT step FRACTION_OF_POLARIZATION=0.99 ROTATION_AXIS=0 -1 0 POLARIZATION_PLANE_NORMAL=0 1 0 DIRECTION_OF_DETECTOR_X-AXIS=1 0 0 DIRECTION_OF_DETECTOR_Y-AXIS=0 1 0 INCIDENT_BEAM_DIRECTION=0 0 1 OSCILLATION_RANGE= 0.5 OVERLOAD=100000000 DATA_RANGE= 1 2 SPOT_RANGE= 1 2 BACKGROUND_RANGE= 1 2 NX= 2068 NY= 2162 QX= 0.075000 QY= 0.075000 DETECTOR= EIGER DETECTOR_DISTANCE= 151.8 ORGX= 1052 ORGY= 1102 X-RAY_WAVELENGTH=0.2846 UNTRUSTED_RECTANGLE= 513 514 0 3262 UNTRUSTED_RECTANGLE= 1028 1039 0 3262 UNTRUSTED_RECTANGLE= 1553 1554 0 3262 UNTRUSTED_RECTANGLE= 2068 2079 0 3262 UNTRUSTED_RECTANGLE= 2593 2594 0 3262 UNTRUSTED_RECTANGLE= 0 3108 512 549 UNTRUSTED_RECTANGLE= 0 3108 1062 1099 UNTRUSTED_RECTANGLE= 0 3108 1612 1649 UNTRUSTED_RECTANGLE= 0 3108 2162 2199 UNTRUSTED_RECTANGLE= 0 3108 2712 2749 SENSOR_THICKNESS=0.75 !mm SILICON= 18.023 !1/mm MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT=4 ! default of 6 is sometimes too high MAXIMUM_NUMBER_OF_STRONG_PIXELS=18000 ! total number of strong pixels used for indexation BACKGROUND_PIXEL=2.0 ! used by COLSPOT and INTEGRATE SIGNAL_PIXEL=3.0 ! needs to be lager than BACKGROUND_PIXEL, specifies standard deviation, used in COLSPOT and INTEGRATE REFINE(IDXREF)= CELL ORIENTATION AXIS ! BEAM POSITION REFINE(INTEGRATE)= CELL ORIENTATION AXIS ! BEAM POSITION REFINE(CORRECT)= CELL ORIENTATION AXIS ! BEAM POSITION """ )
[docs] def test_create_xds_inp_with_overrides(tmp_path: PathLike): inputs = _task_inputs(tmp_path / "cbf" / "frame_{index}.cbf") inputs.update( { "filename": "custom_XDS.INP", "detector": "PILATUS", "job": " DEFPIX INTEGRATE CORRECT", "job_comment_lines": [ "!JOB= XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT", "!JOB= XYCORR INIT COLSPOT IDXREF ", ], "library": "/home/opid27/lib/dectris-neggia.so", "overload": 999999, "space_group_number": 12, "unit_cell_constants": "127.77 127.77 67.26 90.000 90.000 90.000", "friedels_law": "TRUE", "fraction_of_polarization": 0.5, "trusted_region": [0.1, 1.2], "polarization_plane_normal": [1.0, 0.0, 0.0], "name_template_of_data_frames": "custom_????.cbf", "spot_range": [2, 3], "background_range": [1, 1], "rotation_axis": [0.0, 1.0, 0.0], "incident_beam_direction": [0.0, 0.0, -1.0], "untrusted_rectangles": [[1, 2, 3, 4]], "sensor_thickness": 1.0, "silicon": 20.0, "minimum_number_of_pixels_in_a_spot": 5, "maximum_number_of_strong_pixels": 999, "background_pixel": 1.5, "signal_pixel": 4.5, "refine_idxref": "AXIS", "refine_integrate": "BEAM POSITION", "refine_correct": "CELL", "exclude_resolution_range": "3.93 3.87 !ice-ring at 3.897 Angstrom", "include_resolution_range": "60 2.9 ! after CORRECT, insert high resol limit; re-run CORRECT", "beam_divergence": 0.17577, "beam_divergence_esd": 0.01758, "reflecting_range": 1.87829, "reflecting_range_esd": 0.26833, "xds_extra": ["TEST= CUSTOM"], } ) task = CreateXDSInp(inputs=inputs) task.execute() content = (tmp_path / "cbf" / "custom_XDS.INP").read_text(encoding="ascii") assert content == dedent( """\ !JOB= XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT !JOB= XYCORR INIT COLSPOT IDXREF JOB= DEFPIX INTEGRATE CORRECT NAME_TEMPLATE_OF_DATA_FRAMES= custom_????.cbf !LIB= /home/opid27/lib/dectris-neggia.so SPACE_GROUP_NUMBER=12 ! 0 if unknown UNIT_CELL_CONSTANTS=127.77 127.77 67.26 90.000 90.000 90.000 FRIEDEL'S_LAW=TRUE ! This acts only on the CORRECT step FRACTION_OF_POLARIZATION=0.5 ROTATION_AXIS=0 1 0 POLARIZATION_PLANE_NORMAL=1 0 0 DIRECTION_OF_DETECTOR_X-AXIS=1 0 0 DIRECTION_OF_DETECTOR_Y-AXIS=0 1 0 INCIDENT_BEAM_DIRECTION=0 0 -1 OSCILLATION_RANGE= 0.5 OVERLOAD=999999 TRUSTED_REGION= 0.1 1.2 DATA_RANGE= 1 2 SPOT_RANGE= 2 3 BACKGROUND_RANGE= 1 1 NX= 2068 NY= 2162 QX= 0.075000 QY= 0.075000 DETECTOR= PILATUS DETECTOR_DISTANCE= 151.8 ORGX= 1052 ORGY= 1102 X-RAY_WAVELENGTH=0.2846 UNTRUSTED_RECTANGLE= 1 2 3 4 SENSOR_THICKNESS=1 !mm SILICON= 20 !1/mm MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT=5 ! default of 6 is sometimes too high MAXIMUM_NUMBER_OF_STRONG_PIXELS=999 ! total number of strong pixels used for indexation BACKGROUND_PIXEL=1.5 ! used by COLSPOT and INTEGRATE SIGNAL_PIXEL=4.5 ! needs to be lager than BACKGROUND_PIXEL, specifies standard deviation, used in COLSPOT and INTEGRATE REFINE(IDXREF)= AXIS REFINE(INTEGRATE)= BEAM POSITION REFINE(CORRECT)= CELL EXCLUDE_RESOLUTION_RANGE= 3.93 3.87 !ice-ring at 3.897 Angstrom INCLUDE_RESOLUTION_RANGE=60 2.9 ! after CORRECT, insert high resol limit; re-run CORRECT BEAM_DIVERGENCE= 0.17577 BEAM_DIVERGENCE_E.S.D.= 0.01758 REFLECTING_RANGE= 1.87829 REFLECTING_RANGE_E.S.D.= 0.26833 TEST= CUSTOM """ )
[docs] def test_create_xds_inp_requires_directory_output(tmp_path: PathLike): output_file = tmp_path / "not_a_dir" output_file.write_text("x", encoding="ascii") with pytest.raises(RuntimeError, match="CreateXDSInp") as excinfo: task = CreateXDSInp(inputs=_task_inputs(output_file)) task.execute() assert isinstance(excinfo.value.__cause__, NotADirectoryError)
[docs] def test_create_xds_inp_accepts_legacy_aliases(tmp_path: PathLike): inputs = _task_inputs(tmp_path / "cbf") inputs.pop("beam") inputs.pop("distance") inputs.pop("wavelength") inputs["orgx"] = 1052 inputs["orgy"] = 1102 inputs["detector_distance"] = 151.8 inputs["wavelength"] = 0.2846 inputs["name_template_of_data_frames"] = "frame_?.cbf" task = CreateXDSInp(inputs=inputs) task.execute() content = (tmp_path / "cbf" / "XDS.INP").read_text(encoding="ascii") assert "ORGX= 1052 ORGY= 1102" in content assert "DETECTOR_DISTANCE= 151.8" in content assert "X-RAY_WAVELENGTH=0.2846" in content
[docs] def test_create_xds_inp_includes_starting_values_when_provided(tmp_path: PathLike): inputs = _task_inputs(tmp_path / "cbf" / "frame_{index}.cbf") inputs["starting_angle"] = -36 inputs["starting_frame"] = 1 task = CreateXDSInp(inputs=inputs) task.execute() content = (tmp_path / "cbf" / "XDS.INP").read_text(encoding="ascii") assert "STARTING_ANGLE= -36\nSTARTING_FRAME= 1\n" in content