Beispiel #1
0
def import_geometry(xds_inp=None, dials_json=None):
    assert (xds_inp, dials_json).count(None) == 1

    geom_kwds = set([
        "DIRECTION_OF_DETECTOR_X-AXIS",
        "DIRECTION_OF_DETECTOR_Y-AXIS",
        "DETECTOR_DISTANCE",
        "ORGX",
        "ORGY",
        "ROTATION_AXIS",  # "X-RAY_WAVELENGTH",
        "INCIDENT_BEAM_DIRECTION",
        "SEGMENT",
        "DIRECTION_OF_SEGMENT_X-AXIS",
        "DIRECTION_OF_SEGMENT_Y-AXIS",
        "SEGMENT_DISTANCE",
        "SEGMENT_ORGX",
        "SEGMENT_ORGY"
    ])

    # FIXME in case of multi-segment detector..

    if xds_inp:
        inp = get_xdsinp_keyword(xds_inp)
        inp = filter(lambda x: x[0] in geom_kwds, inp)
        return map(lambda x: "%s= %s" % x, inp)
    elif dials_json:
        import dxtbx.imageset
        from dxtbx.serialize.load import _decode_dict
        from dxtbx.model import BeamFactory
        from dxtbx.model import DetectorFactory
        from dxtbx.model import GoniometerFactory
        from dxtbx.model import ScanFactory
        from dxtbx.serialize.xds import to_xds
        j = json.loads(open(dials_json).read(), object_hook=_decode_dict)
        # dummy
        sweep = dxtbx.imageset.ImageSetFactory.from_template(
            "####", image_range=[1, 1], check_format=False)[0]
        sweep.set_detector(DetectorFactory.from_dict(j["detector"][0]))
        sweep.set_beam(BeamFactory.from_dict(j["beam"][0]))
        sweep.set_goniometer(GoniometerFactory.from_dict(j["goniometer"][0]))
        sweep.set_scan(
            ScanFactory.make_scan(image_range=[1, 1],
                                  exposure_times=[1],
                                  oscillation=[1, 2],
                                  epochs=[0]))  # dummy
        sio = cStringIO.StringIO()
        to_xds(sweep).XDS_INP(sio)
        inp = get_xdsinp_keyword(inp_str=sio.getvalue())
        inp = filter(lambda x: x[0] in geom_kwds, inp)
        return map(lambda x: "%s= %s" % x, inp)

    return []
def test_to_xds_multi_panel_i23(dials_regression, tmpdir):
    tmpdir.chdir()
    file_name = os.path.join(
        dials_regression, "image_examples", "DLS_I23", "germ_13KeV_0001.cbf"
    )
    sweep = ImageSetFactory.new([file_name])[0]
    to_xds = xds.to_xds(sweep)
    s1 = to_xds.XDS_INP()
    for expected_substr in (
        """\
!
! SEGMENT 1
!
SEGMENT= 1 2463 1 195
DIRECTION_OF_SEGMENT_X-AXIS= 1.00000 0.00000 0.00000
DIRECTION_OF_SEGMENT_Y-AXIS= 0.00000 -0.14347 0.98966
SEGMENT_DISTANCE= 250.000
SEGMENT_ORGX= 1075.00 SEGMENT_ORGY= 97.67""",
        """\
!
! SEGMENT 24
!
SEGMENT= 1 2463 4877 5071
DIRECTION_OF_SEGMENT_X-AXIS= 1.00000 0.00000 0.00000
DIRECTION_OF_SEGMENT_Y-AXIS= 0.00000 -0.06390 -0.99796
SEGMENT_DISTANCE= 250.000
SEGMENT_ORGX= 1075.00 SEGMENT_ORGY= 4973.67""",
    ):
        assert expected_substr in s1
Beispiel #3
0
def dump(experiments, reflections, directory):
  '''
  Dump the files in XDS format

  '''
  import os
  from dxtbx.serialize import xds
  from scitbx import matrix
  if len(experiments) > 0:

    for i, experiment in enumerate(experiments):
      suffix = ""
      if len(experiments) > 1:
        suffix = "_%i" %(i+1)

      sub_dir = "%s%s" % (directory, suffix)
      if not os.path.isdir(sub_dir):
        os.makedirs(sub_dir)
      # XXX imageset is getting the experimental geometry from the image files
      # rather than the input experiments.json file
      imageset = experiment.imageset
      imageset.set_detector(experiment.detector)
      imageset.set_beam(experiment.beam)
      imageset.set_goniometer(experiment.goniometer)
      imageset.set_scan(experiment.scan)
      crystal_model = experiment.crystal
      crystal_model = crystal_model.change_basis(
        crystal_model.get_space_group().info()\
          .change_of_basis_op_to_reference_setting())
      A = matrix.sqr(crystal_model.get_A())
      A_inv = A.inverse()
      real_space_a = A_inv.elems[:3]
      real_space_b = A_inv.elems[3:6]
      real_space_c = A_inv.elems[6:9]
      to_xds = xds.to_xds(imageset)
      xds_inp = os.path.join(sub_dir, 'XDS.INP')
      xparm_xds = os.path.join(sub_dir, 'XPARM.XDS')
      print "Exporting experiment to %s and %s" %(xds_inp, xparm_xds)
      with open(xds_inp, 'wb') as f:
        to_xds.XDS_INP(
          out=f,
          space_group_number=crystal_model.get_space_group().type().number(),
          real_space_a=real_space_a,
          real_space_b=real_space_b,
          real_space_c=real_space_c,
          job_card="XYCORR INIT DEFPIX INTEGRATE CORRECT")
      with open(xparm_xds, 'wb') as f:
        to_xds.xparm_xds(
          real_space_a, real_space_b, real_space_c,
          crystal_model.get_space_group().type().number(),
          out=f)

      if reflections is not None and len(reflections) > 0:
        ref_cryst = reflections.select(reflections['id'] == i)
        export_spot_xds(ref_cryst, os.path.join(sub_dir, 'SPOT.XDS'))

  else:
    if not os.path.isdir(directory):
      os.makedirs(directory)
    export_spot_xds(reflections, os.path.join(directory, 'SPOT.XDS'))
Beispiel #4
0
    def test_ii(self):
        idxref = self.Idxref()

        self._index_remove_masked_regions()
        for file in ["SPOT.XDS"]:
            idxref.set_input_data_file(file, self._indxr_payload[file])

        idxref.set_data_range(self._indxr_images[0][0],
                              self._indxr_images[0][1])
        idxref.set_background_range(self._indxr_images[0][0],
                                    self._indxr_images[0][1])

        for block in self._indxr_images[:1]:
            starting_frame = block[0]
            starting_angle = self.get_scan().get_angle_from_image_index(
                starting_frame)

            idxref.set_starting_frame(starting_frame)
            idxref.set_starting_angle(starting_angle)

            idxref.add_spot_range(block[0], block[1])

        converter = to_xds(self.get_imageset())
        xds_beam_centre = converter.detector_origin

        idxref.set_beam_centre(xds_beam_centre[0], xds_beam_centre[1])

        idxref.run()

        return idxref.get_fraction_rmsd_rmsphi()
Beispiel #5
0
def test_vmxi_thaumatin(dials_data):
    master_h5 = dials_data("vmxi_thaumatin") / "image_15799_master.h5"
    expts = ExperimentListFactory.from_filenames([master_h5.strpath])
    to_xds = xds.to_xds(expts[0].imageset)
    s = to_xds.XDS_INP()
    assert "DETECTOR=EIGER" in s
    assert "SENSOR_THICKNESS= 0.450" in s
Beispiel #6
0
  def test_ii(self):
    idxref = self.Idxref()

    self._index_remove_masked_regions()
    for file in ['SPOT.XDS']:
      idxref.set_input_data_file(file, self._indxr_payload[file])

    idxref.set_data_range(self._indxr_images[0][0],
                          self._indxr_images[0][1])
    idxref.set_background_range(self._indxr_images[0][0],
                                self._indxr_images[0][1])

    for block in self._indxr_images[:1]:
      starting_frame = block[0]
      starting_angle = self.get_scan().get_angle_from_image_index(starting_frame)

      idxref.set_starting_frame(starting_frame)
      idxref.set_starting_angle(starting_angle)

      idxref.add_spot_range(block[0], block[1])

    #mosflm_beam_centre = self.get_beam_centre()
    #xds_beam_centre = beam_centre_mosflm_to_xds(
        #mosflm_beam_centre[0], mosflm_beam_centre[1], self.get_header())
    from dxtbx.serialize.xds import to_xds
    converter = to_xds(self.get_imageset())
    xds_beam_centre = converter.detector_origin

    idxref.set_beam_centre(xds_beam_centre[0],
                           xds_beam_centre[1])

    idxref.run()

    return idxref.get_fraction_rmsd_rmsphi()
Beispiel #7
0
def dump(experiments, reflections, directory):
  '''
  Dump the files in XDS format

  '''
  import os
  from dxtbx.serialize import xds
  if len(experiments) > 0:

    for i in range(len(experiments)):
      suffix = ""
      if len(experiments) > 1:
        suffix = "_%i" %(i+1)

      sub_dir = "%s%s" % (directory, suffix)
      if not os.path.isdir(sub_dir):
        os.makedirs(sub_dir)
      # XXX imageset is getting the experimental geometry from the image files
      # rather than the input experiments.json file
      imageset = experiments[i].imageset
      imageset.set_detector(experiments[i].detector)
      imageset.set_beam(experiments[i].beam)
      imageset.set_goniometer(experiments[i].goniometer)
      imageset.set_scan(experiments[i].scan)
      crystal_model = experiments[i].crystal
      crystal_model = crystal_model.change_basis(
        crystal_model.get_space_group().info()\
          .change_of_basis_op_to_reference_setting())
      A = crystal_model.get_A()
      A_inv = A.inverse()
      real_space_a = A_inv.elems[:3]
      real_space_b = A_inv.elems[3:6]
      real_space_c = A_inv.elems[6:9]
      to_xds = xds.to_xds(imageset)
      xds_inp = os.path.join(sub_dir, 'XDS.INP')
      xparm_xds = os.path.join(sub_dir, 'XPARM.XDS')
      print "Exporting experiment to %s and %s" %(xds_inp, xparm_xds)
      with open(xds_inp, 'wb') as f:
        to_xds.XDS_INP(
          out=f,
          space_group_number=crystal_model.get_space_group().type().number(),
          real_space_a=real_space_a,
          real_space_b=real_space_b,
          real_space_c=real_space_c,
          job_card="XYCORR INIT DEFPIX INTEGRATE CORRECT")
      with open(xparm_xds, 'wb') as f:
        to_xds.xparm_xds(
          real_space_a, real_space_b, real_space_c,
          crystal_model.get_space_group().type().number(),
          out=f)

      if reflections is not None and len(reflections) > 0:
        ref_cryst = reflections.select(reflections['id'] == i)
        export_spot_xds(ref_cryst, os.path.join(sub_dir, 'SPOT.XDS'))

  else:
    if not os.path.isdir(directory):
      os.makedirs(directory)
    export_spot_xds(reflections, os.path.join(directory, 'SPOT.XDS'))
Beispiel #8
0
def run(file_names):
  if len(file_names) == 1 and file_names[0].endswith('json'):
    from dxtbx.serialize import load
    datablock = load.datablock(file_names[0])
    assert(len(datablock) == 1)
    sweep = datablock[0].extract_sweeps()[0]
  else:
    from dxtbx.imageset import ImageSetFactory
    sweep = ImageSetFactory.new(file_names)[0]
  xsx = xds.to_xds(sweep)
  xsx.XDS_INP()
