Example #1
0
def test(dials_regression):
    from iotbx.xds import xparm, integrate_hkl
    from dials.util import ioutil
    from dials.algorithms.spot_prediction import IndexGenerator
    import numpy
    from rstbx.cftbx.coordinate_frame_converter import \
        coordinate_frame_converter
    from scitbx import matrix

    # The XDS files to read from
    integrate_filename = os.path.join(dials_regression, 'data', 'sim_mx',
                                      'INTEGRATE.HKL')
    gxparm_filename = os.path.join(dials_regression, 'data', 'sim_mx',
                                   'GXPARM.XDS')

    # Read the XDS files
    integrate_handle = integrate_hkl.reader()
    integrate_handle.read_file(integrate_filename)
    gxparm_handle = xparm.reader()
    gxparm_handle.read_file(gxparm_filename)

    # Get the parameters we need from the GXPARM file
    d_min = 1.6
    space_group_type = ioutil.get_space_group_type_from_xparm(gxparm_handle)
    cfc = coordinate_frame_converter(gxparm_filename)
    a_vec = cfc.get('real_space_a')
    b_vec = cfc.get('real_space_b')
    c_vec = cfc.get('real_space_c')
    unit_cell = cfc.get_unit_cell()
    UB = matrix.sqr(a_vec + b_vec + c_vec).inverse()
    ub_matrix = UB

    # Generate the indices
    index_generator = IndexGenerator(unit_cell, space_group_type, d_min)
    miller_indices = index_generator.to_array()

    # Get individual generated hkl
    gen_h = [hkl[0] for hkl in miller_indices]
    gen_k = [hkl[1] for hkl in miller_indices]
    gen_l = [hkl[2] for hkl in miller_indices]

    # Get individual xds generated hkl
    xds_h = [hkl[0] for hkl in integrate_handle.hkl]
    xds_k = [hkl[1] for hkl in integrate_handle.hkl]
    xds_l = [hkl[2] for hkl in integrate_handle.hkl]

    # Get min/max generated hkl
    min_gen_h, max_gen_h = numpy.min(gen_h), numpy.max(gen_h)
    min_gen_k, max_gen_k = numpy.min(gen_k), numpy.max(gen_k)
    min_gen_l, max_gen_l = numpy.min(gen_l), numpy.max(gen_l)

    # Get min/max xds generated hkl
    min_xds_h, max_xds_h = numpy.min(xds_h), numpy.max(xds_h)
    min_xds_k, max_xds_k = numpy.min(xds_k), numpy.max(xds_k)
    min_xds_l, max_xds_l = numpy.min(xds_l), numpy.max(xds_l)

    # Ensure we have the whole xds range  in the generated set
    assert min_gen_h <= min_xds_h and max_gen_h >= max_xds_h
    assert min_gen_k <= min_xds_k and max_gen_k >= max_xds_k
    assert min_gen_l <= min_xds_l and max_gen_l >= max_xds_l
Example #2
0
def test(dials_regression):
    import numpy as np

    from iotbx.xds import integrate_hkl, xparm
    from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter

    from dials.algorithms.spot_prediction import IndexGenerator
    from dials.util import ioutil

    # The XDS files to read from
    integrate_filename = os.path.join(dials_regression, "data", "sim_mx",
                                      "INTEGRATE.HKL")
    gxparm_filename = os.path.join(dials_regression, "data", "sim_mx",
                                   "GXPARM.XDS")

    # Read the XDS files
    integrate_handle = integrate_hkl.reader()
    integrate_handle.read_file(integrate_filename)
    gxparm_handle = xparm.reader()
    gxparm_handle.read_file(gxparm_filename)

    # Get the parameters we need from the GXPARM file
    d_min = 1.6
    space_group_type = ioutil.get_space_group_type_from_xparm(gxparm_handle)
    cfc = coordinate_frame_converter(gxparm_filename)
    unit_cell = cfc.get_unit_cell()

    # Generate the indices
    index_generator = IndexGenerator(unit_cell, space_group_type, d_min)
    miller_indices = index_generator.to_array()

    # Get individual generated hkl
    gen_h = [hkl[0] for hkl in miller_indices]
    gen_k = [hkl[1] for hkl in miller_indices]
    gen_l = [hkl[2] for hkl in miller_indices]

    # Get individual xds generated hkl
    xds_h = [hkl[0] for hkl in integrate_handle.hkl]
    xds_k = [hkl[1] for hkl in integrate_handle.hkl]
    xds_l = [hkl[2] for hkl in integrate_handle.hkl]

    # Get min/max generated hkl
    min_gen_h, max_gen_h = np.min(gen_h), np.max(gen_h)
    min_gen_k, max_gen_k = np.min(gen_k), np.max(gen_k)
    min_gen_l, max_gen_l = np.min(gen_l), np.max(gen_l)

    # Get min/max xds generated hkl
    min_xds_h, max_xds_h = np.min(xds_h), np.max(xds_h)
    min_xds_k, max_xds_k = np.min(xds_k), np.max(xds_k)
    min_xds_l, max_xds_l = np.min(xds_l), np.max(xds_l)

    # Ensure we have the whole xds range  in the generated set
    assert min_gen_h <= min_xds_h and max_gen_h >= max_xds_h
    assert min_gen_k <= min_xds_k and max_gen_k >= max_xds_k
    assert min_gen_l <= min_xds_l and max_gen_l >= max_xds_l
Example #3
0
def run():
  from iotbx.xds import xparm, integrate_hkl
  from dials.util import ioutil
  from dials.algorithms.spot_prediction import IndexGenerator
  from os.path import realpath, dirname, join
  import numpy
  from rstbx.cftbx.coordinate_frame_converter import \
      coordinate_frame_converter
  from scitbx import matrix

  # The XDS files to read from
  test_path = dirname(dirname(dirname(realpath(__file__))))
  integrate_filename = join(test_path, 'data/sim_mx/INTEGRATE.HKL')
  gxparm_filename = join(test_path, 'data/sim_mx/GXPARM.XDS')

  # Read the XDS files
  integrate_handle = integrate_hkl.reader()
  integrate_handle.read_file(integrate_filename)
  gxparm_handle = xparm.reader()
  gxparm_handle.read_file(gxparm_filename)

  # Get the parameters we need from the GXPARM file
  d_min = 1.6
  space_group_type = ioutil.get_space_group_type_from_xparm(gxparm_handle)
  cfc = coordinate_frame_converter(gxparm_filename)
  a_vec = cfc.get('real_space_a')
  b_vec = cfc.get('real_space_b')
  c_vec = cfc.get('real_space_c')
  unit_cell = cfc.get_unit_cell()
  UB = matrix.sqr(a_vec + b_vec + c_vec).inverse()
  ub_matrix = UB

  # Generate the indices
  index_generator = IndexGenerator(unit_cell, space_group_type, d_min)
  miller_indices = index_generator.to_array()

  # Get individual generated hkl
  gen_h = [hkl[0] for hkl in miller_indices]
  gen_k = [hkl[1] for hkl in miller_indices]
  gen_l = [hkl[2] for hkl in miller_indices]

  # Get individual xds generated hkl
  xds_h = [hkl[0] for hkl in integrate_handle.hkl]
  xds_k = [hkl[0] for hkl in integrate_handle.hkl]
  xds_l = [hkl[0] for hkl in integrate_handle.hkl]

  # Get min/max generated hkl
  min_gen_h, max_gen_h = numpy.min(gen_h), numpy.max(gen_h)
  min_gen_k, max_gen_k = numpy.min(gen_k), numpy.max(gen_k)
  min_gen_l, max_gen_l = numpy.min(gen_l), numpy.max(gen_l)

  # Get min/max xds generated hkl
  min_xds_h, max_xds_h = numpy.min(xds_h), numpy.max(xds_h)
  min_xds_k, max_xds_k = numpy.min(xds_k), numpy.max(xds_k)
  min_xds_l, max_xds_l = numpy.min(xds_l), numpy.max(xds_l)

  # Ensure we have the whole xds range  in the generated set
  assert(min_gen_h <= min_xds_h and max_gen_h >= max_xds_h)
  assert(min_gen_k <= min_xds_k and max_gen_k >= max_xds_k)
  assert(min_gen_l <= min_xds_l and max_gen_l >= max_xds_l)

  # Test Passed
  print "OK"