Beispiel #9
0
def test_to_xds_multi_panel_i23(dials_regression, tmpdir, mocker):
    tmpdir.chdir()
    file_name = os.path.join(dials_regression, "image_examples", "DLS_I23",
                             "germ_13KeV_0001.cbf")
    sequence = ImageSetFactory.new([file_name])[0]
    to_xds = xds.to_xds(sequence)
    s1 = to_xds.XDS_INP()
    for expected_substr in (
            """\
!
! SEGMENT 1
!
SEGMENT= 1 2463 1 195
DIRECTION_OF_SEGMENT_X-AXIS= 1.00000 0.00000 0.00000
DIRECTION_OF_SEGMENT_Y-AXIS= 0.00000 -0.14347 0.98966
SEGMENT_DISTANCE= 250.000
SEGMENT_ORGX= 1075.00 SEGMENT_ORGY= 97.67""",
            """\
!
! SEGMENT 24
!
SEGMENT= 1 2463 4877 5071
DIRECTION_OF_SEGMENT_X-AXIS= 1.00000 0.00000 0.00000
DIRECTION_OF_SEGMENT_Y-AXIS= 0.00000 -0.06390 -0.99796
SEGMENT_DISTANCE= 250.000
SEGMENT_ORGX= 1075.00 SEGMENT_ORGY= 4973.67""",
    ):
        assert expected_substr in s1
    assert "UNTRUSTED_RECTANGLE" not in s1

    # Fool the format class into masking out a couple of bad modules
    mocked_timestamp = mocker.patch(
        "dxtbx.format.FormatCBFMiniPilatusDLS12M.get_pilatus_timestamp")
    mocked_timestamp.return_value = 1574857526.34
    sequence = ImageSetFactory.new([file_name])[0]
    to_xds = xds.to_xds(sequence)
    s = to_xds.XDS_INP()
    assert "UNTRUSTED_RECTANGLE= 0 488 3604 3800" in s
    assert "UNTRUSTED_RECTANGLE= 1976 2464 3604 3800" in s
Beispiel #10
0
def read_image_metadata_dxtbx(image):
    """Read the image header and send back the resulting metadata in a
    dictionary. Read this using dxtbx - for a sequence of images use the
    first image in the sequence to derive the metadata, for HDF5 files
    just get on an read."""

    check_file_readable(image)

    if image.endswith(".h5"):
        # XDS can literally only handle master files called (prefix)_master.h5
        assert "master" in image
        from dxtbx.datablock import DataBlockFactory

        db = DataBlockFactory.from_filenames([image])[0]
    else:
        from dxtbx.datablock import DataBlockTemplateImporter

        template, directory = image2template_directory(image)
        full_template = os.path.join(directory, template)
        importer = DataBlockTemplateImporter([full_template],
                                             allow_incomplete_sweeps=True)
        db = importer.datablocks[0]

    if hasattr(db, "extract_sequences"):
        db_extract = db.extract_sequences
    else:
        db_extract = db.extract_sweeps
    sequences = db_extract()[0]

    from dxtbx.serialize.xds import to_xds

    XDS_INP = to_xds(sequences).XDS_INP()
    params = XDS_INP_to_dict(XDS_INP)

    # detector type specific parameters - minimum spot size, trusted region
    # and so on.

    # from dxtbx.model.detector_helpers import detector_helper_sensors
    # d = sequences.get_detector()
    # sensor_type = d[0].get_type()
    # if sensor_type == detector_helper_sensors.SENSOR_PAD:
    #     params["MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT"] = "2"
    # else:
    #     params["MINIMUM_NUMBER_OF_PIXELS_IN_A_SPOT"] = "4"

    # remove things we will want to guarantee we set in fast_dp
    for name in ["BACKGROUND_RANGE", "SPOT_RANGE", "JOB"]:
        if name in params:
            del params[name]

    return params
Beispiel #11
0
def exercise_to_xds():
    if not libtbx.env.has_module("dials"):
        print "Skipping test: dials not present"
        return
    if not libtbx.env.has_module("dials_regression"):
        print "Skipping exercise_to_xds(): dials_regression not present"
        return

    data_dir = libtbx.env.find_in_repositories(
        relative_path="dials_regression/centroid_test_data",
        test=os.path.isdir)
    template = os.path.join(data_dir, "centroid_00*.cbf")
    file_names = glob.glob(template)
    sweep = ImageSetFactory.new(file_names)[0]
    to_xds = xds.to_xds(sweep)
    s1 = StringIO()
    to_xds.XDS_INP(out=s1)
    s2 = StringIO()
    real_space_a = (-5.327642, -39.034747, -4.988286)
    real_space_b = (-35.253495, 7.596265, -22.127661)
    real_space_c = (-22.673623, -1.486119, 35.793463)
    to_xds.xparm_xds(real_space_a,
                     real_space_b,
                     real_space_c,
                     space_group=1,
                     out=s2)
    # run coordinate frame converter on xparm.xds as a sanity check
    f = open_tmp_file(suffix="XPARM.XDS", mode="wb")
    s2.seek(0)
    f.writelines(s2.readlines())
    f.close()
    from rstbx.cftbx import coordinate_frame_helpers
    converter = coordinate_frame_helpers.import_xds_xparm(f.name)
    scan = sweep.get_scan()
    detector = sweep.get_detector()
    goniometer = sweep.get_goniometer()
    beam = sweep.get_beam()
    assert approx_equal(real_space_a, converter.get_real_space_a())
    assert approx_equal(real_space_b, converter.get_real_space_b())
    assert approx_equal(real_space_c, converter.get_real_space_c())
    assert approx_equal(goniometer.get_rotation_axis(),
                        converter.get_rotation_axis())
    assert approx_equal(beam.get_direction(),
                        converter.get_sample_to_source().elems)
    assert approx_equal(detector[0].get_fast_axis(),
                        converter.get_detector_fast())
    assert approx_equal(detector[0].get_slow_axis(),
                        converter.get_detector_slow())
    assert approx_equal(detector[0].get_origin(),
                        converter.get_detector_origin())
Beispiel #12
0
def test_to_xds(dials_regression, tmpdir):
    tmpdir.chdir()
    template = os.path.join(dials_regression, 'centroid_test_data',
                            "centroid_00*.cbf")
    file_names = glob.glob(template)
    sweep = ImageSetFactory.new(file_names)[0]
    to_xds = xds.to_xds(sweep)
    s1 = StringIO()
    to_xds.XDS_INP(out=s1)
    empty = StringIO()
    s1a = to_xds.XDS_INP(as_str=True, out=empty)
    assert empty.getvalue() == ''
    assert s1.getvalue().strip() == s1a
    s2 = StringIO()
    real_space_a = (-5.327642, -39.034747, -4.988286)
    real_space_b = (-35.253495, 7.596265, -22.127661)
    real_space_c = (-22.673623, -1.486119, 35.793463)
    to_xds.xparm_xds(real_space_a,
                     real_space_b,
                     real_space_c,
                     space_group=1,
                     out=s2)
    # run coordinate frame converter on xparm.xds as a sanity check
    with open('xparm.xds', mode="wb") as fh:
        s2.seek(0)
        fh.writelines(s2.readlines())
    from rstbx.cftbx import coordinate_frame_helpers
    converter = coordinate_frame_helpers.import_xds_xparm('xparm.xds')
    scan = sweep.get_scan()
    detector = sweep.get_detector()
    goniometer = sweep.get_goniometer()
    beam = sweep.get_beam()
    assert approx_equal(real_space_a, converter.get_real_space_a())
    assert approx_equal(real_space_b, converter.get_real_space_b())
    assert approx_equal(real_space_c, converter.get_real_space_c())
    assert approx_equal(goniometer.get_rotation_axis(),
                        converter.get_rotation_axis())
    assert approx_equal(beam.get_direction(),
                        converter.get_sample_to_source().elems)
    assert approx_equal(detector[0].get_fast_axis(),
                        converter.get_detector_fast())
    assert approx_equal(detector[0].get_slow_axis(),
                        converter.get_detector_slow())
    assert approx_equal(detector[0].get_origin(),
                        converter.get_detector_origin())
Beispiel #13
0
  def test_i(self):
    idxref = self.Idxref()

    self._index_remove_masked_regions()
    for file in ['SPOT.XDS']:
      idxref.set_input_data_file(file, self._indxr_payload[file])

    idxref.set_data_range(self._indxr_images[0][0],
                          self._indxr_images[0][1])
    idxref.set_background_range(self._indxr_images[0][0],
                                self._indxr_images[0][1])

    # set the phi start etc correctly

    blocks = self._index_select_images_i()

    for block in blocks[:1]:
      starting_frame = block[0]

      dd = Diffdump()
      dd.set_image(self.get_image_name(starting_frame))
      starting_angle = dd.readheader()['phi_start']

      idxref.set_starting_frame(starting_frame)
      idxref.set_starting_angle(starting_angle)

      idxref.add_spot_range(block[0], block[1])

    for block in blocks[1:]:
      idxref.add_spot_range(block[0], block[1])

    #mosflm_beam_centre = self.get_beam_centre()
    #xds_beam_centre = beam_centre_mosflm_to_xds(
        #mosflm_beam_centre[0], mosflm_beam_centre[1], self.get_header())
    from dxtbx.serialize.xds import to_xds
    converter = to_xds(self.get_imageset())
    xds_beam_centre = converter.detector_origin

    idxref.set_beam_centre(xds_beam_centre[0],
                           xds_beam_centre[1])

    idxref.run()

    return idxref.get_fraction_rmsd_rmsphi()
def run(file_names):
  if len(file_names) == 1 and file_names[0].endswith('json'):
    from dxtbx.serialize import load
    try:
      datablock = load.datablock(file_names[0])
      assert len(datablock) == 1
      sweep = datablock[0].extract_sweeps()[0]
    except ValueError as e:
      if str(e) == '"__id__" does not equal "imageset"':
        experiments = load.experiment_list(file_names[0])
        assert len(experiments) == 1
        sweep = experiments[0].imageset
      else:
        raise
  else:
    from dxtbx.imageset import ImageSetFactory
    sweep = ImageSetFactory.new(file_names)[0]
  xsx = xds.to_xds(sweep)
  xsx.XDS_INP()
    def test_i(self):
        idxref = self.Idxref()

        self._index_remove_masked_regions()
        for file in ["SPOT.XDS"]:
            idxref.set_input_data_file(file, self._indxr_payload[file])

        idxref.set_data_range(self._indxr_images[0][0],
                              self._indxr_images[0][1])
        idxref.set_background_range(self._indxr_images[0][0],
                                    self._indxr_images[0][1])

        # set the phi start etc correctly

        blocks = self._index_select_images_i()

        for block in blocks[:1]:
            starting_frame = block[0]
            starting_angle = self.get_scan().get_angle_from_image_index(
                starting_frame)

            idxref.set_starting_frame(starting_frame)
            idxref.set_starting_angle(starting_angle)

            idxref.add_spot_range(block[0], block[1])

        for block in blocks[1:]:
            idxref.add_spot_range(block[0], block[1])

        # mosflm_beam_centre = self.get_beam_centre()
        # xds_beam_centre = beam_centre_mosflm_to_xds(
        # mosflm_beam_centre[0], mosflm_beam_centre[1], self.get_header())
        from dxtbx.serialize.xds import to_xds

        converter = to_xds(self.get_imageset())
        xds_beam_centre = converter.detector_origin

        idxref.set_beam_centre(xds_beam_centre[0], xds_beam_centre[1])

        idxref.run()

        return idxref.get_fraction_rmsd_rmsphi()
Beispiel #16
0
def exercise_to_xds():
  if not libtbx.env.has_module("dials_regression"):
    print "Skipping exercise_to_xds(): dials_regression not present"
    return

  data_dir = libtbx.env.find_in_repositories(
    relative_path="dials_regression/centroid_test_data",
    test=os.path.isdir)
  template = os.path.join(data_dir, "centroid_00*.cbf")
  file_names = glob.glob(template)
  sweep = ImageSetFactory.new(file_names)[0]
  to_xds = xds.to_xds(sweep)
  s1 = StringIO()
  to_xds.XDS_INP(out=s1)
  s2 = StringIO()
  real_space_a = (-5.327642, -39.034747, -4.988286)
  real_space_b = (-35.253495, 7.596265, -22.127661)
  real_space_c = (-22.673623, -1.486119, 35.793463)
  to_xds.xparm_xds(real_space_a, real_space_b, real_space_c, space_group=1, out=s2)
  # run coordinate frame converter on xparm.xds as a sanity check
  f = open_tmp_file(suffix="XPARM.XDS", mode="wb")
  s2.seek(0)
  f.writelines(s2.readlines())
  f.close()
  from rstbx.cftbx import coordinate_frame_helpers
  converter = coordinate_frame_helpers.import_xds_xparm(f.name)
  scan = sweep.get_scan()
  detector = sweep.get_detector()
  goniometer = sweep.get_goniometer()
  beam = sweep.get_beam()
  assert approx_equal(real_space_a, converter.get_real_space_a())
  assert approx_equal(real_space_b, converter.get_real_space_b())
  assert approx_equal(real_space_c, converter.get_real_space_c())
  assert approx_equal(goniometer.get_rotation_axis(),
                      converter.get_rotation_axis())
  assert approx_equal(
    beam.get_direction(), converter.get_sample_to_source().elems)
  assert approx_equal(detector[0].get_fast_axis(), converter.get_detector_fast())
  assert approx_equal(detector[0].get_slow_axis(), converter.get_detector_slow())
  assert approx_equal(detector[0].get_origin(), converter.get_detector_origin())