Example #4
0
    def __init__(self):
        from dials.algorithms.spot_prediction import IndexGenerator
        from dials.algorithms.spot_prediction import ScanStaticRayPredictor
        from dials.algorithms.spot_prediction import ray_intersection
        from iotbx.xds import xparm, integrate_hkl
        from dials.util import ioutil
        from math import ceil
        import dxtbx
        from rstbx.cftbx.coordinate_frame_converter import \
            coordinate_frame_converter
        from scitbx import matrix

        # The XDS files to read from
        integrate_filename = join(dials_regression,
                                  'data/sim_mx/INTEGRATE.HKL')
        gxparm_filename = join(dials_regression, 'data/sim_mx/GXPARM.XDS')

        # Read the XDS files
        self.integrate_handle = integrate_hkl.reader()
        self.integrate_handle.read_file(integrate_filename)
        self.gxparm_handle = xparm.reader()
        self.gxparm_handle.read_file(gxparm_filename)

        # Get the parameters we need from the GXPARM file
        models = dxtbx.load(gxparm_filename)
        self.beam = models.get_beam()
        self.gonio = models.get_goniometer()
        self.detector = models.get_detector()
        self.scan = models.get_scan()

        assert (len(self.detector) == 1)

        #print self.detector

        # Get crystal parameters
        self.space_group_type = ioutil.get_space_group_type_from_xparm(
            self.gxparm_handle)
        cfc = coordinate_frame_converter(gxparm_filename)
        a_vec = cfc.get('real_space_a')
        b_vec = cfc.get('real_space_b')
        c_vec = cfc.get('real_space_c')
        self.unit_cell = cfc.get_unit_cell()
        self.ub_matrix = matrix.sqr(a_vec + b_vec + c_vec).inverse()

        # Get the minimum resolution in the integrate file
        self.d_min = self.detector[0].get_max_resolution_at_corners(
            self.beam.get_s0())

        # Get the number of frames from the max z value
        xcal, ycal, zcal = zip(*self.integrate_handle.xyzcal)
        self.scan.set_image_range(
            (self.scan.get_image_range()[0],
             self.scan.get_image_range()[0] + int(ceil(max(zcal)))))

        # Create the index generator
        generate_indices = IndexGenerator(self.unit_cell,
                                          self.space_group_type, self.d_min)

        s0 = self.beam.get_s0()
        m2 = self.gonio.get_rotation_axis()
        fixed_rotation = self.gonio.get_fixed_rotation()
        setting_rotation = self.gonio.get_setting_rotation()
        UB = self.ub_matrix
        dphi = self.scan.get_oscillation_range(deg=False)

        # Create the ray predictor
        self.predict_rays = ScanStaticRayPredictor(s0, m2, fixed_rotation,
                                                   setting_rotation, dphi)

        # Predict the spot locations
        self.reflections = self.predict_rays(generate_indices.to_array(), UB)

        # Calculate the intersection of the detector and reflection frames
        success = ray_intersection(self.detector, self.reflections)
        self.reflections.select(success)
Example #5
0
    def __init__(self, dials_regression):
        import dxtbx
        from iotbx.xds import integrate_hkl, xparm
        from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter

        from dials.algorithms.spot_prediction import (
            IndexGenerator,
            ScanStaticRayPredictor,
        )
        from dials.util import ioutil

        # The XDS files to read from
        integrate_filename = os.path.join(dials_regression, "data", "sim_mx",
                                          "INTEGRATE.HKL")
        gxparm_filename = os.path.join(dials_regression, "data", "sim_mx",
                                       "GXPARM.XDS")

        # Read the XDS files
        self.integrate_handle = integrate_hkl.reader()
        self.integrate_handle.read_file(integrate_filename)
        self.gxparm_handle = xparm.reader()
        self.gxparm_handle.read_file(gxparm_filename)

        # Get the parameters we need from the GXPARM file
        models = dxtbx.load(gxparm_filename)
        self.beam = models.get_beam()
        self.gonio = models.get_goniometer()
        self.detector = models.get_detector()
        self.scan = models.get_scan()

        # Get crystal parameters
        self.space_group_type = ioutil.get_space_group_type_from_xparm(
            self.gxparm_handle)
        cfc = coordinate_frame_converter(gxparm_filename)
        a_vec = cfc.get("real_space_a")
        b_vec = cfc.get("real_space_b")
        c_vec = cfc.get("real_space_c")
        self.unit_cell = cfc.get_unit_cell()
        self.ub_matrix = matrix.sqr(a_vec + b_vec + c_vec).inverse()

        # Get the minimum resolution in the integrate file
        d = [self.unit_cell.d(h) for h in self.integrate_handle.hkl]
        self.d_min = min(d)
        # extend the resolution shell by epsilon>0
        # to account for rounding artifacts on 32-bit platforms
        self.d_min = self.d_min - 1e-15

        # Get the number of frames from the max z value
        xcal, ycal, zcal = zip(*self.integrate_handle.xyzcal)
        self.scan.set_image_range((
            self.scan.get_image_range()[0],
            self.scan.get_image_range()[0] + int(math.ceil(max(zcal))),
        ))

        # Print stuff
        #        print self.beam
        #        print self.gonio
        #        print self.detector
        #        print self.scan

        # Create the index generator
        self.generate_indices = IndexGenerator(self.unit_cell,
                                               self.space_group_type,
                                               self.d_min)

        s0 = self.beam.get_s0()
        m2 = self.gonio.get_rotation_axis()
        fixed_rotation = self.gonio.get_fixed_rotation()
        setting_rotation = self.gonio.get_setting_rotation()
        UB = self.ub_matrix
        dphi = self.scan.get_oscillation_range(deg=False)

        # Create the ray predictor
        self.predict_rays = ScanStaticRayPredictor(s0, m2, fixed_rotation,
                                                   setting_rotation, dphi)

        # Predict the spot locations
        self.reflections = self.predict_rays(self.generate_indices.to_array(),
                                             UB)