Beispiel #17
0
  def _index(self):
    '''Actually do the autoindexing using the data prepared by the
    previous method.'''

    images_str = '%d to %d' % tuple(self._indxr_images[0])
    for i in self._indxr_images[1:]:
      images_str += ', %d to %d' % tuple(i)

    cell_str = None
    if self._indxr_input_cell:
      cell_str = '%.2f %.2f %.2f %.2f %.2f %.2f' % \
                 self._indxr_input_cell

    # then this is a proper autoindexing run - describe this
    # to the journal entry

    #if len(self._fp_directory) <= 50:
      #dirname = self._fp_directory
    #else:
      #dirname = '...%s' % self._fp_directory[-46:]
    dirname = self.get_directory()

    Journal.block('autoindexing', self._indxr_sweep_name, 'XDS',
                  {'images':images_str,
                   'target cell':cell_str,
                   'target lattice':self._indxr_input_lattice,
                   'template':self.get_template(),
                   'directory':dirname})

    idxref = self.Idxref()

    self._index_remove_masked_regions()
    for file in ['SPOT.XDS']:
      idxref.set_input_data_file(file, self._indxr_payload[file])

    idxref.set_data_range(self._indxr_images[0][0],
                          self._indxr_images[0][1])
    idxref.set_background_range(self._indxr_images[0][0],
                                self._indxr_images[0][1])

    # set the phi start etc correctly

    if self._i_or_ii == None:
      self._i_or_ii = self.decide_i_or_ii()
      Debug.write('Selecting I or II, chose %s' % self._i_or_ii)

    if self._i_or_ii == 'i':
      blocks = self._index_select_images_i()
      for block in blocks[:1]:
        starting_frame = block[0]

        dd = Diffdump()
        dd.set_image(self.get_image_name(starting_frame))
        starting_angle = dd.readheader()['phi_start']

        idxref.set_starting_frame(starting_frame)
        idxref.set_starting_angle(starting_angle)

        idxref.add_spot_range(block[0], block[1])

      for block in blocks[1:]:
        idxref.add_spot_range(block[0], block[1])
    else:
      for block in self._indxr_images[:1]:
        starting_frame = block[0]

        dd = Diffdump()
        dd.set_image(self.get_image_name(starting_frame))
        starting_angle = dd.readheader()['phi_start']

        idxref.set_starting_frame(starting_frame)
        idxref.set_starting_angle(starting_angle)

        idxref.add_spot_range(block[0], block[1])

      for block in self._indxr_images[1:]:
        idxref.add_spot_range(block[0], block[1])

    # FIXME need to also be able to pass in the known unit
    # cell and lattice if already available e.g. from
    # the helper... indirectly

    if self._indxr_user_input_lattice:
      idxref.set_indexer_user_input_lattice(True)

    if self._indxr_input_lattice and self._indxr_input_cell:
      idxref.set_indexer_input_lattice(self._indxr_input_lattice)
      idxref.set_indexer_input_cell(self._indxr_input_cell)

      Debug.write('Set lattice: %s' % self._indxr_input_lattice)
      Debug.write('Set cell: %f %f %f %f %f %f' % \
                  self._indxr_input_cell)

      original_cell = self._indxr_input_cell
    elif self._indxr_input_lattice:
      idxref.set_indexer_input_lattice(self._indxr_input_lattice)
      original_cell = None
    else:
      original_cell = None

    # FIXED need to set the beam centre here - this needs to come
    # from the input .xinfo object or header, and be converted
    # to the XDS frame... done.

    #mosflm_beam_centre = self.get_beam_centre()
    #xds_beam_centre = beam_centre_mosflm_to_xds(
        #mosflm_beam_centre[0], mosflm_beam_centre[1], self.get_header())
    from dxtbx.serialize.xds import to_xds
    converter = to_xds(self.get_imageset())
    xds_beam_centre = converter.detector_origin

    idxref.set_beam_centre(xds_beam_centre[0],
                           xds_beam_centre[1])

    # fixme need to check if the lattice, cell have been set already,
    # and if they have, pass these in as input to the indexing job.

    done = False

    while not done:
      try:
        done = idxref.run()

        # N.B. in here if the IDXREF step was being run in the first
        # pass done is FALSE however there should be a refined
        # P1 orientation matrix etc. available - so keep it!

      except XDSException, e:
        # inspect this - if we have complaints about not
        # enough reflections indexed, and we have a target
        # unit cell, and they are the same, well ignore it

        if 'solution is inaccurate' in str(e):
          Debug.write(
              'XDS complains solution inaccurate - ignoring')
          done = idxref.continue_from_error()
        elif ('insufficient percentage (< 70%)' in str(e) or
              'insufficient percentage (< 50%)' in str(e)) and \
                 original_cell:
          done = idxref.continue_from_error()
          lattice, cell, mosaic = \
                   idxref.get_indexing_solution()
          # compare solutions
          for j in range(3):
            # allow two percent variation in unit cell length
            if math.fabs((cell[j] - original_cell[j]) / \
                         original_cell[j]) > 0.02 and \
                         not Flags.get_relax():
              Debug.write('XDS unhappy and solution wrong')
              raise e
            # and two degree difference in angle
            if math.fabs(cell[j + 3] - original_cell[j + 3]) \
                   > 2.0 and not Flags.get_relax():
              Debug.write('XDS unhappy and solution wrong')
              raise e
          Debug.write('XDS unhappy but solution ok')
        elif 'insufficient percentage (< 70%)' in str(e) or \
                 'insufficient percentage (< 50%)' in str(e):
          Debug.write('XDS unhappy but solution probably ok')
          done = idxref.continue_from_error()
        else:
          raise e
Beispiel #18
0
    def _index_prepare(self):
        """Prepare to do autoindexing - in XDS terms this will mean
        calling xycorr, init and colspot on the input images."""

        # decide on images to work with

        logger.debug("XDS INDEX PREPARE:")
        logger.debug("Wavelength: %.6f", self.get_wavelength())
        logger.debug("Distance: %.2f", self.get_distance())

        if self._indxr_images == []:
            _select_images_function = getattr(
                self, "_index_select_images_%s" % self._index_select_images
            )
            wedges = _select_images_function()
            for wedge in wedges:
                self.add_indexer_image_wedge(wedge)
            self.set_indexer_prepare_done(True)

        all_images = self.get_matching_images()

        first = min(all_images)
        last = max(all_images)

        # next start to process these - first xycorr

        xycorr = self.Xycorr()

        xycorr.set_data_range(first, last)
        xycorr.set_background_range(self._indxr_images[0][0], self._indxr_images[0][1])

        converter = to_xds(self.get_imageset())
        xds_beam_centre = converter.detector_origin
        xycorr.set_beam_centre(xds_beam_centre[0], xds_beam_centre[1])
        for block in self._indxr_images:
            xycorr.add_spot_range(block[0], block[1])

        # FIXME need to set the origin here

        xycorr.run()

        for file in ["X-CORRECTIONS.cbf", "Y-CORRECTIONS.cbf"]:
            self._indxr_payload[file] = xycorr.get_output_data_file(file)

        # next start to process these - then init

        if PhilIndex.params.xia2.settings.input.format.dynamic_shadowing:
            imageset = self._indxr_imagesets[0]
            masker = (
                imageset.get_format_class()
                .get_instance(imageset.paths()[0])
                .get_masker()
            )
            if masker is None:
                # disable dynamic_shadowing
                PhilIndex.params.xia2.settings.input.format.dynamic_shadowing = False

        if PhilIndex.params.xia2.settings.input.format.dynamic_shadowing:
            # find the region of the scan with the least predicted shadow
            # to use for background determination in XDS INIT step
            from dxtbx.model.experiment_list import ExperimentListFactory

            imageset = self._indxr_imagesets[0]
            xsweep = self._indxr_sweeps[0]
            sweep_filename = os.path.join(
                self.get_working_directory(), "%s_indexed.expt" % xsweep.get_name()
            )
            ExperimentListFactory.from_imageset_and_crystal(imageset, None).as_file(
                sweep_filename
            )

            from xia2.Wrappers.Dials.ShadowPlot import ShadowPlot

            shadow_plot = ShadowPlot()
            shadow_plot.set_working_directory(self.get_working_directory())
            auto_logfiler(shadow_plot)
            shadow_plot.set_sweep_filename(sweep_filename)
            shadow_plot.set_json_filename(
                os.path.join(
                    self.get_working_directory(),
                    "%s_shadow_plot.json" % shadow_plot.get_xpid(),
                )
            )
            shadow_plot.run()
            results = shadow_plot.get_results()

            fraction_shadowed = flex.double(results["fraction_shadowed"])
            if flex.max(fraction_shadowed) == 0:
                PhilIndex.params.xia2.settings.input.format.dynamic_shadowing = False
            else:
                scan_points = flex.double(results["scan_points"])

                scan = imageset.get_scan()
                oscillation = scan.get_oscillation()

                if self._background_images is not None:
                    bg_images = self._background_images
                    bg_range_deg = (
                        scan.get_angle_from_image_index(bg_images[0]),
                        scan.get_angle_from_image_index(bg_images[1]),
                    )
                    bg_range_width = bg_range_deg[1] - bg_range_deg[0]

                    min_shadow = 100
                    best_bg_range = bg_range_deg
                    from libtbx.utils import frange

                    for bg_range_start in frange(
                        flex.min(scan_points),
                        flex.max(scan_points) - bg_range_width,
                        step=oscillation[1],
                    ):
                        bg_range_deg = (bg_range_start, bg_range_start + bg_range_width)
                        sel = (scan_points >= bg_range_deg[0]) & (
                            scan_points <= bg_range_deg[1]
                        )
                        mean_shadow = flex.mean(fraction_shadowed.select(sel))
                        if mean_shadow < min_shadow:
                            min_shadow = mean_shadow
                            best_bg_range = bg_range_deg

                    self._background_images = (
                        scan.get_image_index_from_angle(best_bg_range[0]),
                        scan.get_image_index_from_angle(best_bg_range[1]),
                    )
                    logger.debug(
                        "Setting background images: %s -> %s" % self._background_images
                    )

        init = self.Init()

        for file in ["X-CORRECTIONS.cbf", "Y-CORRECTIONS.cbf"]:
            init.set_input_data_file(file, self._indxr_payload[file])

        init.set_data_range(first, last)

        if self._background_images:
            init.set_background_range(
                self._background_images[0], self._background_images[1]
            )
        else:
            init.set_background_range(
                self._indxr_images[0][0], self._indxr_images[0][1]
            )

        for block in self._indxr_images:
            init.add_spot_range(block[0], block[1])

        init.run()

        # at this stage, need to (perhaps) modify the BKGINIT.cbf image
        # to mark out the back stop

        if PhilIndex.params.xds.backstop_mask:
            logger.debug("Applying mask to BKGINIT.pck")

            # copy the original file
            cbf_old = os.path.join(init.get_working_directory(), "BKGINIT.cbf")
            cbf_save = os.path.join(init.get_working_directory(), "BKGINIT.sav")
            shutil.copyfile(cbf_old, cbf_save)

            # modify the file to give the new mask
            from xia2.Toolkit.BackstopMask import BackstopMask

            mask = BackstopMask(PhilIndex.params.xds.backstop_mask)
            mask.apply_mask_xds(self.get_header(), cbf_save, cbf_old)

            init.reload()

        for file in ["BLANK.cbf", "BKGINIT.cbf", "GAIN.cbf"]:
            self._indxr_payload[file] = init.get_output_data_file(file)

        if PhilIndex.params.xia2.settings.developmental.use_dials_spotfinder:

            spotfinder = self.DialsSpotfinder()

            for block in self._indxr_images:
                spotfinder.add_spot_range(block[0], block[1])

            spotfinder.run()
            export = self.DialsExportSpotXDS()
            export.set_input_data_file(
                "observations.refl",
                spotfinder.get_output_data_file("observations.refl"),
            )
            export.run()

            for file in ["SPOT.XDS"]:
                self._indxr_payload[file] = export.get_output_data_file(file)

        else:

            # next start to process these - then colspot

            colspot = self.Colspot()

            for file in (
                "X-CORRECTIONS.cbf",
                "Y-CORRECTIONS.cbf",
                "BLANK.cbf",
                "BKGINIT.cbf",
                "GAIN.cbf",
            ):
                colspot.set_input_data_file(file, self._indxr_payload[file])

            colspot.set_data_range(first, last)
            colspot.set_background_range(
                self._indxr_images[0][0], self._indxr_images[0][1]
            )
            for block in self._indxr_images:
                colspot.add_spot_range(block[0], block[1])

            colspot.run()

            for file in ["SPOT.XDS"]:
                self._indxr_payload[file] = colspot.get_output_data_file(file)