Example #6
0
  def _integrate_finish(self):
    '''Finish off the integration by running correct.'''

    # first run the postrefinement etc with spacegroup P1
    # and the current unit cell - this will be used to
    # obtain a benchmark rmsd in pixels / phi and also
    # cell deviations (this is working towards spotting bad
    # indexing solutions) - only do this if we have no
    # reindex matrix... and no postrefined cell...

    p1_deviations = None

    # fix for bug # 3264 -
    # if we have not run integration with refined parameters, make it so...
    # erm? shouldn't this therefore return if this is the principle, or
    # set the flag after we have tested the lattice?

    if not self._xds_data_files.has_key('GXPARM.XDS') and \
      PhilIndex.params.xds.integrate.reintegrate:
      Debug.write(
          'Resetting integrater, to ensure refined orientation is used')
      self.set_integrater_done(False)

    if not self.get_integrater_reindex_matrix() and not self._intgr_cell \
           and not Flags.get_no_lattice_test() and \
           not self.get_integrater_sweep().get_user_lattice():
      correct = self.Correct()

      correct.set_data_range(self._intgr_wedge[0],
                             self._intgr_wedge[1])

      if self.get_polarization() > 0.0:
        correct.set_polarization(self.get_polarization())

      # FIXME should this be using the correctly transformed
      # cell or are the results ok without it?!

      correct.set_spacegroup_number(1)
      correct.set_cell(self._intgr_refiner_cell)

      correct.run()

      # record the log file -

      pname, xname, dname = self.get_integrater_project_info()
      sweep = self.get_integrater_sweep_name()
      FileHandler.record_log_file('%s %s %s %s CORRECT' % \
                                  (pname, xname, dname, sweep),
                                  os.path.join(
          self.get_working_directory(),
          'CORRECT.LP'))

      FileHandler.record_more_data_file(
          '%s %s %s %s CORRECT' % (pname, xname, dname, sweep),
          os.path.join(self.get_working_directory(), 'XDS_ASCII.HKL'))

      cell = correct.get_result('cell')
      cell_esd = correct.get_result('cell_esd')

      Debug.write('Postrefinement in P1 results:')
      Debug.write('%7.3f %7.3f %7.3f %7.3f %7.3f %7.3f' % \
                  tuple(cell))
      Debug.write('%7.3f %7.3f %7.3f %7.3f %7.3f %7.3f' % \
                  tuple(cell_esd))
      Debug.write('Deviations: %.2f pixels %.2f degrees' % \
                  (correct.get_result('rmsd_pixel'),
                   correct.get_result('rmsd_phi')))

      p1_deviations = (correct.get_result('rmsd_pixel'),
                       correct.get_result('rmsd_phi'))

    # next run the postrefinement etc with the given
    # cell / lattice - this will be the assumed result...

    correct = self.Correct()

    correct.set_data_range(self._intgr_wedge[0],
                           self._intgr_wedge[1])

    if self.get_polarization() > 0.0:
      correct.set_polarization(self.get_polarization())

    # BUG # 2695 probably comes from here - need to check...
    # if the pointless interface comes back with a different
    # crystal setting then the unit cell stored in self._intgr_cell
    # needs to be set to None...

    if self.get_integrater_spacegroup_number():
      correct.set_spacegroup_number(
          self.get_integrater_spacegroup_number())
      if not self._intgr_cell:
        raise RuntimeError, 'no unit cell to recycle'
      correct.set_cell(self._intgr_cell)

    # BUG # 3113 - new version of XDS will try and figure the
    # best spacegroup out from the intensities (and get it wrong!)
    # unless we set the spacegroup and cell explicitly

    if not self.get_integrater_spacegroup_number():
      cell = self._intgr_refiner_cell
      lattice = self._intgr_refiner.get_refiner_lattice()
      spacegroup_number = lattice_to_spacegroup_number(lattice)

      # this should not prevent the postrefinement from
      # working correctly, else what is above would not
      # work correctly (the postrefinement test)

      correct.set_spacegroup_number(spacegroup_number)
      correct.set_cell(cell)

      Debug.write('Setting spacegroup to: %d' % spacegroup_number)
      Debug.write(
        'Setting cell to: %.2f %.2f %.2f %.2f %.2f %.2f' % tuple(cell))

    if self.get_integrater_reindex_matrix():

      # bug! if the lattice is not primitive the values in this
      # reindex matrix need to be multiplied by a constant which
      # depends on the Bravais lattice centering.

      lattice = self._intgr_refiner.get_refiner_lattice()

      import scitbx.matrix
      matrix = self.get_integrater_reindex_matrix()
      matrix = scitbx.matrix.sqr(matrix).transpose().elems
      matrix = r_to_rt(matrix)

      if lattice[1] == 'P':
        mult = 1
      elif lattice[1] == 'C' or lattice[1] == 'I':
        mult = 2
      elif lattice[1] == 'R':
        mult = 3
      elif lattice[1] == 'F':
        mult = 4
      else:
        raise RuntimeError, 'unknown multiplier for lattice %s' % \
              lattice

      Debug.write('REIDX multiplier for lattice %s: %d' % \
                  (lattice, mult))

      mult_matrix = [mult * m for m in matrix]

      Debug.write('REIDX set to %d %d %d %d %d %d %d %d %d %d %d %d' % \
                  tuple(mult_matrix))
      correct.set_reindex_matrix(mult_matrix)

    correct.run()

    # erm. just to be sure
    if self.get_integrater_reindex_matrix() and \
           correct.get_reindex_used():
      raise RuntimeError, 'Reindex panic!'

    # get the reindex operation used, which may be useful if none was
    # set but XDS decided to apply one, e.g. #419.

    if not self.get_integrater_reindex_matrix() and \
           correct.get_reindex_used():
      # convert this reindex operation to h, k, l form: n.b. this
      # will involve dividing through by the lattice centring multiplier

      matrix = rt_to_r(correct.get_reindex_used())
      import scitbx.matrix
      matrix = scitbx.matrix.sqr(matrix).transpose().elems

      lattice = self._intgr_refiner.get_refiner_lattice()

      if lattice[1] == 'P':
        mult = 1.0
      elif lattice[1] == 'C' or lattice[1] == 'I':
        mult = 2.0
      elif lattice[1] == 'R':
        mult = 3.0
      elif lattice[1] == 'F':
        mult = 4.0

      matrix = [m / mult for m in matrix]

      reindex_op = mat_to_symop(matrix)

      # assign this to self: will this reset?! make for a leaky
      # abstraction and just assign this...

      # self.set_integrater_reindex_operator(reindex)

      self._intgr_reindex_operator = reindex_op


    # record the log file -

    pname, xname, dname = self.get_integrater_project_info()
    sweep = self.get_integrater_sweep_name()
    FileHandler.record_log_file('%s %s %s %s CORRECT' % \
                                (pname, xname, dname, sweep),
                                os.path.join(self.get_working_directory(),
                                             'CORRECT.LP'))

    # should get some interesting stuff from the XDS correct file
    # here, for instance the resolution range to use in integration
    # (which should be fed back if not fast) and so on...

    self._intgr_corrected_hklout = os.path.join(self.get_working_directory(),
                                'XDS_ASCII.HKL')

    # also record the batch range - needed for the analysis of the
    # radiation damage in chef...

    self._intgr_batches_out = (self._intgr_wedge[0],
                               self._intgr_wedge[1])

    # FIXME perhaps I should also feedback the GXPARM file here??
    for file in ['GXPARM.XDS']:
      self._xds_data_files[file] = correct.get_output_data_file(file)

    # record the postrefined cell parameters
    self._intgr_cell = correct.get_result('cell')
    self._intgr_n_ref = correct.get_result('n_ref')

    Debug.write('Postrefinement in "correct" spacegroup results:')
    Debug.write('%7.3f %7.3f %7.3f %7.3f %7.3f %7.3f' % \
                tuple(correct.get_result('cell')))
    Debug.write('%7.3f %7.3f %7.3f %7.3f %7.3f %7.3f' % \
                tuple(correct.get_result('cell_esd')))
    Debug.write('Deviations: %.2f pixels %.2f degrees' % \
                (correct.get_result('rmsd_pixel'),
                 correct.get_result('rmsd_phi')))

    Debug.write('Error correction parameters: A=%.3f B=%.3f' % \
                correct.get_result('sdcorrection'))

    # compute misorientation of axes

    xparm_file = os.path.join(self.get_working_directory(), 'GXPARM.XDS')

    from iotbx.xds import xparm
    handle = xparm.reader()
    handle.read_file(xparm_file)

    rotn = handle.rotation_axis
    beam = handle.beam_vector

    dot = sum([rotn[j] * beam[j] for j in range(3)])
    r = math.sqrt(sum([rotn[j] * rotn[j] for j in range(3)]))
    b = math.sqrt(sum([beam[j] * beam[j] for j in range(3)]))

    rtod = 180.0 / math.pi

    angle = rtod * math.fabs(0.5 * math.pi - math.acos(dot / (r * b)))

    Debug.write('Axis misalignment %.2f degrees' % angle)

    correct_deviations = (correct.get_result('rmsd_pixel'),
                          correct.get_result('rmsd_phi'))

    if p1_deviations:
      # compare and reject if both > 50% higher - though adding a little
      # flexibility - 0.5 pixel / osc width slack.

      pixel = p1_deviations[0]
      phi = math.sqrt(0.05 * 0.05 + \
                      p1_deviations[1] * p1_deviations[1])

      threshold = Flags.get_rejection_threshold()

      Debug.write('RMSD ratio: %.2f' % (correct_deviations[0] / pixel))
      Debug.write('RMSPhi ratio: %.2f' % (correct_deviations[1] / phi))

      if correct_deviations[0] / pixel > threshold and \
             correct_deviations[1] / phi > threshold:

        Chatter.write(
        'Eliminating this indexing solution as postrefinement')
        Chatter.write(
        'deviations rather high relative to triclinic')
        raise BadLatticeError, \
              'high relative deviations in postrefinement'

    if not Flags.get_quick() and Flags.get_remove():
      # check for alien reflections and perhaps recycle - removing them
      if len(correct.get_remove()) > 0:

        correct_remove = correct.get_remove()
        current_remove = []
        final_remove = []

        # first ensure that there are no duplicate entries...
        if os.path.exists(os.path.join(
            self.get_working_directory(),
            'REMOVE.HKL')):
          for line in open(os.path.join(
              self.get_working_directory(),
              'REMOVE.HKL'), 'r').readlines():
            h, k, l = map(int, line.split()[:3])
            z = float(line.split()[3])

            if not (h, k, l, z) in current_remove:
              current_remove.append((h, k, l, z))

          for c in correct_remove:
            if c in current_remove:
              continue
            final_remove.append(c)

          Debug.write(
              '%d alien reflections are already removed' % \
              (len(correct_remove) - len(final_remove)))
        else:
          # we want to remove all of the new dodgy reflections
          final_remove = correct_remove

        remove_hkl = open(os.path.join(
            self.get_working_directory(),
            'REMOVE.HKL'), 'w')

        z_min = Flags.get_z_min()
        rejected = 0

        # write in the old reflections
        for remove in current_remove:
          z = remove[3]
          if z >= z_min:
            remove_hkl.write('%d %d %d %f\n' % remove)
          else:
            rejected += 1
        Debug.write('Wrote %d old reflections to REMOVE.HKL' % \
                    (len(current_remove) - rejected))
        Debug.write('Rejected %d as z < %f' % \
                    (rejected, z_min))

        # and the new reflections
        rejected = 0
        used = 0
        for remove in final_remove:
          z = remove[3]
          if z >= z_min:
            used += 1
            remove_hkl.write('%d %d %d %f\n' % remove)
          else:
            rejected += 1
        Debug.write('Wrote %d new reflections to REMOVE.HKL' % \
                    (len(final_remove) - rejected))
        Debug.write('Rejected %d as z < %f' % \
                    (rejected, z_min))

        remove_hkl.close()

        # we want to rerun the finishing step so...
        # unless we have added no new reflections... or unless we
        # have not confirmed the point group (see SCI-398)

        if used and self.get_integrater_reindex_matrix():
          self.set_integrater_finish_done(False)

    else:
      Debug.write(
          'Going quickly so not removing %d outlier reflections...' % \
          len(correct.get_remove()))

    # Convert INTEGRATE.HKL to MTZ format and reapply any reindexing operations
    # spacegroup changes to allow use with CCP4 / Aimless for scaling

    integrate_hkl = os.path.join(
      self.get_working_directory(), 'INTEGRATE.HKL')

    hklout = os.path.splitext(integrate_hkl)[0] + ".mtz"
    self._factory.set_working_directory(self.get_working_directory())
    pointless = self._factory.Pointless()
    pointless.set_xdsin(integrate_hkl)
    pointless.set_hklout(hklout)
    pointless.xds_to_mtz()

    integrate_mtz = hklout

    if self.get_integrater_reindex_operator() or \
       self.get_integrater_spacegroup_number():

      Debug.write('Reindexing things to MTZ')

      reindex = Reindex()
      reindex.set_working_directory(self.get_working_directory())
      auto_logfiler(reindex)

      if self.get_integrater_reindex_operator():
        reindex.set_operator(self.get_integrater_reindex_operator())

      if self.get_integrater_spacegroup_number():
        reindex.set_spacegroup(self.get_integrater_spacegroup_number())

      hklout = '%s_reindex.mtz' % os.path.splitext(integrate_mtz)[0]

      reindex.set_hklin(integrate_mtz)
      reindex.set_hklout(hklout)
      reindex.reindex()
      integrate_mtz = hklout

    return integrate_mtz