Beispiel #19
0
    def _index(self):
        '''Actually do the autoindexing using the data prepared by the
    previous method.'''

        images_str = '%d to %d' % tuple(self._indxr_images[0])
        for i in self._indxr_images[1:]:
            images_str += ', %d to %d' % tuple(i)

        cell_str = None
        if self._indxr_input_cell:
            cell_str = '%.2f %.2f %.2f %.2f %.2f %.2f' % \
                       self._indxr_input_cell

        # then this is a proper autoindexing run - describe this
        # to the journal entry

        #if len(self._fp_directory) <= 50:
        #dirname = self._fp_directory
        #else:
        #dirname = '...%s' % self._fp_directory[-46:]
        dirname = self.get_directory()

        Journal.block(
            'autoindexing', self._indxr_sweep_name, 'XDS', {
                'images': images_str,
                'target cell': cell_str,
                'target lattice': self._indxr_input_lattice,
                'template': self.get_template(),
                'directory': dirname
            })

        self._index_remove_masked_regions()

        if self._i_or_ii is None:
            self._i_or_ii = self.decide_i_or_ii()
            Debug.write('Selecting I or II, chose %s' % self._i_or_ii)

        idxref = self.Idxref()

        for file in ['SPOT.XDS']:
            idxref.set_input_data_file(file, self._indxr_payload[file])

        # set the phi start etc correctly

        idxref.set_data_range(self._indxr_images[0][0],
                              self._indxr_images[0][1])
        idxref.set_background_range(self._indxr_images[0][0],
                                    self._indxr_images[0][1])

        if self._i_or_ii == 'i':
            blocks = self._index_select_images_i()
            for block in blocks[:1]:
                starting_frame = block[0]
                starting_angle = self.get_scan().get_angle_from_image_index(
                    starting_frame)

                idxref.set_starting_frame(starting_frame)
                idxref.set_starting_angle(starting_angle)

                idxref.add_spot_range(block[0], block[1])

            for block in blocks[1:]:
                idxref.add_spot_range(block[0], block[1])
        else:
            for block in self._indxr_images[:1]:
                starting_frame = block[0]
                starting_angle = self.get_scan().get_angle_from_image_index(
                    starting_frame)

                idxref.set_starting_frame(starting_frame)
                idxref.set_starting_angle(starting_angle)

                idxref.add_spot_range(block[0], block[1])

            for block in self._indxr_images[1:]:
                idxref.add_spot_range(block[0], block[1])

        # FIXME need to also be able to pass in the known unit
        # cell and lattice if already available e.g. from
        # the helper... indirectly

        if self._indxr_user_input_lattice:
            idxref.set_indexer_user_input_lattice(True)

        if self._indxr_input_lattice and self._indxr_input_cell:
            idxref.set_indexer_input_lattice(self._indxr_input_lattice)
            idxref.set_indexer_input_cell(self._indxr_input_cell)

            Debug.write('Set lattice: %s' % self._indxr_input_lattice)
            Debug.write('Set cell: %f %f %f %f %f %f' % \
                        self._indxr_input_cell)

            original_cell = self._indxr_input_cell
        elif self._indxr_input_lattice:
            idxref.set_indexer_input_lattice(self._indxr_input_lattice)
            original_cell = None
        else:
            original_cell = None

        # FIXED need to set the beam centre here - this needs to come
        # from the input .xinfo object or header, and be converted
        # to the XDS frame... done.

        #mosflm_beam_centre = self.get_beam_centre()
        #xds_beam_centre = beam_centre_mosflm_to_xds(
        #mosflm_beam_centre[0], mosflm_beam_centre[1], self.get_header())
        from dxtbx.serialize.xds import to_xds
        converter = to_xds(self.get_imageset())
        xds_beam_centre = converter.detector_origin

        idxref.set_beam_centre(xds_beam_centre[0], xds_beam_centre[1])

        # fixme need to check if the lattice, cell have been set already,
        # and if they have, pass these in as input to the indexing job.

        done = False

        while not done:
            try:
                done = idxref.run()

                # N.B. in here if the IDXREF step was being run in the first
                # pass done is FALSE however there should be a refined
                # P1 orientation matrix etc. available - so keep it!

            except XDSException as e:
                # inspect this - if we have complaints about not
                # enough reflections indexed, and we have a target
                # unit cell, and they are the same, well ignore it

                if 'solution is inaccurate' in str(e):
                    Debug.write('XDS complains solution inaccurate - ignoring')
                    done = idxref.continue_from_error()
                elif ('insufficient percentage (< 70%)' in str(e) or
                      'insufficient percentage (< 50%)' in str(e)) and \
                         original_cell:
                    done = idxref.continue_from_error()
                    lattice, cell, mosaic = \
                             idxref.get_indexing_solution()
                    # compare solutions
                    check = PhilIndex.params.xia2.settings.xds_check_cell_deviation
                    for j in range(3):
                        # allow two percent variation in unit cell length
                        if math.fabs((cell[j] - original_cell[j]) / \
                                     original_cell[j]) > 0.02 and check:
                            Debug.write('XDS unhappy and solution wrong')
                            raise e
                        # and two degree difference in angle
                        if math.fabs(cell[j + 3] - original_cell[j + 3]) \
                               > 2.0 and check:
                            Debug.write('XDS unhappy and solution wrong')
                            raise e
                    Debug.write('XDS unhappy but solution ok')
                elif 'insufficient percentage (< 70%)' in str(e) or \
                         'insufficient percentage (< 50%)' in str(e):
                    Debug.write('XDS unhappy but solution probably ok')
                    done = idxref.continue_from_error()
                else:
                    raise e

        FileHandler.record_log_file(
            '%s INDEX' % self.get_indexer_full_name(),
            os.path.join(self.get_working_directory(), 'IDXREF.LP'))

        for file in ['SPOT.XDS', 'XPARM.XDS']:
            self._indxr_payload[file] = idxref.get_output_data_file(file)

        # need to get the indexing solutions out somehow...

        self._indxr_other_lattice_cell = idxref.get_indexing_solutions()

        self._indxr_lattice, self._indxr_cell, self._indxr_mosaic = \
                             idxref.get_indexing_solution()

        import dxtbx
        from dxtbx.serialize.xds import to_crystal
        xparm_file = os.path.join(self.get_working_directory(), 'XPARM.XDS')
        models = dxtbx.load(xparm_file)
        crystal_model = to_crystal(xparm_file)

        from dxtbx.model import Experiment, ExperimentList
        experiment = Experiment(
            beam=models.get_beam(),
            detector=models.get_detector(),
            goniometer=models.get_goniometer(),
            scan=models.get_scan(),
            crystal=crystal_model,
            #imageset=self.get_imageset(),
        )

        experiment_list = ExperimentList([experiment])
        self.set_indexer_experiment_list(experiment_list)

        # I will want this later on to check that the lattice was ok
        self._idxref_subtree_problem = idxref.get_index_tree_problem()

        return
Beispiel #20
0
    def _index(self):
        """Actually do the autoindexing using the data prepared by the
        previous method."""

        images_str = "%d to %d" % tuple(self._indxr_images[0])
        for i in self._indxr_images[1:]:
            images_str += ", %d to %d" % tuple(i)

        cell_str = None
        if self._indxr_input_cell:
            cell_str = "%.2f %.2f %.2f %.2f %.2f %.2f" % self._indxr_input_cell

        # then this is a proper autoindexing run - describe this
        # to the journal entry

        dirname = self.get_directory()

        Journal.block(
            "autoindexing",
            self._indxr_sweep_name,
            "XDS",
            {
                "images": images_str,
                "target cell": cell_str,
                "target lattice": self._indxr_input_lattice,
                "template": self.get_template(),
                "directory": dirname,
            },
        )

        idxref = self.Idxref()

        self._index_remove_masked_regions()
        for file in ["SPOT.XDS"]:
            idxref.set_input_data_file(file, self._indxr_payload[file])

        # edit SPOT.XDS to remove reflections in untrusted regions of the detector

        idxref.set_data_range(self._indxr_images[0][0],
                              self._indxr_images[0][1])
        idxref.set_background_range(self._indxr_images[0][0],
                                    self._indxr_images[0][1])

        # set the phi start etc correctly

        for block in self._indxr_images[:1]:
            starting_frame = block[0]
            starting_angle = self.get_scan().get_angle_from_image_index(
                starting_frame)

            idxref.set_starting_frame(starting_frame)
            idxref.set_starting_angle(starting_angle)

            idxref.add_spot_range(block[0], block[1])

        for block in self._indxr_images[1:]:
            idxref.add_spot_range(block[0], block[1])

        if self._indxr_user_input_lattice:
            idxref.set_indexer_user_input_lattice(True)

        if self._indxr_input_lattice and self._indxr_input_cell:
            idxref.set_indexer_input_lattice(self._indxr_input_lattice)
            idxref.set_indexer_input_cell(self._indxr_input_cell)

            Debug.write("Set lattice: %s" % self._indxr_input_lattice)
            Debug.write("Set cell: %f %f %f %f %f %f" % self._indxr_input_cell)

            original_cell = self._indxr_input_cell
        elif self._indxr_input_lattice:
            idxref.set_indexer_input_lattice(self._indxr_input_lattice)
            original_cell = None
        else:
            original_cell = None

        from dxtbx.serialize.xds import to_xds

        converter = to_xds(self.get_imageset())
        xds_beam_centre = converter.detector_origin

        idxref.set_beam_centre(xds_beam_centre[0], xds_beam_centre[1])

        # fixme need to check if the lattice, cell have been set already,
        # and if they have, pass these in as input to the indexing job.

        done = False

        while not done:
            try:
                done = idxref.run()

                # N.B. in here if the IDXREF step was being run in the first
                # pass done is FALSE however there should be a refined
                # P1 orientation matrix etc. available - so keep it!

            except XDSException as e:
                # inspect this - if we have complaints about not
                # enough reflections indexed, and we have a target
                # unit cell, and they are the same, well ignore it

                if "solution is inaccurate" in str(e):
                    Debug.write("XDS complains solution inaccurate - ignoring")
                    done = idxref.continue_from_error()
                elif ("insufficient percentage (< 70%)" in str(e)
                      or "insufficient percentage (< 50%)"
                      in str(e)) and original_cell:
                    done = idxref.continue_from_error()
                    lattice, cell, mosaic = idxref.get_indexing_solution()
                    # compare solutions FIXME should use xds_cell_deviation
                    check = PhilIndex.params.xia2.settings.xds_check_cell_deviation
                    for j in range(3):
                        # allow two percent variation in unit cell length
                        if (math.fabs(
                            (cell[j] - original_cell[j]) / original_cell[j]) >
                                0.02 and check):
                            Debug.write("XDS unhappy and solution wrong")
                            raise e
                        # and two degree difference in angle
                        if (math.fabs(cell[j + 3] - original_cell[j + 3]) > 2.0
                                and check):
                            Debug.write("XDS unhappy and solution wrong")
                            raise e
                    Debug.write("XDS unhappy but solution ok")
                elif "insufficient percentage (< 70%)" in str(
                        e) or "insufficient percentage (< 50%)" in str(e):
                    Debug.write("XDS unhappy but solution probably ok")
                    done = idxref.continue_from_error()
                else:
                    raise e

        FileHandler.record_log_file(
            "%s INDEX" % self.get_indexer_full_name(),
            os.path.join(self.get_working_directory(), "IDXREF.LP"),
        )

        for file in ["SPOT.XDS", "XPARM.XDS"]:
            self._indxr_payload[file] = idxref.get_output_data_file(file)

        # need to get the indexing solutions out somehow...

        self._indxr_other_lattice_cell = idxref.get_indexing_solutions()

        self._indxr_lattice, self._indxr_cell, self._indxr_mosaic = (
            idxref.get_indexing_solution())

        import dxtbx
        from dxtbx.serialize.xds import to_crystal

        xparm_file = os.path.join(self.get_working_directory(), "XPARM.XDS")
        models = dxtbx.load(xparm_file)
        crystal_model = to_crystal(xparm_file)

        from dxtbx.model import Experiment, ExperimentList

        experiment = Experiment(
            beam=models.get_beam(),
            detector=models.get_detector(),
            goniometer=models.get_goniometer(),
            scan=models.get_scan(),
            crystal=crystal_model,
            # imageset=self.get_imageset(),
        )

        experiment_list = ExperimentList([experiment])
        self.set_indexer_experiment_list(experiment_list)

        # I will want this later on to check that the lattice was ok
        self._idxref_subtree_problem = idxref.get_index_tree_problem()

        return