Example #7
0
def test(dials_regression, run_in_tmpdir):
    import dxtbx
    from iotbx.xds import integrate_hkl, xparm
    from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter

    from dials.algorithms.spot_prediction import RotationAngles

    # The XDS files to read from
    integrate_filename = os.path.join(dials_regression,
                                      "data/sim_mx/INTEGRATE.HKL")
    gxparm_filename = os.path.join(dials_regression, "data/sim_mx/GXPARM.XDS")

    # Read the XDS files
    integrate_handle = integrate_hkl.reader()
    integrate_handle.read_file(integrate_filename)
    gxparm_handle = xparm.reader()
    gxparm_handle.read_file(gxparm_filename)

    # Get the parameters we need from the GXPARM file
    models = dxtbx.load(gxparm_filename)
    beam = models.get_beam()
    gonio = models.get_goniometer()
    scan = models.get_scan()

    # Get the crystal parameters
    cfc = coordinate_frame_converter(gxparm_filename)
    a_vec = cfc.get("real_space_a")
    b_vec = cfc.get("real_space_b")
    c_vec = cfc.get("real_space_c")
    UB = matrix.sqr(a_vec + b_vec + c_vec).inverse()
    ub_matrix = UB

    # Get the number of frames from the max z value
    xcal, ycal, zcal = zip(*integrate_handle.xyzcal)
    num_frames = int(math.ceil(max(zcal)))
    scan.set_image_range((scan.get_image_range()[0],
                          scan.get_image_range()[0] + num_frames - 1))

    # Create the rotation angle object
    ra = RotationAngles(beam.get_s0(), gonio.get_rotation_axis())

    # Setup the matrices
    ub = matrix.sqr(ub_matrix)
    s0 = matrix.col(beam.get_s0())
    m2 = matrix.col(gonio.get_rotation_axis())

    # For all the miller indices
    for h in integrate_handle.hkl:
        h = matrix.col(h)

        # Calculate the angles
        angles = ra(h, ub)

        # For all the angles
        for phi in angles:
            r = m2.axis_and_angle_as_r3_rotation_matrix(angle=phi)
            pstar = r * ub * h
            s1 = s0 + pstar
            assert s1.length() == pytest.approx(s0.length(), abs=1e-7)

    # Create a dict of lists of xy for each hkl
    gen_phi = {}
    for h in integrate_handle.hkl:

        # Calculate the angles
        angles = ra(h, ub)
        gen_phi[h] = angles
    #        for phi in angles:
    #            try:
    #                a = gen_phi[h]
    #                a.append(phi)
    #                gen_phi[h] = a
    #            except KeyError:
    #                gen_phi[h] = [phi]

    # For each hkl in the xds file
    for hkl, xyz in zip(integrate_handle.hkl, integrate_handle.xyzcal):

        # Calculate the XDS phi value
        xds_phi = (scan.get_oscillation(deg=False)[0] +
                   xyz[2] * scan.get_oscillation(deg=False)[1])

        # Select the nearest xy to use if there are 2
        my_phi = gen_phi[hkl]
        if len(my_phi) == 2:
            my_phi0 = my_phi[0]
            my_phi1 = my_phi[1]
            diff0 = abs(xds_phi - my_phi0)
            diff1 = abs(xds_phi - my_phi1)
            if diff0 < diff1:
                my_phi = my_phi0
            else:
                my_phi = my_phi1
        else:
            my_phi = my_phi[0]

        # Check the Phi values are the same
        assert xds_phi == pytest.approx(my_phi, abs=0.1)
Example #8
0
  def __init__(self):
    from dials.algorithms.spot_prediction import IndexGenerator
    from dials.algorithms.spot_prediction import ScanStaticRayPredictor
    from iotbx.xds import xparm, integrate_hkl
    from dials.util import ioutil
    from math import ceil
    import dxtbx
    from rstbx.cftbx.coordinate_frame_converter import \
        coordinate_frame_converter
    from scitbx import matrix

    # The XDS files to read from
    integrate_filename = join(dials_regression, 'data/sim_mx/INTEGRATE.HKL')
    gxparm_filename = join(dials_regression, 'data/sim_mx/GXPARM.XDS')

    # Read the XDS files
    self.integrate_handle = integrate_hkl.reader()
    self.integrate_handle.read_file(integrate_filename)
    self.gxparm_handle = xparm.reader()
    self.gxparm_handle.read_file(gxparm_filename)

    # Get the parameters we need from the GXPARM file
    models = dxtbx.load(gxparm_filename)
    self.beam = models.get_beam()
    self.gonio = models.get_goniometer()
    self.detector = models.get_detector()
    self.scan = models.get_scan()

    # Get crystal parameters
    self.space_group_type = ioutil.get_space_group_type_from_xparm(
        self.gxparm_handle)
    cfc = coordinate_frame_converter(gxparm_filename)
    a_vec = cfc.get('real_space_a')
    b_vec = cfc.get('real_space_b')
    c_vec = cfc.get('real_space_c')
    self.unit_cell = cfc.get_unit_cell()
    self.ub_matrix = matrix.sqr(a_vec + b_vec + c_vec).inverse()

    # Get the minimum resolution in the integrate file
    d = [self.unit_cell.d(h) for h in self.integrate_handle.hkl]
    self.d_min = min(d)
    # extend the resolution shell by epsilon>0
    # to account for rounding artifacts on 32-bit platforms
    self.d_min = self.d_min - 1e-15

    # Get the number of frames from the max z value
    xcal, ycal, zcal = zip(*self.integrate_handle.xyzcal)
    self.scan.set_image_range((self.scan.get_image_range()[0],
                             self.scan.get_image_range()[0] +
                                int(ceil(max(zcal)))))

    # Print stuff
#        print self.beam
#        print self.gonio
#        print self.detector
#        print self.scan

    # Create the index generator
    self.generate_indices = IndexGenerator(self.unit_cell,
        self.space_group_type, self.d_min)

    s0 = self.beam.get_s0()
    m2 = self.gonio.get_rotation_axis()
    fixed_rotation = self.gonio.get_fixed_rotation()
    setting_rotation = self.gonio.get_setting_rotation()
    UB = self.ub_matrix
    dphi = self.scan.get_oscillation_range(deg=False)

    # Create the ray predictor
    self.predict_rays = ScanStaticRayPredictor(s0, m2, fixed_rotation,
                                               setting_rotation, dphi)

    # Predict the spot locations
    self.reflections = self.predict_rays(
                            self.generate_indices.to_array(), UB)
def import_xds_xparm(xparm_file):
    '''Read an XDS XPARM file, transform the parameters contained therein
    into the standard coordinate frame, record this as a dictionary.'''
    from iotbx.xds import xparm

    handle = xparm.reader()
    handle.read_file(xparm_file)

    # first determine the rotation R from the XDS coordinate frame used in
    # the processing to the central (i.e. imgCIF) coordinate frame. N.B.
    # if the scan was e.g. a PHI scan the resulting frame could well come out
    # a little odd...

    axis = handle.rotation_axis
    beam = handle.beam_vector
    x, y = handle.detector_x_axis, handle.detector_y_axis

    # XDS defines the beam vector as s0 rather than from sample -> source.

    B = - matrix.col(beam).normalize()
    A = matrix.col(axis).normalize()

    X = matrix.col(x).normalize()
    Y = matrix.col(y).normalize()
    N = X.cross(Y)

    _X = matrix.col([1, 0, 0])
    _Y = matrix.col([0, 1, 0])
    _Z = matrix.col([0, 0, 1])

    R = align_reference_frame(A, _X, B, _Z)

    # now transform contents of the XPARM file to the form which we want to
    # return...

    nx, ny = handle.detector_size
    px, py = handle.pixel_size

    distance = handle.detector_distance
    ox, oy = handle.detector_origin

    a = handle.unit_cell_a_axis
    b = handle.unit_cell_b_axis
    c = handle.unit_cell_c_axis

    # Need to subtract 0.5 because XDS seems to do centroids in fortran coords
    ox = ox - 0.5
    oy = oy - 0.5

    detector_origin = R * (distance * N - ox * px * X - oy * py * Y)
    detector_fast = R * X
    detector_slow = R * Y
    rotation_axis = R * A
    sample_to_source = R * B
    wavelength = handle.wavelength
    real_space_a = R * matrix.col(a)
    real_space_b = R * matrix.col(b)
    real_space_c = R * matrix.col(c)
    space_group_number = handle.space_group
    starting_angle = handle.starting_angle
    oscillation_range = handle.oscillation_range
    starting_frame = handle.starting_frame

    panel_offset = None
    panel_size = None
    panel_origins = None
    panel_fast_axes = None
    panel_slow_axes = None

    if handle.num_segments > 1:
        # Now, for each detector segment the following two lines of information
        # are provided.

        # The 5 numbers of this line, iseg x1 x2 y1 y2, define the pixel numbers
        # IX,IY belonging to segment #iseg as x1<=IX<=x2, y1<=IY<=y2.
        # The 9 numbers of this line, ORGXS ORGYS FS EDS(:,1) EDS(:,2), describe
        # origin and orientation of segment #iseg with respect to the detector
        # coordinate system.

        panel_offset = []
        panel_size = []
        panel_origins = []
        panel_fast_axes = []
        panel_slow_axes = []
        for segment, orientation,  in zip(handle.segments, handle.orientation):
            iseg, x1, x2, y1, y2 = segment
            # XDS panel limits inclusive range
            panel_offset.append((x1-1, y1-1))
            panel_size.append((x2-x1+1, y2-y1+1))
            panel_fast = matrix.col(orientation[3:6])
            panel_slow = matrix.col(orientation[6:9])
            # local basis vectors
            fl = matrix.col(panel_fast)
            sl = matrix.col(panel_slow)
            nl = fl.cross(sl)

            orgxs, orgys, fs = orientation[:3]
            panel_origin = R * (- (orgxs - x1 + 1) * px * fl \
                                - (orgys - y1 + 1) * py * sl \
                                + fs * nl ) \
                + detector_origin

            # detector to laboratory transformation
            ED = matrix.sqr(list(X) + list(Y) + list(N))

            panel_normal = (R * panel_fast).cross(R * panel_slow)
            panel_origins.append(panel_origin)
            panel_fast_axes.append(R * ED * panel_fast)
            panel_slow_axes.append(R * ED * panel_slow)

    return coordinate_frame_information(
        detector_origin, detector_fast, detector_slow, (nx, ny), (px, py),
        rotation_axis, sample_to_source, wavelength,
        real_space_a, real_space_b, real_space_c, space_group_number,
        None, None, starting_angle, oscillation_range, starting_frame,
        original_rotation=R,
        panel_offset=panel_offset,
        panel_size=panel_size,
        panel_origin=panel_origins,
        panel_fast=panel_fast_axes,
        panel_slow=panel_slow_axes)