Beispiel #21
0
    def _index(self):
        """Actually do the autoindexing using the data prepared by the
        previous method."""

        self._index_remove_masked_regions()

        if self._i_or_ii is None:
            self._i_or_ii = self.decide_i_or_ii()
            logger.debug("Selecting I or II, chose %s", self._i_or_ii)

        idxref = self.Idxref()

        for file in ["SPOT.XDS"]:
            idxref.set_input_data_file(file, self._indxr_payload[file])

        # set the phi start etc correctly

        idxref.set_data_range(self._indxr_images[0][0],
                              self._indxr_images[0][1])
        idxref.set_background_range(self._indxr_images[0][0],
                                    self._indxr_images[0][1])

        if self._i_or_ii == "i":
            blocks = self._index_select_images_i()
            for block in blocks[:1]:
                starting_frame = block[0]
                starting_angle = self.get_scan().get_angle_from_image_index(
                    starting_frame)

                idxref.set_starting_frame(starting_frame)
                idxref.set_starting_angle(starting_angle)

                idxref.add_spot_range(block[0], block[1])

            for block in blocks[1:]:
                idxref.add_spot_range(block[0], block[1])
        else:
            for block in self._indxr_images[:1]:
                starting_frame = block[0]
                starting_angle = self.get_scan().get_angle_from_image_index(
                    starting_frame)

                idxref.set_starting_frame(starting_frame)
                idxref.set_starting_angle(starting_angle)

                idxref.add_spot_range(block[0], block[1])

            for block in self._indxr_images[1:]:
                idxref.add_spot_range(block[0], block[1])

        # FIXME need to also be able to pass in the known unit
        # cell and lattice if already available e.g. from
        # the helper... indirectly

        if self._indxr_user_input_lattice:
            idxref.set_indexer_user_input_lattice(True)

        if self._indxr_input_lattice and self._indxr_input_cell:
            idxref.set_indexer_input_lattice(self._indxr_input_lattice)
            idxref.set_indexer_input_cell(self._indxr_input_cell)

            logger.debug("Set lattice: %s", self._indxr_input_lattice)
            logger.debug("Set cell: %f %f %f %f %f %f" %
                         self._indxr_input_cell)

            original_cell = self._indxr_input_cell
        elif self._indxr_input_lattice:
            idxref.set_indexer_input_lattice(self._indxr_input_lattice)
            original_cell = None
        else:
            original_cell = None

        # FIXED need to set the beam centre here - this needs to come
        # from the input .xinfo object or header, and be converted
        # to the XDS frame... done.

        from dxtbx.serialize.xds import to_xds

        converter = to_xds(self.get_imageset())
        xds_beam_centre = converter.detector_origin

        idxref.set_beam_centre(xds_beam_centre[0], xds_beam_centre[1])

        # fixme need to check if the lattice, cell have been set already,
        # and if they have, pass these in as input to the indexing job.

        done = False

        while not done:
            try:
                done = idxref.run()

                # N.B. in here if the IDXREF step was being run in the first
                # pass done is FALSE however there should be a refined
                # P1 orientation matrix etc. available - so keep it!

            except XDSException as e:
                # inspect this - if we have complaints about not
                # enough reflections indexed, and we have a target
                # unit cell, and they are the same, well ignore it

                if "solution is inaccurate" in str(e):
                    logger.debug(
                        "XDS complains solution inaccurate - ignoring")
                    done = idxref.continue_from_error()
                elif ("insufficient percentage (< 70%)" in str(e)
                      or "insufficient percentage (< 50%)"
                      in str(e)) and original_cell:
                    done = idxref.continue_from_error()
                    lattice, cell, mosaic = idxref.get_indexing_solution()
                    # compare solutions
                    check = PhilIndex.params.xia2.settings.xds_check_cell_deviation
                    for j in range(3):
                        # allow two percent variation in unit cell length
                        if (math.fabs(
                            (cell[j] - original_cell[j]) / original_cell[j]) >
                                0.02 and check):
                            logger.debug("XDS unhappy and solution wrong")
                            raise e
                        # and two degree difference in angle
                        if (math.fabs(cell[j + 3] - original_cell[j + 3]) > 2.0
                                and check):
                            logger.debug("XDS unhappy and solution wrong")
                            raise e
                    logger.debug("XDS unhappy but solution ok")
                elif "insufficient percentage (< 70%)" in str(
                        e) or "insufficient percentage (< 50%)" in str(e):
                    logger.debug("XDS unhappy but solution probably ok")
                    done = idxref.continue_from_error()
                else:
                    raise e

        FileHandler.record_log_file(
            "%s INDEX" % self.get_indexer_full_name(),
            os.path.join(self.get_working_directory(), "IDXREF.LP"),
        )

        for file in ["SPOT.XDS", "XPARM.XDS"]:
            self._indxr_payload[file] = idxref.get_output_data_file(file)

        # need to get the indexing solutions out somehow...

        self._indxr_other_lattice_cell = idxref.get_indexing_solutions()

        (
            self._indxr_lattice,
            self._indxr_cell,
            self._indxr_mosaic,
        ) = idxref.get_indexing_solution()

        xparm_file = os.path.join(self.get_working_directory(), "XPARM.XDS")
        models = dxtbx.load(xparm_file)
        crystal_model = to_crystal(xparm_file)

        # this information gets lost when re-creating the models from the
        # XDS results - however is not refined so can simply copy from the
        # input - https://github.com/xia2/xia2/issues/372
        models.get_detector()[0].set_thickness(
            converter.get_detector()[0].get_thickness())

        experiment = Experiment(
            beam=models.get_beam(),
            detector=models.get_detector(),
            goniometer=models.get_goniometer(),
            scan=models.get_scan(),
            crystal=crystal_model,
            # imageset=self.get_imageset(),
        )

        experiment_list = ExperimentList([experiment])
        self.set_indexer_experiment_list(experiment_list)

        # I will want this later on to check that the lattice was ok
        self._idxref_subtree_problem = idxref.get_index_tree_problem()
def test_to_xds(dials_regression, tmpdir):
    tmpdir.chdir()
    template = os.path.join(dials_regression, "centroid_test_data", "centroid_00*.cbf")
    file_names = glob.glob(template)
    sweep = ImageSetFactory.new(file_names)[0]
    to_xds = xds.to_xds(sweep)
    s1 = to_xds.XDS_INP()
    expected = """\
DETECTOR=PILATUS MINIMUM_VALID_PIXEL_VALUE=0 OVERLOAD=495976
SENSOR_THICKNESS= 0.320
!SENSOR_MATERIAL / THICKNESS Si 0.320
!SILICON= 3.960382
DIRECTION_OF_DETECTOR_X-AXIS= 1.00000 0.00000 0.00000
DIRECTION_OF_DETECTOR_Y-AXIS= 0.00000 1.00000 0.00000
NX=2463 NY=2527 QX=0.1720 QY=0.1720
DETECTOR_DISTANCE= 190.180000
ORGX= 1235.84 ORGY= 1279.58
ROTATION_AXIS= 1.00000 0.00000 0.00000
STARTING_ANGLE= 0.000
OSCILLATION_RANGE= 0.200
X-RAY_WAVELENGTH= 0.97950
INCIDENT_BEAM_DIRECTION= -0.000 -0.000 1.021
FRACTION_OF_POLARIZATION= 0.999
POLARIZATION_PLANE_NORMAL= 0.000 1.000 0.000
NAME_TEMPLATE_OF_DATA_FRAMES= %s
TRUSTED_REGION= 0.0 1.41
UNTRUSTED_RECTANGLE= 487 495 0 2528
UNTRUSTED_RECTANGLE= 981 989 0 2528
UNTRUSTED_RECTANGLE= 1475 1483 0 2528
UNTRUSTED_RECTANGLE= 1969 1977 0 2528
UNTRUSTED_RECTANGLE= 0 2464 195 213
UNTRUSTED_RECTANGLE= 0 2464 407 425
UNTRUSTED_RECTANGLE= 0 2464 619 637
UNTRUSTED_RECTANGLE= 0 2464 831 849
UNTRUSTED_RECTANGLE= 0 2464 1043 1061
UNTRUSTED_RECTANGLE= 0 2464 1255 1273
UNTRUSTED_RECTANGLE= 0 2464 1467 1485
UNTRUSTED_RECTANGLE= 0 2464 1679 1697
UNTRUSTED_RECTANGLE= 0 2464 1891 1909
UNTRUSTED_RECTANGLE= 0 2464 2103 2121
UNTRUSTED_RECTANGLE= 0 2464 2315 2333
DATA_RANGE= 1 9
JOB=XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT\
""" % os.path.join(
        dials_regression, "centroid_test_data", "centroid_????.cbf"
    )
    assert s1 == expected
    real_space_a = (-5.327642, -39.034747, -4.988286)
    real_space_b = (-35.253495, 7.596265, -22.127661)
    real_space_c = (-22.673623, -1.486119, 35.793463)
    s2 = to_xds.xparm_xds(real_space_a, real_space_b, real_space_c, space_group=1)
    # run coordinate frame converter on xparm.xds as a sanity check
    with open("xparm.xds", mode="wb") as fh:
        fh.write(s2.encode("ASCII"))
    from rstbx.cftbx import coordinate_frame_helpers

    converter = coordinate_frame_helpers.import_xds_xparm("xparm.xds")
    detector = sweep.get_detector()
    goniometer = sweep.get_goniometer()
    beam = sweep.get_beam()
    assert approx_equal(real_space_a, converter.get_real_space_a())
    assert approx_equal(real_space_b, converter.get_real_space_b())
    assert approx_equal(real_space_c, converter.get_real_space_c())
    assert approx_equal(goniometer.get_rotation_axis(), converter.get_rotation_axis())
    assert approx_equal(beam.get_direction(), converter.get_sample_to_source().elems)
    assert approx_equal(detector[0].get_fast_axis(), converter.get_detector_fast())
    assert approx_equal(detector[0].get_slow_axis(), converter.get_detector_slow())
    assert approx_equal(detector[0].get_origin(), converter.get_detector_origin())