Example #10
0
def run():
  if not have_dials_regression:
    print "Skipping test: dials_regression not available."
    return

  from scitbx import matrix
  from iotbx.xds import xparm, integrate_hkl
  from dials.util import ioutil
  from math import ceil
  from dials.algorithms.spot_prediction import RotationAngles
  import dxtbx
  from rstbx.cftbx.coordinate_frame_converter import \
      coordinate_frame_converter

  # The XDS files to read from
  integrate_filename = join(dials_regression, 'data/sim_mx/INTEGRATE.HKL')
  gxparm_filename = join(dials_regression, 'data/sim_mx/GXPARM.XDS')

  # Read the XDS files
  integrate_handle = integrate_hkl.reader()
  integrate_handle.read_file(integrate_filename)
  gxparm_handle = xparm.reader()
  gxparm_handle.read_file(gxparm_filename)

  # Get the parameters we need from the GXPARM file
  models = dxtbx.load(gxparm_filename)
  beam = models.get_beam()
  gonio = models.get_goniometer()
  detector = models.get_detector()
  scan = models.get_scan()

  # Get the crystal parameters
  space_group_type = ioutil.get_space_group_type_from_xparm(gxparm_handle)
  cfc = coordinate_frame_converter(gxparm_filename)
  a_vec = cfc.get('real_space_a')
  b_vec = cfc.get('real_space_b')
  c_vec = cfc.get('real_space_c')
  unit_cell = cfc.get_unit_cell()
  UB = matrix.sqr(a_vec + b_vec + c_vec).inverse()
  ub_matrix = UB

  # Get the minimum resolution in the integrate file
  d = [unit_cell.d(h) for h in integrate_handle.hkl]
  d_min = min(d)

  # Get the number of frames from the max z value
  xcal, ycal, zcal = zip(*integrate_handle.xyzcal)
  num_frames = int(ceil(max(zcal)))
  scan.set_image_range((scan.get_image_range()[0],
                      scan.get_image_range()[0] + num_frames - 1))

  # Create the rotation angle object
  ra = RotationAngles(beam.get_s0(), gonio.get_rotation_axis())

  # Setup the matrices
  ub = matrix.sqr(ub_matrix)
  s0 = matrix.col(beam.get_s0())
  m2 = matrix.col(gonio.get_rotation_axis())

  # For all the miller indices
  for h in integrate_handle.hkl:
    h = matrix.col(h)

    # Calculate the angles
    angles = ra(h, ub)

    # For all the angles
    for phi in angles:
      r = m2.axis_and_angle_as_r3_rotation_matrix(angle=phi)
      pstar = r * ub * h
      s1 = s0 + pstar
      assert(abs(s1.length() - s0.length()) < 1e-7)

  print "OK"

  # Create a dict of lists of xy for each hkl
  gen_phi = {}
  for h in integrate_handle.hkl:

    # Calculate the angles
    angles = ra(h, ub)
    gen_phi[h] = angles
#        for phi in angles:
#            try:
#                a = gen_phi[h]
#                a.append(phi)
#                gen_phi[h] = a
#            except KeyError:
#                gen_phi[h] = [phi]

  # For each hkl in the xds file
  for hkl, xyz in zip(integrate_handle.hkl,
                      integrate_handle.xyzcal):

    # Calculate the XDS phi value
    xds_phi = scan.get_oscillation(deg=False)[0] + \
              xyz[2]*scan.get_oscillation(deg=False)[1]

    # Select the nearest xy to use if there are 2
    my_phi = gen_phi[hkl]
    if len(my_phi) == 2:
      my_phi0 = my_phi[0]
      my_phi1 = my_phi[1]
      diff0 = abs(xds_phi - my_phi0)
      diff1 = abs(xds_phi - my_phi1)
      if diff0 < diff1:
        my_phi = my_phi0
      else:
        my_phi = my_phi1
    else:
      my_phi = my_phi[0]

    # Check the Phi values are the same
    assert(abs(xds_phi - my_phi) < 0.1)

  # Test Passed
  print "OK"