Beispiel #23
0
Datei: XDS.py Projekt: xia2/xia2
def imageset_to_xds(imageset, synchrotron = None, refined_beam_vector = None,
                    refined_rotation_axis = None, refined_distance = None):
  '''A function to take an input header dictionary from Diffdump
  and generate a list of records to start XDS - see Doc/INP.txt.'''

  # decide if we are at a synchrotron if we don't know already...
  # that is, the wavelength is around either the Copper or Chromium
  # K-alpha edge and this is an image plate.

  beam = imageset.get_beam()

  from dxtbx.serialize.xds import to_xds, xds_detector_name
  converter = to_xds(imageset)

  detector_class_is_square = {
      'adsc q4':True,
      'adsc q4 2x2 binned':True,
      'adsc q210':True,
      'adsc q210 2x2 binned':True,
      'adsc q270':True,
      'adsc q270 2x2 binned':True,
      'adsc q315':True,
      'adsc q315 2x2 binned':True,
      'adsc HF4M':True,
      'holton fake 01':True,
      'mar 345':False,
      'mar 180':False,
      'mar 240':False,
      'mar 300 ccd':True,
      'mar 325 ccd':True,
      'mar 225 ccd':True,
      'mar ccd 225 hs':True,
      'rayonix ccd 165':False,
      'rayonix ccd 135':False,
      'rayonix ccd 300':True,
      'rayonix ccd 325':True,
      'rayonix ccd 225':True,
      'rayonix ccd 225 hs':True,
      'rayonix ccd 300 hs':True,
      'mar 165 ccd':False,
      'mar 135 ccd':False,
      'pilatus 12M':True,
      'pilatus 6M':True,
      'pilatus 2M':True,
      'pilatus 1M':True,
      'pilatus 200K':True,
      'pilatus 300K':True,
      'eiger 4M':True,
      'eiger 9M':True,
      'eiger 16M':True,
      'rigaku saturn 92 2x2 binned':True,
      'rigaku saturn 944 2x2 binned':True,
      'rigaku saturn 724 2x2 binned':True,
      'rigaku saturn 92':True,
      'rigaku saturn 944':True,
      'rigaku saturn 724':True,
      'rigaku saturn a200':True,
      'raxis IV':True,
      'NOIR1':True}

  sensor = converter.get_detector()[0].get_type()
  fast, slow = converter.detector_size
  f, s = converter.pixel_size
  df = int(1000 * f)
  ds = int(1000 * s)

  # FIXME probably need to rotate by pi about the X axis

  result = []

  from dxtbx.model.detector_helpers_types import detector_helpers_types
  detector = xds_detector_name(
      detector_helpers_types.get(sensor, fast, slow, df, ds))
  trusted = converter.get_detector()[0].get_trusted_range()

  # FIXME what follows below should perhaps be 0 for the really weak
  # pilatus data sets?

  result.append('DETECTOR=%s MINIMUM_VALID_PIXEL_VALUE=%d OVERLOAD=%d' %
                (detector, trusted[0] + 1, trusted[1]))

  result.append('DIRECTION_OF_DETECTOR_X-AXIS=%f %f %f' %
                converter.detector_x_axis)

  result.append('DIRECTION_OF_DETECTOR_Y-AXIS=%f %f %f' %
                converter.detector_y_axis)

  from xia2.Handlers.Phil import PhilIndex
  params = PhilIndex.get_python_object()
  if params.xds.trusted_region:
    result.append(
      'TRUSTED_REGION= %.2f %.2f' % tuple(params.xds.trusted_region))
  elif detector_class_is_square[
    detector_helpers_types.get(sensor, fast, slow, df, ds).replace('-', ' ')]:
    result.append('TRUSTED_REGION=0.0 1.41')
  else:
    result.append('TRUSTED_REGION=0.0 0.99')

  result.append('NX=%d NY=%d QX=%.4f QY=%.4f' % (fast, slow, f, s))

  # RAXIS detectors have the distance written negative - why????
  # this is ONLY for XDS - SATURN are the same - probably left handed
  # goniometer rotation on rigaku X-ray sets.

  if refined_distance:
    result.append('DETECTOR_DISTANCE=%7.3f' % refined_distance)
  else:
    result.append('DETECTOR_DISTANCE=%7.3f' % converter.detector_distance)

  result.append('OSCILLATION_RANGE=%4.2f' % converter.oscillation_range)
  result.append('X-RAY_WAVELENGTH=%8.6f' % converter.wavelength)

  # if user specified reversephi and this was not picked up in the
  # format class reverse phi: n.b. double-negative warning!

  if refined_rotation_axis:
    result.append('ROTATION_AXIS= %f %f %f' % \
                  refined_rotation_axis)
  else:
    result.append('ROTATION_AXIS= %.3f %.3f %.3f' % \
                  converter.rotation_axis)

  if refined_beam_vector:
    result.append('INCIDENT_BEAM_DIRECTION=%f %f %f' % \
                  refined_beam_vector)
  else:
    result.append(
      'INCIDENT_BEAM_DIRECTION= %.3f %.3f %.3f' % converter.beam_vector)

  if hasattr(beam, "get_polarization_fraction"):
    R = converter.imagecif_to_xds_transformation_matrix
    result.append('FRACTION_OF_POLARIZATION= %.3f' %
                  beam.get_polarization_fraction())
    result.append('POLARIZATION_PLANE_NORMAL= %.3f %.3f %.3f' %
                  (R * matrix.col(beam.get_polarization_normal())).elems)

  # 24/NOV/14 XDS determines the air absorption automatically
  # based on wavelength. May be useful to override this for in vacuo exps
  # result.append('AIR=0.001')

  if detector == 'PILATUS':
    try:
      thickness = converter.get_detector()[0].get_thickness()
      if not thickness:
        thickness = 0.32
        Debug.write('Could not determine sensor thickness. Assuming default PILATUS 0.32mm')
    except e:
      thickness = 0.32
      Debug.write('Error occured during sensor thickness determination. Assuming default PILATUS 0.32mm')
    result.append('SENSOR_THICKNESS=%f' % thickness)

  #  # FIXME: Sensor absorption coefficient calculation probably requires a more general solution
  #  if converter.get_detector()[0].get_material() == 'CdTe':
  #    print "CdTe detector detected. Beam wavelength is %8.6f Angstrom" % converter.wavelength

  if len(converter.panel_x_axis) > 1:
    for panel_id in range(len(converter.panel_x_axis)):

      result.append('')
      result.append('!')
      result.append('! SEGMENT %d' %(panel_id+1))
      result.append('!')
      result.append('SEGMENT= %d %d %d %d' % converter.panel_limits[panel_id])
      result.append('DIRECTION_OF_SEGMENT_X-AXIS= %.3f %.3f %.3f' % \
            converter.panel_x_axis[panel_id])
      result.append('DIRECTION_OF_SEGMENT_Y-AXIS= %.3f %.3f %.3f' % \
            converter.panel_y_axis[panel_id])
      result.append('SEGMENT_DISTANCE= %.3f' % converter.panel_distance[panel_id])
      result.append(
        'SEGMENT_ORGX= %.1f SEGMENT_ORGY= %.1f' % converter.panel_origin[panel_id])
      result.append('')

  for f0, s0, f1, s1 in converter.get_detector()[0].get_mask():
    result.append('UNTRUSTED_RECTANGLE= %d %d %d %d' %
                  (f0 - 1, f1 + 1, s0 - 1, s1 + 1))

  if params.xds.untrusted_ellipse:
    for untrusted_ellipse in params.xds.untrusted_ellipse:
      result.append(
        'UNTRUSTED_ELLIPSE= %d %d %d %d' % tuple(untrusted_ellipse))
    Debug.write(result[-1])

  if params.xds.untrusted_rectangle:
    for untrusted_rectangle in params.xds.untrusted_rectangle:
      result.append(
        'UNTRUSTED_RECTANGLE= %d %d %d %d' % tuple(untrusted_rectangle))
    Debug.write(result[-1])

  return result
Beispiel #24
0
  def _index_prepare(self):
    '''Prepare to do autoindexing - in XDS terms this will mean
    calling xycorr, init and colspot on the input images.'''

    # decide on images to work with

    Debug.write('XDS INDEX PREPARE:')
    Debug.write('Wavelength: %.6f' % self.get_wavelength())
    Debug.write('Distance: %.2f' % self.get_distance())

    if self._indxr_images == []:
      _select_images_function = getattr(
          self, '_index_select_images_%s' % (self._index_select_images))
      wedges = _select_images_function()
      for wedge in wedges:
        self.add_indexer_image_wedge(wedge)
      self.set_indexer_prepare_done(True)

    all_images = self.get_matching_images()

    first = min(all_images)
    last = max(all_images)

    # next start to process these - first xycorr

    xycorr = self.Xycorr()

    xycorr.set_data_range(first, last)
    xycorr.set_background_range(self._indxr_images[0][0],
                                self._indxr_images[0][1])
    from dxtbx.serialize.xds import to_xds
    converter = to_xds(self.get_imageset())
    xds_beam_centre = converter.detector_origin
    xycorr.set_beam_centre(xds_beam_centre[0],
                           xds_beam_centre[1])
    for block in self._indxr_images:
      xycorr.add_spot_range(block[0], block[1])

    # FIXME need to set the origin here

    xycorr.run()

    for file in ['X-CORRECTIONS.cbf',
                 'Y-CORRECTIONS.cbf']:
      self._indxr_payload[file] = xycorr.get_output_data_file(file)

    # next start to process these - then init

    if PhilIndex.params.xia2.settings.input.format.dynamic_shadowing:
      # find the region of the scan with the least predicted shadow
      # to use for background determination in XDS INIT step
      from dxtbx.serialize import dump
      from dxtbx.datablock import DataBlock
      imageset = self._indxr_imagesets[0]
      xsweep = self._indxr_sweeps[0]
      sweep_filename = os.path.join(
        self.get_working_directory(), '%s_datablock.json' %xsweep.get_name())
      dump.datablock(DataBlock([imageset]), sweep_filename)

      from xia2.Wrappers.Dials.ShadowPlot import ShadowPlot
      shadow_plot = ShadowPlot()
      shadow_plot.set_working_directory(self.get_working_directory())
      auto_logfiler(shadow_plot)
      shadow_plot.set_sweep_filename(sweep_filename)
      shadow_plot.set_json_filename(
        os.path.join(
          self.get_working_directory(),
          '%s_shadow_plot.json' %shadow_plot.get_xpid()))
      shadow_plot.run()
      results = shadow_plot.get_results()
      from scitbx.array_family import flex
      fraction_shadowed = flex.double(results['fraction_shadowed'])
      scan_points = flex.double(results['scan_points'])

      phi_width = self.get_phi_width()
      scan = imageset.get_scan()
      oscillation_range = scan.get_oscillation_range()
      oscillation = scan.get_oscillation()
      bg_images = self._background_images
      bg_range_deg = (scan.get_angle_from_image_index(bg_images[0]),
                      scan.get_angle_from_image_index(bg_images[1]))
      bg_range_width = bg_range_deg[1] - bg_range_deg[0]

      min_shadow = 100
      best_bg_range = bg_range_deg
      from libtbx.utils import frange
      for bg_range_start in frange(flex.min(scan_points), flex.max(scan_points) - bg_range_width, step=oscillation[1]):
        bg_range_deg = (bg_range_start, bg_range_start + bg_range_width)
        sel = (scan_points >= bg_range_deg[0]) & (scan_points <= bg_range_deg[1])
        mean_shadow = flex.mean(fraction_shadowed.select(sel))
        if mean_shadow < min_shadow:
          min_shadow = mean_shadow
          best_bg_range = bg_range_deg

      self._background_images = (
        scan.get_image_index_from_angle(best_bg_range[0]),
        scan.get_image_index_from_angle(best_bg_range[1]))
      Debug.write('Setting background images: %s -> %s' %self._background_images)

    init = self.Init()

    for file in ['X-CORRECTIONS.cbf',
                 'Y-CORRECTIONS.cbf']:
      init.set_input_data_file(file, self._indxr_payload[file])

    init.set_data_range(first, last)

    if self._background_images:
      init.set_background_range(self._background_images[0],
                                self._background_images[1])
    else:
      init.set_background_range(self._indxr_images[0][0],
                                self._indxr_images[0][1])

    for block in self._indxr_images:
      init.add_spot_range(block[0], block[1])

    init.run()

    # at this stage, need to (perhaps) modify the BKGINIT.cbf image
    # to mark out the back stop

    if PhilIndex.params.general.backstop_mask:
      Debug.write('Applying mask to BKGINIT.pck')

      # copy the original file
      cbf_old = os.path.join(init.get_working_directory(),
                             'BKGINIT.cbf')
      cbf_save = os.path.join(init.get_working_directory(),
                              'BKGINIT.sav')
      shutil.copyfile(cbf_old, cbf_save)

      # modify the file to give the new mask
      from xia2.Toolkit.BackstopMask import BackstopMask
      mask = BackstopMask(PhilIndex.params.general.backstop_mask)
      mask.apply_mask_xds(self.get_header(), cbf_save, cbf_old)

      init.reload()

    for file in ['BLANK.cbf',
                 'BKGINIT.cbf',
                 'GAIN.cbf']:
      self._indxr_payload[file] = init.get_output_data_file(file)

    if PhilIndex.params.xia2.settings.developmental.use_dials_spotfinder:

      spotfinder = self.DialsSpotfinder()

      for block in self._indxr_images:
        spotfinder.add_spot_range(block[0], block[1])

      spotfinder.run()
      export = self.DialsExportSpotXDS()
      export.set_input_data_file(
          'reflections.pickle',
          spotfinder.get_output_data_file('reflections.pickle'))
      export.run()

      for file in ['SPOT.XDS']:
        self._indxr_payload[file] = export.get_output_data_file(file)

    else:

      # next start to process these - then colspot

      colspot = self.Colspot()

      for file in ['X-CORRECTIONS.cbf',
                   'Y-CORRECTIONS.cbf',
                   'BLANK.cbf',
                   'BKGINIT.cbf',
                   'GAIN.cbf']:
        colspot.set_input_data_file(file, self._indxr_payload[file])

      colspot.set_data_range(first, last)
      colspot.set_background_range(self._indxr_images[0][0],
                                   self._indxr_images[0][1])
      for block in self._indxr_images:
        colspot.add_spot_range(block[0], block[1])

      colspot.run()

      for file in ['SPOT.XDS']:
        self._indxr_payload[file] = colspot.get_output_data_file(file)

    # that should be everything prepared... all of the important
    # files should be loaded into memory to be able to cope with
    # integration happening somewhere else

    return