Example #11
0
    def _integrate_finish(self):
        """Finish off the integration by running correct."""

        # first run the postrefinement etc with spacegroup P1
        # and the current unit cell - this will be used to
        # obtain a benchmark rmsd in pixels / phi and also
        # cell deviations (this is working towards spotting bad
        # indexing solutions) - only do this if we have no
        # reindex matrix... and no postrefined cell...

        p1_deviations = None

        # fix for bug # 3264 -
        # if we have not run integration with refined parameters, make it so...
        # erm? shouldn't this therefore return if this is the principle, or
        # set the flag after we have tested the lattice?

        if ("GXPARM.XDS" not in self._xds_data_files
                and PhilIndex.params.xds.integrate.reintegrate):
            logger.debug(
                "Resetting integrater, to ensure refined orientation is used")
            self.set_integrater_done(False)

        if (not self.get_integrater_reindex_matrix() and not self._intgr_cell
                and PhilIndex.params.xia2.settings.lattice_rejection
                and not self.get_integrater_sweep().get_user_lattice()):
            correct = self.Correct()

            correct.set_data_range(
                self._intgr_wedge[0] + self.get_frame_offset(),
                self._intgr_wedge[1] + self.get_frame_offset(),
            )

            if self.get_polarization() > 0.0:
                correct.set_polarization(self.get_polarization())

            # FIXME should this be using the correctly transformed
            # cell or are the results ok without it?!

            correct.set_spacegroup_number(1)
            correct.set_cell(self._intgr_refiner_cell)

            correct.run()

            cell = correct.get_result("cell")
            cell_esd = correct.get_result("cell_esd")

            logger.debug("Postrefinement in P1 results:")
            logger.debug("%7.3f %7.3f %7.3f %7.3f %7.3f %7.3f" % tuple(cell))
            logger.debug("%7.3f %7.3f %7.3f %7.3f %7.3f %7.3f" %
                         tuple(cell_esd))
            logger.debug("Deviations: %.2f pixels %.2f degrees" %
                         (correct.get_result("rmsd_pixel"),
                          correct.get_result("rmsd_phi")))

            p1_deviations = (
                correct.get_result("rmsd_pixel"),
                correct.get_result("rmsd_phi"),
            )

        # next run the postrefinement etc with the given
        # cell / lattice - this will be the assumed result...

        integrate_hkl = os.path.join(self.get_working_directory(),
                                     "INTEGRATE.HKL")

        if PhilIndex.params.xia2.settings.input.format.dynamic_shadowing:
            from dxtbx.serialize import load
            from dials.algorithms.shadowing.filter import filter_shadowed_reflections

            experiments_json = xparm_xds_to_experiments_json(
                os.path.join(self.get_working_directory(), "XPARM.XDS"),
                self.get_working_directory(),
            )
            experiments = load.experiment_list(experiments_json,
                                               check_format=True)
            imageset = experiments[0].imageset
            masker = (imageset.get_format_class().get_instance(
                imageset.paths()[0]).get_masker())
            if masker is not None:
                integrate_filename = integrate_hkl_to_reflection_file(
                    integrate_hkl, experiments_json,
                    self.get_working_directory())
                reflections = flex.reflection_table.from_file(
                    integrate_filename)

                t0 = time.time()
                sel = filter_shadowed_reflections(experiments, reflections)
                shadowed = reflections.select(sel)
                t1 = time.time()
                logger.debug("Filtered %i reflections in %.1f seconds" %
                             (sel.count(True), t1 - t0))

                filter_hkl = os.path.join(self.get_working_directory(),
                                          "FILTER.HKL")
                with open(filter_hkl, "wb") as f:
                    detector = experiments[0].detector
                    for ref in shadowed:
                        p = detector[ref["panel"]]
                        ox, oy = p.get_raw_image_offset()
                        h, k, l = ref["miller_index"]
                        x, y, z = ref["xyzcal.px"]
                        dx, dy, dz = (2, 2, 2)
                        print(
                            "%i %i %i %.1f %.1f %.1f %.1f %.1f %.1f" %
                            (h, k, l, x + ox, y + oy, z, dx, dy, dz),
                            file=f,
                        )
                t2 = time.time()
                logger.debug("Written FILTER.HKL in %.1f seconds" % (t2 - t1))

        correct = self.Correct()

        correct.set_data_range(
            self._intgr_wedge[0] + self.get_frame_offset(),
            self._intgr_wedge[1] + self.get_frame_offset(),
        )

        if self.get_polarization() > 0.0:
            correct.set_polarization(self.get_polarization())

        # BUG # 2695 probably comes from here - need to check...
        # if the pointless interface comes back with a different
        # crystal setting then the unit cell stored in self._intgr_cell
        # needs to be set to None...

        if self.get_integrater_spacegroup_number():
            correct.set_spacegroup_number(
                self.get_integrater_spacegroup_number())
            if not self._intgr_cell:
                raise RuntimeError("no unit cell to recycle")
            correct.set_cell(self._intgr_cell)

        # BUG # 3113 - new version of XDS will try and figure the
        # best spacegroup out from the intensities (and get it wrong!)
        # unless we set the spacegroup and cell explicitly

        if not self.get_integrater_spacegroup_number():
            cell = self._intgr_refiner_cell
            lattice = self._intgr_refiner.get_refiner_lattice()
            spacegroup_number = lattice_to_spacegroup_number(lattice)

            # this should not prevent the postrefinement from
            # working correctly, else what is above would not
            # work correctly (the postrefinement test)

            correct.set_spacegroup_number(spacegroup_number)
            correct.set_cell(cell)

            logger.debug("Setting spacegroup to: %d" % spacegroup_number)
            logger.debug("Setting cell to: %.2f %.2f %.2f %.2f %.2f %.2f" %
                         tuple(cell))

        if self.get_integrater_reindex_matrix():

            # bug! if the lattice is not primitive the values in this
            # reindex matrix need to be multiplied by a constant which
            # depends on the Bravais lattice centering.

            lattice = self._intgr_refiner.get_refiner_lattice()

            matrix = self.get_integrater_reindex_matrix()
            matrix = scitbx.matrix.sqr(matrix).transpose().elems
            matrix = r_to_rt(matrix)

            if lattice[1] == "P":
                mult = 1
            elif lattice[1] == "C" or lattice[1] == "I":
                mult = 2
            elif lattice[1] == "R":
                mult = 3
            elif lattice[1] == "F":
                mult = 4
            else:
                raise RuntimeError("unknown multiplier for lattice %s" %
                                   lattice)

            logger.debug("REIDX multiplier for lattice %s: %d" %
                         (lattice, mult))

            mult_matrix = [mult * m for m in matrix]

            logger.debug("REIDX set to %d %d %d %d %d %d %d %d %d %d %d %d" %
                         tuple(mult_matrix))
            correct.set_reindex_matrix(mult_matrix)

        correct.run()

        # record the log file -

        pname, xname, dname = self.get_integrater_project_info()
        sweep = self.get_integrater_sweep_name()
        FileHandler.record_log_file(
            f"{pname} {xname} {dname} {sweep} CORRECT",
            os.path.join(self.get_working_directory(), "CORRECT.LP"),
        )

        FileHandler.record_more_data_file(
            f"{pname} {xname} {dname} {sweep} CORRECT",
            os.path.join(self.get_working_directory(), "XDS_ASCII.HKL"),
        )

        # erm. just to be sure
        if self.get_integrater_reindex_matrix() and correct.get_reindex_used():
            raise RuntimeError("Reindex panic!")

        # get the reindex operation used, which may be useful if none was
        # set but XDS decided to apply one, e.g. #419.

        if not self.get_integrater_reindex_matrix(
        ) and correct.get_reindex_used():
            # convert this reindex operation to h, k, l form: n.b. this
            # will involve dividing through by the lattice centring multiplier

            matrix = rt_to_r(correct.get_reindex_used())

            matrix = scitbx.matrix.sqr(matrix).transpose().elems

            lattice = self._intgr_refiner.get_refiner_lattice()

            if lattice[1] == "P":
                mult = 1.0
            elif lattice[1] == "C" or lattice[1] == "I":
                mult = 2.0
            elif lattice[1] == "R":
                mult = 3.0
            elif lattice[1] == "F":
                mult = 4.0

            matrix = [m / mult for m in matrix]

            reindex_op = mat_to_symop(matrix)

            # assign this to self: will this reset?! make for a leaky
            # abstraction and just assign this...

            # self.set_integrater_reindex_operator(reindex)

            self._intgr_reindex_operator = reindex_op

        # record the log file -

        pname, xname, dname = self.get_integrater_project_info()
        sweep = self.get_integrater_sweep_name()
        FileHandler.record_log_file(
            f"{pname} {xname} {dname} {sweep} CORRECT",
            os.path.join(self.get_working_directory(), "CORRECT.LP"),
        )

        # should get some interesting stuff from the XDS correct file
        # here, for instance the resolution range to use in integration
        # (which should be fed back if not fast) and so on...

        self._intgr_corrected_hklout = os.path.join(
            self.get_working_directory(), "XDS_ASCII.HKL")

        # also record the batch range - needed for the analysis of the
        # radiation damage in chef...

        self._intgr_batches_out = (self._intgr_wedge[0], self._intgr_wedge[1])

        # FIXME perhaps I should also feedback the GXPARM file here??
        for file in ["GXPARM.XDS"]:
            self._xds_data_files[file] = correct.get_output_data_file(file)

        # record the postrefined cell parameters
        self._intgr_cell = correct.get_result("cell")
        self._intgr_n_ref = correct.get_result("n_ref")

        logger.debug('Postrefinement in "correct" spacegroup results:')
        logger.debug("%7.3f %7.3f %7.3f %7.3f %7.3f %7.3f" %
                     tuple(correct.get_result("cell")))
        logger.debug("%7.3f %7.3f %7.3f %7.3f %7.3f %7.3f" %
                     tuple(correct.get_result("cell_esd")))
        logger.debug(
            "Deviations: %.2f pixels %.2f degrees" %
            (correct.get_result("rmsd_pixel"), correct.get_result("rmsd_phi")))

        logger.debug("Error correction parameters: A=%.3f B=%.3f" %
                     correct.get_result("sdcorrection"))

        # compute misorientation of axes

        xparm_file = os.path.join(self.get_working_directory(), "GXPARM.XDS")

        handle = xparm.reader()
        handle.read_file(xparm_file)

        rotn = handle.rotation_axis
        beam = handle.beam_vector

        dot = sum(rotn[j] * beam[j] for j in range(3))
        r = math.sqrt(sum(rotn[j] * rotn[j] for j in range(3)))
        b = math.sqrt(sum(beam[j] * beam[j] for j in range(3)))

        rtod = 180.0 / math.pi

        angle = rtod * math.fabs(0.5 * math.pi - math.acos(dot / (r * b)))

        logger.debug("Axis misalignment %.2f degrees" % angle)

        correct_deviations = (
            correct.get_result("rmsd_pixel"),
            correct.get_result("rmsd_phi"),
        )

        if p1_deviations:
            # compare and reject if both > 50% higher - though adding a little
            # flexibility - 0.5 pixel / osc width slack.

            pixel = p1_deviations[0]
            phi = math.sqrt(0.05 * 0.05 + p1_deviations[1] * p1_deviations[1])

            threshold = PhilIndex.params.xia2.settings.lattice_rejection_threshold
            logger.debug("RMSD ratio: %.2f" % (correct_deviations[0] / pixel))
            logger.debug("RMSPhi ratio: %.2f" % (correct_deviations[1] / phi))

            if (correct_deviations[0] / pixel > threshold
                    and correct_deviations[1] / phi > threshold):

                logger.info(
                    "Eliminating this indexing solution as postrefinement")
                logger.info("deviations rather high relative to triclinic")
                raise BadLatticeError(
                    "high relative deviations in postrefinement")

        if (not PhilIndex.params.dials.fast_mode
                and not PhilIndex.params.xds.keep_outliers):
            # check for alien reflections and perhaps recycle - removing them
            correct_remove = correct.get_remove()
            if correct_remove:
                current_remove = set()
                final_remove = []

                # first ensure that there are no duplicate entries...
                if os.path.exists(
                        os.path.join(self.get_working_directory(),
                                     "REMOVE.HKL")):
                    with open(
                            os.path.join(self.get_working_directory(),
                                         "REMOVE.HKL")) as fh:
                        for line in fh.readlines():
                            h, k, l = list(map(int, line.split()[:3]))
                            z = float(line.split()[3])

                            if (h, k, l, z) not in current_remove:
                                current_remove.add((h, k, l, z))

                    for c in correct_remove:
                        if c in current_remove:
                            continue
                        final_remove.append(c)

                    logger.debug("%d alien reflections are already removed" %
                                 (len(correct_remove) - len(final_remove)))
                else:
                    # we want to remove all of the new dodgy reflections
                    final_remove = correct_remove

                z_min = PhilIndex.params.xds.z_min
                rejected = 0

                with open(
                        os.path.join(self.get_working_directory(),
                                     "REMOVE.HKL"), "w") as remove_hkl:

                    # write in the old reflections
                    for remove in current_remove:
                        z = remove[3]
                        if z >= z_min:
                            remove_hkl.write("%d %d %d %f\n" % remove)
                        else:
                            rejected += 1
                    logger.debug("Wrote %d old reflections to REMOVE.HKL" %
                                 (len(current_remove) - rejected))
                    logger.debug("Rejected %d as z < %f" % (rejected, z_min))

                    # and the new reflections
                    rejected = 0
                    used = 0
                    for remove in final_remove:
                        z = remove[3]
                        if z >= z_min:
                            used += 1
                            remove_hkl.write("%d %d %d %f\n" % remove)
                        else:
                            rejected += 1
                    logger.debug("Wrote %d new reflections to REMOVE.HKL" %
                                 (len(final_remove) - rejected))
                    logger.debug("Rejected %d as z < %f" % (rejected, z_min))

                # we want to rerun the finishing step so...
                # unless we have added no new reflections... or unless we
                # have not confirmed the point group (see SCI-398)

                if used and self.get_integrater_reindex_matrix():
                    self.set_integrater_finish_done(False)

        else:
            logger.debug(
                "Going quickly so not removing %d outlier reflections..." %
                len(correct.get_remove()))

        # Convert INTEGRATE.HKL to MTZ format and reapply any reindexing operations
        # spacegroup changes to allow use with CCP4 / Aimless for scaling

        hklout = os.path.splitext(integrate_hkl)[0] + ".mtz"
        self._factory.set_working_directory(self.get_working_directory())
        pointless = self._factory.Pointless()
        pointless.set_xdsin(integrate_hkl)
        pointless.set_hklout(hklout)
        pointless.xds_to_mtz()

        integrate_mtz = hklout

        if (self.get_integrater_reindex_operator()
                or self.get_integrater_spacegroup_number()):

            logger.debug("Reindexing things to MTZ")

            reindex = Reindex()
            reindex.set_working_directory(self.get_working_directory())
            auto_logfiler(reindex)

            if self.get_integrater_reindex_operator():
                reindex.set_operator(self.get_integrater_reindex_operator())

            if self.get_integrater_spacegroup_number():
                reindex.set_spacegroup(self.get_integrater_spacegroup_number())

            hklout = "%s_reindex.mtz" % os.path.splitext(integrate_mtz)[0]

            reindex.set_hklin(integrate_mtz)
            reindex.set_hklout(hklout)
            reindex.reindex()
            integrate_mtz = hklout

        experiments_json = xparm_xds_to_experiments_json(
            self._xds_data_files["GXPARM.XDS"], self.get_working_directory())
        pname, xname, dname = self.get_integrater_project_info()
        sweep = self.get_integrater_sweep_name()
        FileHandler.record_more_data_file(f"{pname} {xname} {dname} {sweep}",
                                          experiments_json)
        FileHandler.record_more_data_file(
            f"{pname} {xname} {dname} {sweep} INTEGRATE", integrate_mtz)

        self._intgr_experiments_filename = experiments_json

        return integrate_mtz