Beispiel #25
0
  def _index(self):
    '''Actually do the autoindexing using the data prepared by the
    previous method.'''

    images_str = '%d to %d' % tuple(self._indxr_images[0])
    for i in self._indxr_images[1:]:
      images_str += ', %d to %d' % tuple(i)

    cell_str = None
    if self._indxr_input_cell:
      cell_str = '%.2f %.2f %.2f %.2f %.2f %.2f' % \
                 self._indxr_input_cell

    # then this is a proper autoindexing run - describe this
    # to the journal entry

    dirname = self.get_directory()

    Journal.block('autoindexing', self._indxr_sweep_name, 'XDS',
                  {'images':images_str,
                   'target cell':cell_str,
                   'target lattice':self._indxr_input_lattice,
                   'template':self.get_template(),
                   'directory':dirname})

    idxref = self.Idxref()

    self._index_remove_masked_regions()
    for file in ['SPOT.XDS']:
      idxref.set_input_data_file(file, self._indxr_payload[file])

    # edit SPOT.XDS to remove reflections in untrusted regions of the detector

    idxref.set_data_range(self._indxr_images[0][0],
                          self._indxr_images[0][1])
    idxref.set_background_range(self._indxr_images[0][0],
                                self._indxr_images[0][1])

    # set the phi start etc correctly

    for block in self._indxr_images[:1]:
      starting_frame = block[0]
      starting_angle = self.get_scan().get_angle_from_image_index(starting_frame)

      idxref.set_starting_frame(starting_frame)
      idxref.set_starting_angle(starting_angle)

      idxref.add_spot_range(block[0], block[1])

    for block in self._indxr_images[1:]:
      idxref.add_spot_range(block[0], block[1])

    if self._indxr_user_input_lattice:
      idxref.set_indexer_user_input_lattice(True)

    if self._indxr_input_lattice and self._indxr_input_cell:
      idxref.set_indexer_input_lattice(self._indxr_input_lattice)
      idxref.set_indexer_input_cell(self._indxr_input_cell)

      Debug.write('Set lattice: %s' % self._indxr_input_lattice)
      Debug.write('Set cell: %f %f %f %f %f %f' % \
                  self._indxr_input_cell)

      original_cell = self._indxr_input_cell
    elif self._indxr_input_lattice:
      idxref.set_indexer_input_lattice(self._indxr_input_lattice)
      original_cell = None
    else:
      original_cell = None

    from dxtbx.serialize.xds import to_xds
    converter = to_xds(self.get_imageset())
    xds_beam_centre = converter.detector_origin

    idxref.set_beam_centre(xds_beam_centre[0],
                           xds_beam_centre[1])

    # fixme need to check if the lattice, cell have been set already,
    # and if they have, pass these in as input to the indexing job.

    done = False

    while not done:
      try:
        done = idxref.run()

        # N.B. in here if the IDXREF step was being run in the first
        # pass done is FALSE however there should be a refined
        # P1 orientation matrix etc. available - so keep it!

      except XDSException, e:
        # inspect this - if we have complaints about not
        # enough reflections indexed, and we have a target
        # unit cell, and they are the same, well ignore it

        if 'solution is inaccurate' in str(e):
          Debug.write(
              'XDS complains solution inaccurate - ignoring')
          done = idxref.continue_from_error()
        elif ('insufficient percentage (< 70%)' in str(e) or
              'insufficient percentage (< 50%)' in str(e)) and \
                 original_cell:
          done = idxref.continue_from_error()
          lattice, cell, mosaic = \
                   idxref.get_indexing_solution()
          # compare solutions FIXME should use xds_cell_deviation
          check = PhilIndex.params.xia2.settings.xds_check_cell_deviation
          for j in range(3):
            # allow two percent variation in unit cell length
            if math.fabs((cell[j] - original_cell[j]) / \
                         original_cell[j]) > 0.02 and check:
              Debug.write('XDS unhappy and solution wrong')
              raise e
            # and two degree difference in angle
            if math.fabs(cell[j + 3] - original_cell[j + 3]) \
                   > 2.0 and check:
              Debug.write('XDS unhappy and solution wrong')
              raise e
          Debug.write('XDS unhappy but solution ok')
        elif 'insufficient percentage (< 70%)' in str(e) or \
                 'insufficient percentage (< 50%)' in str(e):
          Debug.write('XDS unhappy but solution probably ok')
          done = idxref.continue_from_error()
        else:
          raise e
Beispiel #26
0
def imageset_to_xds(
    imageset,
    synchrotron=None,
    refined_beam_vector=None,
    refined_rotation_axis=None,
    refined_distance=None,
):
    """A function to take an input header dictionary from Diffdump
    and generate a list of records to start XDS - see Doc/INP.txt."""

    # decide if we are at a synchrotron if we don't know already...
    # that is, the wavelength is around either the Copper or Chromium
    # K-alpha edge and this is an image plate.

    beam = imageset.get_beam()

    from dxtbx.serialize.xds import to_xds, xds_detector_name

    converter = to_xds(imageset)

    h5_names = ["h5", "nxs"]
    if imageset.get_template().split(".")[-1] in h5_names:
        if not check_xds_ok_with_h5():
            raise RuntimeError("HDF5 input with no converter for XDS")

    detector_class_is_square = {
        "adsc q4": True,
        "adsc q4 2x2 binned": True,
        "adsc q210": True,
        "adsc q210 2x2 binned": True,
        "adsc q270": True,
        "adsc q270 2x2 binned": True,
        "adsc q315": True,
        "adsc q315 2x2 binned": True,
        "adsc HF4M": True,
        "holton fake 01": True,
        "unknown electron 57": True,
        "mar 345": False,
        "mar 180": False,
        "mar 240": False,
        "mar 300 ccd": True,
        "mar 325 ccd": True,
        "mar 225 ccd": True,
        "mar ccd 225 hs": True,
        "rayonix ccd 165": False,
        "rayonix ccd 135": False,
        "rayonix ccd 300": True,
        "rayonix ccd 325": True,
        "rayonix ccd 225": True,
        "rayonix ccd 225 hs": True,
        "rayonix ccd 300 hs": True,
        "mar 165 ccd": False,
        "mar 135 ccd": False,
        "pilatus 12M": True,
        "pilatus 6M": True,
        "pilatus 2M": True,
        "pilatus 1M": True,
        "pilatus 200K": True,
        "pilatus 300K": True,
        "eiger 4M": True,
        "eiger 9M": True,
        "eiger 16M": True,
        "rigaku saturn 92 2x2 binned": True,
        "rigaku saturn 944 2x2 binned": True,
        "rigaku saturn 724 2x2 binned": True,
        "rigaku saturn 92": True,
        "rigaku saturn 944": True,
        "rigaku saturn 724": True,
        "rigaku saturn a200": True,
        "raxis IV": True,
        "NOIR1": True,
    }

    sensor = converter.get_detector()[0].get_type()
    fast, slow = converter.detector_size
    f, s = converter.pixel_size
    df = int(1000 * f)
    ds = int(1000 * s)

    # FIXME probably need to rotate by pi about the X axis

    result = []

    from dxtbx.model.detector_helpers_types import detector_helpers_types

    detector = xds_detector_name(
        detector_helpers_types.get(sensor, fast, slow, df, ds))
    trusted = converter.get_detector()[0].get_trusted_range()

    # if CCD; undo dxtbx pedestal offset, hard code minimum 1; else use trusted
    # range verbatim (i.e. for PAD) (later in pipeline sensor is SENSOR_UNKNOWN
    # so additional test)

    if sensor == "SENSOR_CCD" or detector == "CCDCHESS":
        trusted = 1, trusted[1] - trusted[0]

    # XDS upset if we trust < 0 see #193
    if trusted[0] < 0:
        trusted = 0, trusted[1]

    result.append("DETECTOR=%s MINIMUM_VALID_PIXEL_VALUE=%d OVERLOAD=%d" %
                  (detector, trusted[0], trusted[1]))

    result.append("DIRECTION_OF_DETECTOR_X-AXIS=%f %f %f" %
                  converter.detector_x_axis)

    result.append("DIRECTION_OF_DETECTOR_Y-AXIS=%f %f %f" %
                  converter.detector_y_axis)

    from xia2.Handlers.Phil import PhilIndex

    params = PhilIndex.get_python_object()
    if params.xds.trusted_region:
        result.append("TRUSTED_REGION= %.2f %.2f" %
                      tuple(params.xds.trusted_region))
    elif detector_class_is_square[detector_helpers_types.get(
            sensor, fast, slow, df, ds).replace("-", " ")]:
        result.append("TRUSTED_REGION=0.0 1.41")
    else:
        result.append("TRUSTED_REGION=0.0 0.99")

    result.append("NX=%d NY=%d QX=%.4f QY=%.4f" % (fast, slow, f, s))

    # RAXIS detectors have the distance written negative - why????
    # this is ONLY for XDS - SATURN are the same - probably left handed
    # goniometer rotation on rigaku X-ray sets.

    if refined_distance:
        result.append("DETECTOR_DISTANCE=%7.3f" % refined_distance)
    else:
        result.append("DETECTOR_DISTANCE=%7.3f" % converter.detector_distance)

    result.append("OSCILLATION_RANGE=%4.2f" % converter.oscillation_range)
    result.append("X-RAY_WAVELENGTH=%8.6f" % converter.wavelength)

    # if user specified reversephi and this was not picked up in the
    # format class reverse phi: n.b. double-negative warning!

    if refined_rotation_axis:
        result.append("ROTATION_AXIS= %f %f %f" % refined_rotation_axis)
    else:
        result.append("ROTATION_AXIS= %.3f %.3f %.3f" %
                      converter.rotation_axis)

    if refined_beam_vector:
        result.append("INCIDENT_BEAM_DIRECTION=%f %f %f" % refined_beam_vector)
    else:
        result.append("INCIDENT_BEAM_DIRECTION= %.3f %.3f %.3f" %
                      converter.beam_vector)

    if hasattr(beam, "get_polarization_fraction"):
        R = converter.imagecif_to_xds_transformation_matrix
        result.append("FRACTION_OF_POLARIZATION= %.3f" %
                      beam.get_polarization_fraction())
        result.append("POLARIZATION_PLANE_NORMAL= %.3f %.3f %.3f" %
                      (R * matrix.col(beam.get_polarization_normal())).elems)

    # 24/NOV/14 XDS determines the air absorption automatically
    # based on wavelength. May be useful to override this for in vacuo exps
    # result.append('AIR=0.001')

    if detector == "PILATUS":
        try:
            thickness = converter.get_detector()[0].get_thickness()
            if not thickness:
                thickness = 0.32
                Debug.write(
                    "Could not determine sensor thickness. Assuming default PILATUS 0.32mm"
                )
        except e:
            thickness = 0.32
            Debug.write(
                "Error occured during sensor thickness determination. Assuming default PILATUS 0.32mm"
            )
        result.append("SENSOR_THICKNESS=%f" % thickness)

    #  FIXME: Sensor absorption coefficient calculation probably requires a more general solution
    #  if converter.get_detector()[0].get_material() == 'CdTe':
    #    print "CdTe detector detected. Beam wavelength is %8.6f Angstrom" % converter.wavelength

    if len(converter.panel_x_axis) > 1:
        for panel_id in range(len(converter.panel_x_axis)):

            result.append("")
            result.append("!")
            result.append("! SEGMENT %d" % (panel_id + 1))
            result.append("!")
            result.append("SEGMENT= %d %d %d %d" %
                          converter.panel_limits[panel_id])
            result.append("DIRECTION_OF_SEGMENT_X-AXIS= %.3f %.3f %.3f" %
                          converter.panel_x_axis[panel_id])
            result.append("DIRECTION_OF_SEGMENT_Y-AXIS= %.3f %.3f %.3f" %
                          converter.panel_y_axis[panel_id])
            result.append("SEGMENT_DISTANCE= %.3f" %
                          converter.panel_distance[panel_id])
            result.append("SEGMENT_ORGX= %.1f SEGMENT_ORGY= %.1f" %
                          converter.panel_origin[panel_id])
            result.append("")

    for f0, s0, f1, s1 in converter.get_detector()[0].get_mask():
        result.append("UNTRUSTED_RECTANGLE= %d %d %d %d" %
                      (f0 - 1, f1 + 1, s0 - 1, s1 + 1))

    if params.xds.untrusted_ellipse:
        for untrusted_ellipse in params.xds.untrusted_ellipse:
            result.append("UNTRUSTED_ELLIPSE= %d %d %d %d" %
                          tuple(untrusted_ellipse))
        Debug.write(result[-1])

    if params.xds.untrusted_rectangle:
        for untrusted_rectangle in params.xds.untrusted_rectangle:
            result.append("UNTRUSTED_RECTANGLE= %d %d %d %d" %
                          tuple(untrusted_rectangle))
        Debug.write(result[-1])

    return result