Example #12
0
  def run(self):

    from iotbx.xds import xparm
    import os
    import libtbx.load_env
    from libtbx.test_utils import open_tmp_file

    iotbx_dir = libtbx.env.dist_path('iotbx')
    filename = os.path.join(iotbx_dir, 'xds', 'tests', 'XPARM.XDS')
    handle = xparm.reader()
    assert handle.find_version(filename) == 1
    handle.read_file(filename)

    print('OK')

    filename = os.path.join(iotbx_dir, 'xds', 'tests', 'NEW_XPARM.XDS')
    handle = xparm.reader()
    assert handle.find_version(filename) == 2
    handle.read_file(filename)
    print('OK')

    f = open_tmp_file(suffix='XPARM.XDS', mode='wb')
    f.close()
    writer = xparm.writer(
      handle.starting_frame,
      handle.starting_angle,
      handle.oscillation_range,
      handle.rotation_axis,
      handle.wavelength,
      handle.beam_vector,
      handle.space_group,
      handle.unit_cell,
      handle.unit_cell_a_axis,
      handle.unit_cell_b_axis,
      handle.unit_cell_c_axis,
      handle.num_segments,
      handle.detector_size,
      handle.pixel_size,
      handle.detector_origin,
      handle.detector_distance,
      handle.detector_x_axis,
      handle.detector_y_axis,
      handle.detector_normal,
      handle.segments,
      handle.orientation)
    writer.write_file(f.name)
    handle_recycled = xparm.reader()
    # make sure we wrote out version 2
    assert handle_recycled.find_version(f.name) == 2
    handle_recycled.read_file(f.name)

    for handle in (handle, handle_recycled):

      # Scan and goniometer stuff
      assert handle.starting_frame == 1
      assert handle.starting_angle == 82.0
      assert handle.oscillation_range == 0.1500
      assert handle.rotation_axis == (0.999997, -0.001590, -0.001580)

      # Beam stuff
      assert handle.wavelength == 0.976250
      assert handle.beam_vector == (0.001608, 0.004392, 1.024317)

      # Detector stuff
      assert handle.detector_size == (2463, 2527)
      assert handle.pixel_size == (0.172, 0.172)

      assert handle.detector_distance == 264.928955
      assert handle.detector_origin == (1224.856812, 1187.870972)
      assert handle.detector_x_axis == (1.0, 0.0, 0.0)
      assert handle.detector_y_axis == (0.0, 1.0, 0.0)
      assert handle.detector_normal == (0.0, 0.0, 1.0)

      # Crystal stuff
      assert handle.space_group == 75
      assert handle.unit_cell == (57.7831, 57.7831, 150.0135, 90.000, 90.000, 90.000)
      assert handle.unit_cell_a_axis == (-14.918090, -22.358297, 51.151196)
      assert handle.unit_cell_b_axis == (-19.858326, 51.608330, 16.766487)
      assert handle.unit_cell_c_axis == (-135.447952, -34.400188, -54.539391)

    # segment stuff
    assert handle_recycled.num_segments == 1
    assert handle_recycled.segments == [(1, 1, 2463, 1, 2527)]
    assert handle_recycled.orientation == [
      (0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0)]

    print('OK')
Example #13
0
def run():
  if not have_dials_regression:
    print "Skipping test: dials_regression not available."
    return

  from scitbx import matrix
  from iotbx.xds import xparm, integrate_hkl
  from dials.util import ioutil
  from math import ceil
  from dials.algorithms.spot_prediction import RotationAngles
  import dxtbx
  from rstbx.cftbx.coordinate_frame_converter import \
      coordinate_frame_converter

  # The XDS files to read from
  integrate_filename = join(dials_regression, 'data/sim_mx/INTEGRATE.HKL')
  gxparm_filename = join(dials_regression, 'data/sim_mx/GXPARM.XDS')

  # Read the XDS files
  integrate_handle = integrate_hkl.reader()
  integrate_handle.read_file(integrate_filename)
  gxparm_handle = xparm.reader()
  gxparm_handle.read_file(gxparm_filename)

  # Get the parameters we need from the GXPARM file
  models = dxtbx.load(gxparm_filename)
  beam = models.get_beam()
  gonio = models.get_goniometer()
  detector = models.get_detector()
  scan = models.get_scan()

  # Get the crystal parameters
  space_group_type = ioutil.get_space_group_type_from_xparm(gxparm_handle)
  cfc = coordinate_frame_converter(gxparm_filename)
  a_vec = cfc.get('real_space_a')
  b_vec = cfc.get('real_space_b')
  c_vec = cfc.get('real_space_c')
  unit_cell = cfc.get_unit_cell()
  UB = matrix.sqr(a_vec + b_vec + c_vec).inverse()
  ub_matrix = UB

  # Get the minimum resolution in the integrate file
  d = [unit_cell.d(h) for h in integrate_handle.hkl]
  d_min = min(d)

  # Get the number of frames from the max z value
  xcal, ycal, zcal = zip(*integrate_handle.xyzcal)
  num_frames = int(ceil(max(zcal)))
  scan.set_image_range((scan.get_image_range()[0],
                      scan.get_image_range()[0] + num_frames - 1))

  # Create the rotation angle object
  ra = RotationAngles(beam.get_s0(), gonio.get_rotation_axis())

  # Setup the matrices
  ub = matrix.sqr(ub_matrix)
  s0 = matrix.col(beam.get_s0())
  m2 = matrix.col(gonio.get_rotation_axis())

  # For all the miller indices
  for h in integrate_handle.hkl:
    h = matrix.col(h)

    # Calculate the angles
    angles = ra(h, ub)

    # For all the angles
    for phi in angles:
      r = m2.axis_and_angle_as_r3_rotation_matrix(angle=phi)
      pstar = r * ub * h
      s1 = s0 + pstar
      assert(abs(s1.length() - s0.length()) < 1e-7)

  print "OK"

  # Create a dict of lists of xy for each hkl
  gen_phi = {}
  for h in integrate_handle.hkl:

    # Calculate the angles
    angles = ra(h, ub)
    gen_phi[h] = angles
#        for phi in angles:
#            try:
#                a = gen_phi[h]
#                a.append(phi)
#                gen_phi[h] = a
#            except KeyError:
#                gen_phi[h] = [phi]

  # For each hkl in the xds file
  for hkl, xyz in zip(integrate_handle.hkl,
                      integrate_handle.xyzcal):

    # Calculate the XDS phi value
    xds_phi = scan.get_oscillation(deg=False)[0] + \
              xyz[2]*scan.get_oscillation(deg=False)[1]

    # Select the nearest xy to use if there are 2
    my_phi = gen_phi[hkl]
    if len(my_phi) == 2:
      my_phi0 = my_phi[0]
      my_phi1 = my_phi[1]
      diff0 = abs(xds_phi - my_phi0)
      diff1 = abs(xds_phi - my_phi1)
      if diff0 < diff1:
        my_phi = my_phi0
      else:
        my_phi = my_phi1
    else:
      my_phi = my_phi[0]

    # Check the Phi values are the same
    assert(abs(xds_phi - my_phi) < 0.1)

  # Test Passed
  print "OK"
def import_xds_xparm(xparm_file):
    '''Read an XDS XPARM file, transform the parameters contained therein
    into the standard coordinate frame, record this as a dictionary.'''
    from iotbx.xds import xparm

    handle = xparm.reader()
    handle.read_file(xparm_file)

    # first determine the rotation R from the XDS coordinate frame used in
    # the processing to the central (i.e. imgCIF) coordinate frame. N.B.
    # if the scan was e.g. a PHI scan the resulting frame could well come out
    # a little odd...

    axis = handle.rotation_axis
    beam = handle.beam_vector
    x, y = handle.detector_x_axis, handle.detector_y_axis

    # XDS defines the beam vector as s0 rather than from sample -> source.

    B = - matrix.col(beam).normalize()
    A = matrix.col(axis).normalize()

    X = matrix.col(x).normalize()
    Y = matrix.col(y).normalize()
    N = X.cross(Y)

    _X = matrix.col([1, 0, 0])
    _Y = matrix.col([0, 1, 0])
    _Z = matrix.col([0, 0, 1])

    R = align_reference_frame(A, _X, B, _Z)

    # now transform contents of the XPARM file to the form which we want to
    # return...

    nx, ny = handle.detector_size
    px, py = handle.pixel_size

    distance = handle.detector_distance
    ox, oy = handle.detector_origin

    a = handle.unit_cell_a_axis
    b = handle.unit_cell_b_axis
    c = handle.unit_cell_c_axis

    # Need to subtract 0.5 because XDS seems to do centroids in fortran coords
    ox = ox - 0.5
    oy = oy - 0.5

    detector_origin = R * (distance * N - ox * px * X - oy * py * Y)
    detector_fast = R * X
    detector_slow = R * Y
    rotation_axis = R * A
    sample_to_source = R * B
    wavelength = handle.wavelength
    real_space_a = R * matrix.col(a)
    real_space_b = R * matrix.col(b)
    real_space_c = R * matrix.col(c)
    space_group_number = handle.space_group
    starting_angle = handle.starting_angle
    oscillation_range = handle.oscillation_range
    starting_frame = handle.starting_frame

    return coordinate_frame_information(
        detector_origin, detector_fast, detector_slow, (nx, ny), (px, py),
        rotation_axis, sample_to_source, wavelength,
        real_space_a, real_space_b, real_space_c, space_group_number,
        None, None, starting_angle, oscillation_range, starting_frame,
        original_rotation = R)
Example #15
0
  def run(self):

    from iotbx.xds import xparm
    import os
    import libtbx.load_env
    from libtbx.test_utils import open_tmp_file

    iotbx_dir = libtbx.env.dist_path('iotbx')
    filename = os.path.join(iotbx_dir, 'xds', 'tests', 'XPARM.XDS')
    handle = xparm.reader()
    assert handle.find_version(filename) == 1
    handle.read_file(filename)

    print 'OK'

    filename = os.path.join(iotbx_dir, 'xds', 'tests', 'NEW_XPARM.XDS')
    handle = xparm.reader()
    assert handle.find_version(filename) == 2
    handle.read_file(filename)
    print 'OK'

    f = open_tmp_file(suffix='XPARM.XDS', mode='wb')
    f.close()
    writer = xparm.writer(
      handle.starting_frame,
      handle.starting_angle,
      handle.oscillation_range,
      handle.rotation_axis,
      handle.wavelength,
      handle.beam_vector,
      handle.space_group,
      handle.unit_cell,
      handle.unit_cell_a_axis,
      handle.unit_cell_b_axis,
      handle.unit_cell_c_axis,
      handle.num_segments,
      handle.detector_size,
      handle.pixel_size,
      handle.detector_origin,
      handle.detector_distance,
      handle.detector_x_axis,
      handle.detector_y_axis,
      handle.detector_normal,
      handle.segments,
      handle.orientation)
    writer.write_file(f.name)
    handle_recycled = xparm.reader()
    # make sure we wrote out version 2
    assert handle_recycled.find_version(f.name) == 2
    handle_recycled.read_file(f.name)

    for handle in (handle, handle_recycled):

      # Scan and goniometer stuff
      assert handle.starting_frame == 1
      assert handle.starting_angle == 82.0
      assert handle.oscillation_range == 0.1500
      assert handle.rotation_axis == (0.999997, -0.001590, -0.001580)

      # Beam stuff
      assert handle.wavelength == 0.976250
      assert handle.beam_vector == (0.001608, 0.004392, 1.024317)

      # Detector stuff
      assert handle.detector_size == (2463, 2527)
      assert handle.pixel_size == (0.172, 0.172)

      assert handle.detector_distance == 264.928955
      assert handle.detector_origin == (1224.856812, 1187.870972)
      assert handle.detector_x_axis == (1.0, 0.0, 0.0)
      assert handle.detector_y_axis == (0.0, 1.0, 0.0)
      assert handle.detector_normal == (0.0, 0.0, 1.0)

      # Crystal stuff
      assert handle.space_group == 75
      assert handle.unit_cell == (57.7831, 57.7831, 150.0135, 90.000, 90.000, 90.000)
      assert handle.unit_cell_a_axis == (-14.918090, -22.358297, 51.151196)
      assert handle.unit_cell_b_axis == (-19.858326, 51.608330, 16.766487)
      assert handle.unit_cell_c_axis == (-135.447952, -34.400188, -54.539391)

    # segment stuff
    assert handle_recycled.num_segments == 1
    assert handle_recycled.segments == [(1, 1, 2463, 1, 2527)]
    assert handle_recycled.orientation == [
      (0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0)]

    print 'OK'
Example #16
0
  def __init__(self):
    from dials.algorithms.spot_prediction import IndexGenerator
    from dials.algorithms.spot_prediction import ScanStaticRayPredictor
    from dials.algorithms.spot_prediction import ray_intersection
    from iotbx.xds import xparm, integrate_hkl
    from dials.util import ioutil
    from math import ceil
    from os.path import realpath, dirname, join
    import dxtbx
    from rstbx.cftbx.coordinate_frame_converter import \
        coordinate_frame_converter
    from scitbx import matrix

    # The XDS files to read from
    test_path = dirname(dirname(dirname(realpath(__file__))))
    integrate_filename = join(test_path, 'data/sim_mx/INTEGRATE.HKL')
    gxparm_filename = join(test_path, 'data/sim_mx/GXPARM.XDS')

    # Read the XDS files
    self.integrate_handle = integrate_hkl.reader()
    self.integrate_handle.read_file(integrate_filename)
    self.gxparm_handle = xparm.reader()
    self.gxparm_handle.read_file(gxparm_filename)

    # Get the parameters we need from the GXPARM file
    models = dxtbx.load(gxparm_filename)
    self.beam = models.get_beam()
    self.gonio = models.get_goniometer()
    self.detector = models.get_detector()
    self.scan = models.get_scan()

    assert(len(self.detector) == 1)

    #print self.detector

    # Get crystal parameters
    self.space_group_type = ioutil.get_space_group_type_from_xparm(
        self.gxparm_handle)
    cfc = coordinate_frame_converter(gxparm_filename)
    a_vec = cfc.get('real_space_a')
    b_vec = cfc.get('real_space_b')
    c_vec = cfc.get('real_space_c')
    self.unit_cell = cfc.get_unit_cell()
    self.ub_matrix = matrix.sqr(a_vec + b_vec + c_vec).inverse()

    # Get the minimum resolution in the integrate file
    self.d_min = self.detector[0].get_max_resolution_at_corners(
        self.beam.get_s0())

    # Get the number of frames from the max z value
    xcal, ycal, zcal = zip(*self.integrate_handle.xyzcal)
    self.scan.set_image_range((self.scan.get_image_range()[0],
                               self.scan.get_image_range()[0] +
                                int(ceil(max(zcal)))))

    # Create the index generator
    generate_indices = IndexGenerator(self.unit_cell, self.space_group_type,
                                      self.d_min)

    s0 = self.beam.get_s0()
    m2 = self.gonio.get_rotation_axis()
    fixed_rotation = self.gonio.get_fixed_rotation()
    UB = self.ub_matrix
    dphi = self.scan.get_oscillation_range(deg=False)

    # Create the ray predictor
    self.predict_rays = ScanStaticRayPredictor(s0, m2, fixed_rotation, dphi)

    # Predict the spot locations
    self.reflections = self.predict_rays(
                                    generate_indices.to_array(), UB)

    # Calculate the intersection of the detector and reflection frames
    success = ray_intersection(self.detector, self.reflections)
    self.reflections.select(success)