Beispiel #27
0
    def _index_prepare(self):
        '''Prepare to do autoindexing - in XDS terms this will mean
    calling xycorr, init and colspot on the input images.'''

        # decide on images to work with

        Debug.write('XDS INDEX PREPARE:')
        Debug.write('Wavelength: %.6f' % self.get_wavelength())
        Debug.write('Distance: %.2f' % self.get_distance())

        if self._indxr_images == []:
            _select_images_function = getattr(
                self, '_index_select_images_%s' % (self._index_select_images))
            wedges = _select_images_function()
            for wedge in wedges:
                self.add_indexer_image_wedge(wedge)
            self.set_indexer_prepare_done(True)

        all_images = self.get_matching_images()

        first = min(all_images)
        last = max(all_images)

        # next start to process these - first xycorr

        xycorr = self.Xycorr()

        xycorr.set_data_range(first, last)
        xycorr.set_background_range(self._indxr_images[0][0],
                                    self._indxr_images[0][1])
        from dxtbx.serialize.xds import to_xds
        converter = to_xds(self.get_imageset())
        xds_beam_centre = converter.detector_origin
        xycorr.set_beam_centre(xds_beam_centre[0], xds_beam_centre[1])
        for block in self._indxr_images:
            xycorr.add_spot_range(block[0], block[1])

        # FIXME need to set the origin here

        xycorr.run()

        for file in ['X-CORRECTIONS.cbf', 'Y-CORRECTIONS.cbf']:
            self._indxr_payload[file] = xycorr.get_output_data_file(file)

        # next start to process these - then init

        if PhilIndex.params.xia2.settings.input.format.dynamic_shadowing:
            imageset = self._indxr_imagesets[0]
            masker = imageset.masker().format_class(
                imageset.paths()[0]).get_goniometer_shadow_masker()
            if masker is None:
                # disable dynamic_shadowing
                PhilIndex.params.xia2.settings.input.format.dynamic_shadowing = False

        if PhilIndex.params.xia2.settings.input.format.dynamic_shadowing:
            # find the region of the scan with the least predicted shadow
            # to use for background determination in XDS INIT step
            from dxtbx.serialize import dump
            from dxtbx.datablock import DataBlock
            imageset = self._indxr_imagesets[0]
            xsweep = self._indxr_sweeps[0]
            sweep_filename = os.path.join(
                self.get_working_directory(),
                '%s_datablock.json' % xsweep.get_name())
            dump.datablock(DataBlock([imageset]), sweep_filename)

            from xia2.Wrappers.Dials.ShadowPlot import ShadowPlot
            shadow_plot = ShadowPlot()
            shadow_plot.set_working_directory(self.get_working_directory())
            auto_logfiler(shadow_plot)
            shadow_plot.set_sweep_filename(sweep_filename)
            shadow_plot.set_json_filename(
                os.path.join(self.get_working_directory(),
                             '%s_shadow_plot.json' % shadow_plot.get_xpid()))
            shadow_plot.run()
            results = shadow_plot.get_results()
            from scitbx.array_family import flex
            fraction_shadowed = flex.double(results['fraction_shadowed'])
            if flex.max(fraction_shadowed) == 0:
                PhilIndex.params.xia2.settings.input.format.dynamic_shadowing = False
            else:
                scan_points = flex.double(results['scan_points'])

                phi_width = self.get_phi_width()
                scan = imageset.get_scan()
                oscillation_range = scan.get_oscillation_range()
                oscillation = scan.get_oscillation()

                if self._background_images is not None:
                    bg_images = self._background_images
                    bg_range_deg = (scan.get_angle_from_image_index(
                        bg_images[0]),
                                    scan.get_angle_from_image_index(
                                        bg_images[1]))
                    bg_range_width = bg_range_deg[1] - bg_range_deg[0]

                    min_shadow = 100
                    best_bg_range = bg_range_deg
                    from libtbx.utils import frange
                    for bg_range_start in frange(flex.min(scan_points),
                                                 flex.max(scan_points) -
                                                 bg_range_width,
                                                 step=oscillation[1]):
                        bg_range_deg = (bg_range_start,
                                        bg_range_start + bg_range_width)
                        sel = (scan_points >= bg_range_deg[0]) & (
                            scan_points <= bg_range_deg[1])
                        mean_shadow = flex.mean(fraction_shadowed.select(sel))
                        if mean_shadow < min_shadow:
                            min_shadow = mean_shadow
                            best_bg_range = bg_range_deg

                    self._background_images = (scan.get_image_index_from_angle(
                        best_bg_range[0]),
                                               scan.get_image_index_from_angle(
                                                   best_bg_range[1]))
                    Debug.write('Setting background images: %s -> %s' %
                                self._background_images)

        init = self.Init()

        for file in ['X-CORRECTIONS.cbf', 'Y-CORRECTIONS.cbf']:
            init.set_input_data_file(file, self._indxr_payload[file])

        init.set_data_range(first, last)

        if self._background_images:
            init.set_background_range(self._background_images[0],
                                      self._background_images[1])
        else:
            init.set_background_range(self._indxr_images[0][0],
                                      self._indxr_images[0][1])

        for block in self._indxr_images:
            init.add_spot_range(block[0], block[1])

        init.run()

        # at this stage, need to (perhaps) modify the BKGINIT.cbf image
        # to mark out the back stop

        if PhilIndex.params.general.backstop_mask:
            Debug.write('Applying mask to BKGINIT.pck')

            # copy the original file
            cbf_old = os.path.join(init.get_working_directory(), 'BKGINIT.cbf')
            cbf_save = os.path.join(init.get_working_directory(),
                                    'BKGINIT.sav')
            shutil.copyfile(cbf_old, cbf_save)

            # modify the file to give the new mask
            from xia2.Toolkit.BackstopMask import BackstopMask
            mask = BackstopMask(PhilIndex.params.general.backstop_mask)
            mask.apply_mask_xds(self.get_header(), cbf_save, cbf_old)

            init.reload()

        for file in ['BLANK.cbf', 'BKGINIT.cbf', 'GAIN.cbf']:
            self._indxr_payload[file] = init.get_output_data_file(file)

        if PhilIndex.params.xia2.settings.developmental.use_dials_spotfinder:

            spotfinder = self.DialsSpotfinder()

            for block in self._indxr_images:
                spotfinder.add_spot_range(block[0], block[1])

            spotfinder.run()
            export = self.DialsExportSpotXDS()
            export.set_input_data_file(
                'reflections.pickle',
                spotfinder.get_output_data_file('reflections.pickle'))
            export.run()

            for file in ['SPOT.XDS']:
                self._indxr_payload[file] = export.get_output_data_file(file)

        else:

            # next start to process these - then colspot

            colspot = self.Colspot()

            for file in [
                    'X-CORRECTIONS.cbf', 'Y-CORRECTIONS.cbf', 'BLANK.cbf',
                    'BKGINIT.cbf', 'GAIN.cbf'
            ]:
                colspot.set_input_data_file(file, self._indxr_payload[file])

            colspot.set_data_range(first, last)
            colspot.set_background_range(self._indxr_images[0][0],
                                         self._indxr_images[0][1])
            for block in self._indxr_images:
                colspot.add_spot_range(block[0], block[1])

            colspot.run()

            for file in ['SPOT.XDS']:
                self._indxr_payload[file] = colspot.get_output_data_file(file)

        # that should be everything prepared... all of the important
        # files should be loaded into memory to be able to cope with
        # integration happening somewhere else

        return
Beispiel #28
0
def dump(experiments, reflections, directory):
    """Dump the files in XDS format"""
    if len(experiments) > 0:
        for i, experiment in enumerate(experiments):
            suffix = ""
            if len(experiments) > 1:
                suffix = "_%i" % (i + 1)

            sub_dir = f"{directory}{suffix}"
            if not os.path.isdir(sub_dir):
                os.makedirs(sub_dir)
            # XXX imageset is getting the experimental geometry from the image files
            # rather than the input models.expt file
            imageset = experiment.imageset
            imageset.set_detector(experiment.detector)
            imageset.set_beam(experiment.beam)
            imageset.set_goniometer(experiment.goniometer)
            imageset.set_scan(experiment.scan)

            if experiment.crystal is None:
                space_group_number = None
                real_space_a = None
                real_space_b = None
                real_space_c = None
                job_card = "XYCORR INIT COLSPOT IDXREF DEFPIX INTEGRATE CORRECT"
            else:
                crystal_model = experiment.crystal
                crystal_model = crystal_model.change_basis(
                    crystal_model.get_space_group()
                    .info()
                    .change_of_basis_op_to_reference_setting()
                )
                space_group_number = crystal_model.get_space_group().type().number()
                A = matrix.sqr(crystal_model.get_A())
                A_inv = A.inverse()
                real_space_a = A_inv.elems[:3]
                real_space_b = A_inv.elems[3:6]
                real_space_c = A_inv.elems[6:9]
                job_card = ("XYCORR INIT DEFPIX INTEGRATE CORRECT",)

            to_xds = xds.to_xds(imageset)
            xds_inp = os.path.join(sub_dir, "XDS.INP")
            xparm_xds = os.path.join(sub_dir, "XPARM.XDS")
            logger.info("Exporting experiment to %s", xds_inp)
            with open(xds_inp, "w") as f:
                f.write(
                    to_xds.XDS_INP(
                        space_group_number=space_group_number,
                        real_space_a=real_space_a,
                        real_space_b=real_space_b,
                        real_space_c=real_space_c,
                        job_card=job_card,
                    )
                )
            if space_group_number:
                logger.info("Exporting crystal model to %s", xparm_xds)
                with open(xparm_xds, "w") as f:
                    f.write(
                        to_xds.xparm_xds(
                            real_space_a, real_space_b, real_space_c, space_group_number
                        )
                    )

            if reflections is not None and len(reflections) > 0:
                ref_cryst = reflections.select(reflections["id"] == i)
                export_spot_xds(ref_cryst, os.path.join(sub_dir, "SPOT.XDS"))

    else:
        if not os.path.isdir(directory):
            os.makedirs(directory)
        export_spot_xds(reflections, os.path.join(directory, "SPOT.XDS"))
Beispiel #29
0
# Print out the contents of the dxtbx understanding of a bunch of images to
# an example XDS.INP file. This should illustrate the usage of the dxtbx
# classes.

import sys
from dxtbx.serialize import xds

def run(file_names):
  if len(file_names) == 1 and file_names[0].endswith('json'):
    from dxtbx.serialize import load
    try:
      datablock = load.datablock(file_names[0])
      assert len(datablock) == 1
      sweep = datablock[0].extract_sweeps()[0]
    except ValueError, e:
      if str(e) == '"__id__" does not equal "imageset"':
        experiments = load.experiment_list(file_names[0])
        assert len(experiments) == 1
        sweep = experiments[0].imageset
      else:
        raise
  else:
    from dxtbx.imageset import ImageSetFactory
    sweep = ImageSetFactory.new(file_names)[0]
  xsx = xds.to_xds(sweep)
  xsx.XDS_INP()


if __name__ == '__main__':
  run(sys.argv[1:])
Beispiel #30
0
# Print out the contents of the dxtbx understanding of a bunch of images to
# an example XDS.INP file. This should illustrate the usage of the dxtbx
# classes.

import sys
from dxtbx.serialize import xds

def run(file_names):
  if len(file_names) == 1 and file_names[0].endswith('json'):
    from dxtbx.serialize import load
    try:
      datablock = load.datablock(file_names[0])
      assert len(datablock) == 1
      sweep = datablock[0].extract_sweeps()[0]
    except ValueError, e:
      if str(e) == '"__id__" does not equal "imageset"':
        experiments = load.experiment_list(file_names[0])
        assert len(experiments) == 1
        sweep = experiments[0].imageset
      else:
        raise
  else:
    from dxtbx.imageset import ImageSetFactory
    sweep = ImageSetFactory.new(file_names)[0]
  xsx = xds.to_xds(sweep)
  xsx.XDS_INP()


if __name__ == '__main__':
  run(sys.argv[1:])