Example #1
0
def rotation_scattering(reflections,
                        UB_mat,
                        rotation_vector,
                        wavelength,
                        resolution,
                        assert_non_integer_index=False):
    '''Perform some kind of calculation...'''

    ra = rotation_angles(resolution, UB_mat, wavelength, rotation_vector)
    beam_vector = matrix.col([0, 0, 1 / wavelength])

    for hkl in reflections:
        if ra(hkl):
            omegas = ra.get_intersection_angles()
            if assert_non_integer_index:
                assert ra.H[0] != int(ra.H[0]) or \
                       ra.H[1] != int(ra.H[1]) or \
                       ra.H[2] != int(ra.H[2])

            for omegaidx in [0, 1]:

                rot_mat = rotation_vector.axis_and_angle_as_r3_rotation_matrix(
                    omegas[omegaidx])
                assert (-0.0001 < math.fabs(rot_mat.determinant() - 1.0) <
                        0.0001)

                H1 = (rot_mat * UB_mat) * hkl
                H1 = H1 + beam_vector
                len_H1 = math.sqrt((H1[0] * H1[0]) + (H1[1] * H1[1]) +
                                   (H1[2] * H1[2]))

                if math.fabs(len_H1 - 1.0 / wavelength) > 0.0001:
                    raise RuntimeError, 'length error for %d %d %d' % hkl
    def observed_indices_and_angles_from_angle_range(
        self, phi_start_rad, phi_end_rad, indices
    ):
        """For a list of indices, return those indices that can be rotated into
        diffracting position, along with the corresponding angles"""

        # calculate conversion matrix to rossmann frame.
        R_to_rossmann = self.align_reference_frame(
            self._beam.get_unit_s0(),
            (0.0, 0.0, 1.0),
            self._gonio.get_rotation_axis(),
            (0.0, 1.0, 0.0),
        )

        # Create a rotation_angles object for the current geometry
        ra = rotation_angles(
            self._dmin,
            R_to_rossmann * self._crystal.get_U() * self._crystal.get_B(),
            self._beam.get_wavelength(),
            R_to_rossmann * matrix.col(self._gonio.get_rotation_axis()),
        )

        (obs_indices, obs_angles) = ra.observed_indices_and_angles_from_angle_range(
            phi_start_rad=0.0, phi_end_rad=pi, indices=indices
        )

        # convert to integer miller indices
        obs_indices_int = flex.miller_index()
        for hkl in obs_indices:
            hkl = map(lambda x: int(round(x)), hkl)
            obs_indices_int.append(tuple(hkl))
        return obs_indices_int, obs_angles
    def predict(self, hkl):
        """Solve the prediction formula for the reflecting angle phi"""

        # calculate conversion matrix to rossmann frame.
        R_to_rossmann = self.align_reference_frame(
            self._beam.get_unit_s0(),
            (0.0, 0.0, 1.0),
            self._gonio.get_rotation_axis(),
            (0.0, 1.0, 0.0),
        )

        # Create a rotation_angles object for the current geometry
        ra = rotation_angles(
            self._dmin,
            R_to_rossmann * self._crystal.get_U() * self._crystal.get_B(),
            self._beam.get_wavelength(),
            R_to_rossmann * matrix.col(self._gonio.get_rotation_axis()),
        )

        if ra(hkl):

            return ra.get_intersection_angles()

        else:
            return None
  def observed_indices_and_angles_from_angle_range(self, phi_start_rad,
          phi_end_rad, indices):
    """For a list of indices, return those indices that can be rotated into
    diffracting position, along with the corresponding angles"""

    # calculate conversion matrix to rossmann frame.
    R_to_rossmann = self.align_reference_frame(
                self._beam.get_unit_s0(), (0.0, 0.0, 1.0),
                self._gonio.get_rotation_axis(), (0.0, 1.0, 0.0))

    # Create a rotation_angles object for the current geometry
    ra = rotation_angles(self._dmin,
             R_to_rossmann * self._crystal.get_U() * self._crystal.get_B(),
             self._beam.get_wavelength(),
             R_to_rossmann * matrix.col(self._gonio.get_rotation_axis()))

    (obs_indices,
     obs_angles) = ra.observed_indices_and_angles_from_angle_range(
        phi_start_rad = 0.0, phi_end_rad = pi, indices = indices)

    # convert to integer miller indices
    obs_indices_int = flex.miller_index()
    for hkl in obs_indices:
      hkl = map(lambda x: int(round(x)), hkl)
      obs_indices_int.append(tuple(hkl))
    return obs_indices_int, obs_angles
def rotation_scattering(reflections, UB_mat, rotation_vector,
                        wavelength, resolution,
                        assert_non_integer_index = False):
    '''Perform some kind of calculation...'''

    ra = rotation_angles(resolution, UB_mat, wavelength, rotation_vector)
    beam_vector = matrix.col([0, 0, 1 / wavelength])

    for hkl in reflections:
        if ra(hkl):
            omegas = ra.get_intersection_angles()
            if assert_non_integer_index:
                assert ra.H[0] != int(ra.H[0]) or \
                       ra.H[1] != int(ra.H[1]) or \
                       ra.H[2] != int(ra.H[2])

            for omegaidx in [0,1]:

                rot_mat = rotation_vector.axis_and_angle_as_r3_rotation_matrix(
                    omegas[omegaidx])
                assert(
                    -0.0001 < math.fabs(rot_mat.determinant() - 1.0) < 0.0001)

                H1 = (rot_mat * UB_mat)*hkl
                H1 =  H1 + beam_vector
                len_H1 = math.sqrt((H1[0] * H1[0]) +
                                   (H1[1] * H1[1]) +
                                   (H1[2] * H1[2]))

                if math.fabs(len_H1 - 1.0 / wavelength) > 0.0001:
                    raise RuntimeError, 'length error for %d %d %d' % hkl
Example #6
0
    def get_predicted_spot_positions_and_status(
            self,
            old_status=None
    ):  #similar to above function; above can be refactored
        panel = self.detector[0]
        from scitbx import matrix
        Astar = matrix.sqr(self.getOrientation().reciprocal_matrix())
        # must have set the basis in order to generate Astar matrix.  How to assert this has been done???

        import math, copy
        xyz = self.getXyzData()
        if old_status is None:
            spot_status = [SpotClass.GOOD] * len(xyz)
        else:
            assert len(old_status) == len(xyz)
            spot_status = copy.copy(
                old_status)  # valid way of copying enums w/o reference
        self.assigned_hkl = [(0, 0, 0)] * len(xyz)

        # step 1.  Deduce fractional HKL values from the XyzData.  start with x = A* h
        #          solve for h:  h = (A*^-1) x
        Astarinv = Astar.inverse()
        Hint = flex.vec3_double()
        results = flex.vec3_double()
        for x in xyz:
            H = Astarinv * x
            Hint.append((round(H[0], 0), round(H[1], 0), round(H[2], 0)))
        xyz_miller = flex.vec3_double()
        from rstbx.diffraction import rotation_angles
        ra = rotation_angles(limiting_resolution=1.0,
                             orientation=Astar,
                             wavelength=1. / self.inv_wave,
                             axial_direction=self.axis)
        for ij, hkl in enumerate(Hint):
            xyz_miller.append(
                Astar *
                hkl)  # figure out how to do this efficiently on vector data
            if ra(hkl):
                omegas = ra.get_intersection_angles()
                rotational_diffs = [
                    abs((-omegas[omegaidx] * 180. / math.pi) -
                        self.raw_spot_input[ij][2]) for omegaidx in [0, 1]
                ]
                min_diff = min(rotational_diffs)
                min_index = rotational_diffs.index(min_diff)
                omega = omegas[min_index]
                rot_mat = self.axis.axis_and_angle_as_r3_rotation_matrix(omega)

                Svec = (rot_mat * Astar) * hkl + self.S0_vector
                if self.panelID is not None:
                    panel = self.detector[self.panelID[ij]]
                xy = panel.get_ray_intersection(Svec)
                results.append((xy[0], xy[1], 0.0))
                self.assigned_hkl[ij] = hkl
            else:
                results.append((0.0, 0.0, 0.0))
                spot_status[ij] = SpotClass.NONE
        return results, spot_status
Example #7
0
    def model_likelihood(self, separation_mm):
        TOLERANCE = 0.5
        fraction_properly_predicted = 0.0

        #help(self.detector)
        #print self.detector[0]
        #help(self.detector[0])
        panel = self.detector[0]
        from scitbx import matrix
        Astar = matrix.sqr(self.getOrientation().reciprocal_matrix())

        import math
        xyz = self.getXyzData()

        # step 1.  Deduce fractional HKL values from the XyzData.  start with x = A* h
        #          solve for h:  h = (A*^-1) x
        Astarinv = Astar.inverse()
        Hint = flex.vec3_double()
        for x in xyz:
            H = Astarinv * x
            #print "%7.3f %7.3f %7.3f"%(H[0],H[1],H[2])
            Hint.append((round(H[0], 0), round(H[1], 0), round(H[2], 0)))
        xyz_miller = flex.vec3_double()
        from rstbx.diffraction import rotation_angles
        # XXX limiting shell of 1.0 angstroms probably needs to be changed/ removed.  How?
        ra = rotation_angles(limiting_resolution=1.0,
                             orientation=Astar,
                             wavelength=1. / self.inv_wave,
                             axial_direction=self.axis)
        for ij, hkl in enumerate(Hint):
            xyz_miller.append(
                Astar *
                hkl)  # figure out how to do this efficiently on vector data
            if ra(hkl):
                omegas = ra.get_intersection_angles()
                rotational_diffs = [
                    abs((-omegas[omegaidx] * 180. / math.pi) -
                        self.raw_spot_input[ij][2]) for omegaidx in [0, 1]
                ]
                min_diff = min(rotational_diffs)
                min_index = rotational_diffs.index(min_diff)
                omega = omegas[min_index]
                rot_mat = self.axis.axis_and_angle_as_r3_rotation_matrix(omega)

                Svec = (rot_mat * Astar) * hkl + self.S0_vector
                #        print panel.get_ray_intersection(Svec), self.raw_spot_input[ij]
                if self.panelID is not None:
                    panel = self.detector[self.panelID[ij]]
                calc = matrix.col(panel.get_ray_intersection(Svec))
                pred = matrix.col(self.raw_spot_input[ij][0:2])
                #        print (calc-pred).length(), separation_mm * TOLERANCE
                if ((calc - pred).length() < separation_mm * TOLERANCE):
                    fraction_properly_predicted += 1. / self.raw_spot_input.size(
                    )
        #print "fraction properly predicted",fraction_properly_predicted,"with spot sep (mm)",separation_mm
        return fraction_properly_predicted
Example #8
0
def regression_test():
    """Perform a regression test by comparing to indices generating
  by the brute force method used in the Use Case."""

    from rstbx.diffraction import rotation_angles
    from rstbx.diffraction import full_sphere_indices
    from cctbx.sgtbx import space_group, space_group_symbols
    from cctbx.uctbx import unit_cell

    # cubic, 50A cell, 1A radiation, 1 deg osciillation, everything ideal

    a = 50.0

    ub_beg = matrix.sqr(
        (1.0 / a, 0.0, 0.0, 0.0, 1.0 / a, 0.0, 0.0, 0.0, 1.0 / a))

    axis = matrix.col((0, 1, 0))

    r_osc = matrix.sqr(
        scitbx.math.r3_rotation_axis_and_angle_as_matrix(axis=axis,
                                                         angle=1.0,
                                                         deg=True))

    ub_end = r_osc * ub_beg

    uc = unit_cell((a, a, a, 90, 90, 90))
    sg = space_group(space_group_symbols('P23').hall())

    s0 = matrix.col((0, 0, 1))

    wavelength = 1.0
    dmin = 1.5

    indices = full_sphere_indices(unit_cell=uc,
                                  resolution_limit=dmin,
                                  space_group=sg)

    ra = rotation_angles(dmin, ub_beg, wavelength, axis)

    obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range(
        phi_start_rad=0.0 * pi / 180.0,
        phi_end_rad=1.0 * pi / 180.0,
        indices=indices)

    r = reeke_model(ub_beg, ub_end, axis, s0, dmin, 1.0)
    reeke_indices = r.generate_indices()
    #r.visualize_with_rgl()

    for oi in obs_indices:
        assert (tuple(map(int, oi)) in reeke_indices)

    #TODO Tests for an oblique cell

    print "OK"
Example #9
0
  def model_likelihood(self,separation_mm):
    TOLERANCE = 0.5
    fraction_properly_predicted = 0.0

    #help(self.detector)
    #print self.detector[0]
    #help(self.detector[0])
    panel = self.detector[0]
    from scitbx import matrix
    Astar = matrix.sqr(self.getOrientation().reciprocal_matrix())

    import math
    xyz = self.getXyzData()

    # step 1.  Deduce fractional HKL values from the XyzData.  start with x = A* h
    #          solve for h:  h = (A*^-1) x
    Astarinv = Astar.inverse()
    Hint = flex.vec3_double()
    for x in xyz:
      H = Astarinv * x
      #print "%7.3f %7.3f %7.3f"%(H[0],H[1],H[2])
      Hint.append((round(H[0],0), round(H[1],0), round(H[2],0)))
    xyz_miller = flex.vec3_double()
    from rstbx.diffraction import rotation_angles
    # XXX limiting shell of 1.0 angstroms probably needs to be changed/ removed.  How?
    ra = rotation_angles(limiting_resolution=1.0,orientation = Astar,
                         wavelength = 1./self.inv_wave, axial_direction = self.axis)
    for ij,hkl in enumerate(Hint):
      xyz_miller.append( Astar * hkl ) # figure out how to do this efficiently on vector data
      if ra(hkl):
        omegas = ra.get_intersection_angles()
        rotational_diffs = [ abs((-omegas[omegaidx] * 180./math.pi)-self.raw_spot_input[ij][2])
                             for omegaidx in [0,1] ]
        min_diff = min(rotational_diffs)
        min_index = rotational_diffs.index(min_diff)
        omega = omegas[min_index]
        rot_mat = self.axis.axis_and_angle_as_r3_rotation_matrix(omega)

        Svec = (rot_mat * Astar) * hkl + self.S0_vector
#        print panel.get_ray_intersection(Svec), self.raw_spot_input[ij]
        if self.panelID is not None: panel = self.detector[ self.panelID[ij] ]
        calc = matrix.col(panel.get_ray_intersection(Svec))
        pred = matrix.col(self.raw_spot_input[ij][0:2])
#        print (calc-pred).length(), separation_mm * TOLERANCE
        if ((calc-pred).length() < separation_mm * TOLERANCE):
          fraction_properly_predicted += 1./ self.raw_spot_input.size()
    #print "fraction properly predicted",fraction_properly_predicted,"with spot sep (mm)",separation_mm
    return fraction_properly_predicted
Example #10
0
def scattering_prediction(reflections,
                          UB_mat,
                          rotation_vector,
                          wavelength,
                          resolution,
                          assert_non_integer_index=False):
    '''Test the reflection_prediction class.'''

    ra = rotation_angles(resolution, UB_mat, wavelength, rotation_vector)
    beam_vector = matrix.col([0, 0, 1 / wavelength])

    detector_size = 100
    detector_distance = 100

    s = sensor(
        matrix.col(
            (-0.5 * detector_size, -0.5 * detector_size, detector_distance)),
        matrix.col((1, 0, 0)), matrix.col((0, 1, 0)), (0, detector_size),
        (0, detector_size))
    rp = reflection_prediction(rotation_vector, beam_vector, UB_mat, s)

    for hkl in reflections:
        if ra(hkl):
            omegas = ra.get_intersection_angles()
            if assert_non_integer_index:
                assert ra.H[0] != int(ra.H[0]) or \
                       ra.H[1] != int(ra.H[1]) or \
                       ra.H[2] != int(ra.H[2])

            for omegaidx in [0, 1]:

                rot_mat = rotation_vector.axis_and_angle_as_r3_rotation_matrix(
                    omegas[omegaidx])

                assert (math.fabs(rot_mat.determinant() - 1.0) < 0.0001)

                H1 = (rot_mat * UB_mat) * hkl
                H1 = H1 + beam_vector
                len_H1 = math.sqrt((H1[0] * H1[0]) + (H1[1] * H1[1]) +
                                   (H1[2] * H1[2]))

                if math.fabs(len_H1 - 1.0 / wavelength) > 0.0001:
                    raise RuntimeError, 'length error for %d %d %d' % hkl

                if rp(hkl, omegas[omegaidx]):
                    x, y = rp.get_prediction()
                    assert (0 < x < detector_size)
                    assert (0 < y < detector_size)
Example #11
0
  def get_predicted_spot_positions_and_status(self, old_status=None): #similar to above function; above can be refactored
    panel = self.detector[0]
    from scitbx import matrix
    Astar = matrix.sqr(self.getOrientation().reciprocal_matrix())
    # must have set the basis in order to generate Astar matrix.  How to assert this has been done???

    import math,copy
    xyz = self.getXyzData()
    if old_status is None:
      spot_status = [SpotClass.GOOD]*len(xyz)
    else:
      assert len(old_status)==len(xyz)
      spot_status = copy.copy( old_status ) # valid way of copying enums w/o reference
    self.assigned_hkl= [(0,0,0)]*len(xyz)

    # step 1.  Deduce fractional HKL values from the XyzData.  start with x = A* h
    #          solve for h:  h = (A*^-1) x
    Astarinv = Astar.inverse()
    Hint = flex.vec3_double()
    results = flex.vec3_double()
    for x in xyz:
      H = Astarinv * x
      Hint.append((round(H[0],0), round(H[1],0), round(H[2],0)))
    xyz_miller = flex.vec3_double()
    from rstbx.diffraction import rotation_angles
    ra = rotation_angles(limiting_resolution=1.0,orientation = Astar,
                         wavelength = 1./self.inv_wave, axial_direction = self.axis)
    for ij,hkl in enumerate(Hint):
      xyz_miller.append( Astar * hkl ) # figure out how to do this efficiently on vector data
      if ra(hkl):
        omegas = ra.get_intersection_angles()
        rotational_diffs = [ abs((-omegas[omegaidx] * 180./math.pi)-self.raw_spot_input[ij][2])
                             for omegaidx in [0,1] ]
        min_diff = min(rotational_diffs)
        min_index = rotational_diffs.index(min_diff)
        omega = omegas[min_index]
        rot_mat = self.axis.axis_and_angle_as_r3_rotation_matrix(omega)

        Svec = (rot_mat * Astar) * hkl + self.S0_vector
        if self.panelID is not None: panel = self.detector[ self.panelID[ij] ]
        xy = panel.get_ray_intersection(Svec)
        results.append((xy[0],xy[1],0.0))
        self.assigned_hkl[ij]=hkl
      else:
        results.append((0.0,0.0,0.0))
        spot_status[ij]=SpotClass.NONE
    return results,spot_status
def scattering_prediction(reflections, UB_mat, rotation_vector,
                          wavelength, resolution,
                          assert_non_integer_index = False):
    '''Test the reflection_prediction class.'''

    ra = rotation_angles(resolution, UB_mat, wavelength, rotation_vector)
    beam_vector = matrix.col([0, 0, 1 / wavelength])

    detector_size = 100
    detector_distance = 100

    s =  sensor(matrix.col((- 0.5 * detector_size,
                            - 0.5 * detector_size,
                            detector_distance)),
                matrix.col((1, 0, 0)),
                matrix.col((0, 1, 0)),
                (0, detector_size), (0, detector_size))
    rp = reflection_prediction(rotation_vector, beam_vector, UB_mat, s)

    for hkl in reflections:
        if ra(hkl):
            omegas = ra.get_intersection_angles()
            if assert_non_integer_index:
                assert ra.H[0] != int(ra.H[0]) or \
                       ra.H[1] != int(ra.H[1]) or \
                       ra.H[2] != int(ra.H[2])

            for omegaidx in [0,1]:

                rot_mat = rotation_vector.axis_and_angle_as_r3_rotation_matrix(
                    omegas[omegaidx])

                assert(math.fabs(rot_mat.determinant() - 1.0) < 0.0001)

                H1 = (rot_mat * UB_mat)*hkl
                H1 =  H1 + beam_vector
                len_H1 = math.sqrt((H1[0] * H1[0]) +
                                   (H1[1] * H1[1]) +
                                   (H1[2] * H1[2]))

                if math.fabs(len_H1 - 1.0 / wavelength) > 0.0001:
                    raise RuntimeError, 'length error for %d %d %d' % hkl

                if rp(hkl, omegas[omegaidx]):
                    x, y = rp.get_prediction()
                    assert(0 < x < detector_size)
                    assert(0 < y < detector_size)
Example #13
0
def regression_test():
    """Perform a regression test by comparing to indices generating
  by the brute force method used in the Use Case."""

    from rstbx.diffraction import rotation_angles
    from rstbx.diffraction import full_sphere_indices
    from cctbx.sgtbx import space_group, space_group_symbols
    from cctbx.uctbx import unit_cell

    # cubic, 50A cell, 1A radiation, 1 deg osciillation, everything ideal

    a = 50.0

    ub_beg = matrix.sqr((1.0 / a, 0.0, 0.0, 0.0, 1.0 / a, 0.0, 0.0, 0.0, 1.0 / a))

    axis = matrix.col((0, 1, 0))

    r_osc = matrix.sqr(scitbx.math.r3_rotation_axis_and_angle_as_matrix(axis=axis, angle=1.0, deg=True))

    ub_end = r_osc * ub_beg

    uc = unit_cell((a, a, a, 90, 90, 90))
    sg = space_group(space_group_symbols("P23").hall())

    s0 = matrix.col((0, 0, 1))

    wavelength = 1.0
    dmin = 1.5

    indices = full_sphere_indices(unit_cell=uc, resolution_limit=dmin, space_group=sg)

    ra = rotation_angles(dmin, ub_beg, wavelength, axis)

    obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range(
        phi_start_rad=0.0 * pi / 180.0, phi_end_rad=1.0 * pi / 180.0, indices=indices
    )

    r = reeke_model(ub_beg, ub_end, axis, s0, dmin, 1.0)
    reeke_indices = r.generate_indices()
    # r.visualize_with_rgl()

    for oi in obs_indices:
        assert tuple(map(int, oi)) in reeke_indices

    # TODO Tests for an oblique cell

    print "OK"
def test_versus_brute_force():
    """Perform a regression test by comparing to indices generated by the brute
    force method"""

    # cubic, 50A cell, 1A radiation, 1 deg osciillation, everything ideal
    a = 50.0
    ub_beg = matrix.sqr(
        (1.0 / a, 0.0, 0.0, 0.0, 1.0 / a, 0.0, 0.0, 0.0, 1.0 / a))
    axis = matrix.col((0, 1, 0))
    r_osc = matrix.sqr(
        r3_rotation_axis_and_angle_as_matrix(axis=axis, angle=1.0, deg=True))
    ub_end = r_osc * ub_beg
    uc = unit_cell((a, a, a, 90, 90, 90))
    sg = space_group(space_group_symbols("P23").hall())
    s0 = matrix.col((0, 0, 1))
    wavelength = 1.0
    dmin = 1.5

    # get the full set of indices
    indices = full_sphere_indices(unit_cell=uc,
                                  resolution_limit=dmin,
                                  space_group=sg)

    # find the observed indices
    ra = rotation_angles(dmin, ub_beg, wavelength, axis)
    obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range(
        phi_start_rad=0.0 * math.pi / 180.0,
        phi_end_rad=1.0 * math.pi / 180.0,
        indices=indices,
    )

    # r = reeke_model(ub_beg, ub_end, axis, s0, dmin, 1.0)
    # reeke_indices = r.generate_indices()

    # now try the Reeke method to generate indices
    r = ReekeIndexGenerator(ub_beg,
                            ub_end,
                            sg.type(),
                            axis,
                            s0,
                            dmin,
                            margin=1)
    reeke_indices = r.to_array()

    for oi in obs_indices:
        assert tuple(map(int, oi)) in reeke_indices
  def predict(self, hkl):
    """Solve the prediction formula for the reflecting angle phi"""

    # calculate conversion matrix to rossmann frame.
    R_to_rossmann = self.align_reference_frame(
                self._beam.get_unit_s0(), (0.0, 0.0, 1.0),
                self._gonio.get_rotation_axis(), (0.0, 1.0, 0.0))

    # Create a rotation_angles object for the current geometry
    ra = rotation_angles(self._dmin,
             R_to_rossmann * self._crystal.get_U() * self._crystal.get_B(),
             self._beam.get_wavelength(),
             R_to_rossmann * matrix.col(self._gonio.get_rotation_axis()))

    if ra(hkl):

      return ra.get_intersection_angles()

    else: return None
Example #16
0
def generate_intersection_angles(a_matrix, dmin, wavelength, indices):
    """From an A matrix following the Mosflm convention and the list of
    indices, return a list of phi, (h, k, l) where (typically) there will be
    two records corresponding to each h, k, l."""

    from rstbx.diffraction import rotation_angles
    from scitbx import matrix
    import math

    ra = rotation_angles(dmin, a_matrix, wavelength, matrix.col((0, 1, 0)))

    phi_hkl = []

    r2d = 180.0 / math.pi

    for i in indices:
        if ra(i):
            phis = ra.get_intersection_angles()
            phi_hkl.append((phis[0] * r2d % 360, i))
            phi_hkl.append((phis[1] * r2d % 360, i))

    return phi_hkl
def generate_intersection_angles(a_matrix, dmin, wavelength, indices):
  '''From an A matrix following the Mosflm convention and the list of
  indices, return a list of phi, (h, k, l) where (typically) there will be
  two records corresponding to each h, k, l.'''

  from rstbx.diffraction import rotation_angles
  from scitbx import matrix
  import math

  ra = rotation_angles(dmin, a_matrix, wavelength, matrix.col((0, 1, 0)))

  phi_hkl = []

  r2d = 180.0 / math.pi

  for i in indices:
    if ra(i):
      phis = ra.get_intersection_angles()
      phi_hkl.append((phis[0] * r2d % 360, i))
      phi_hkl.append((phis[1] * r2d % 360, i))

  return phi_hkl
Example #18
0
def find_HKL(cbf_image):

    # construct and link a cbf_handle to the image itself.
    cbf_handle = pycbf.cbf_handle_struct()
    cbf_handle.read_file(cbf_image, pycbf.MSG_DIGEST)

    # get the beam direction
    cbf_handle.find_category('axis')
    cbf_handle.find_column('equipment')
    cbf_handle.find_row('source')

    beam_direction = []

    for j in range(3):
        cbf_handle.find_column('vector[%d]' % (j + 1))
        beam_direction.append(cbf_handle.get_doublevalue())

    B = - matrix.col(beam_direction).normalize()

    detector = cbf_handle.construct_detector(0)

    # this returns slow fast slow fast pixels pixels mm mm

    detector_normal = tuple(detector.get_detector_normal())
    distance = detector.get_detector_distance()
    pixel = (detector.get_inferred_pixel_size(1),
             detector.get_inferred_pixel_size(2))

    gonio = cbf_handle.construct_goniometer()

    real_axis, real_angle = determine_effective_scan_axis(gonio)

    axis = tuple(gonio.get_rotation_axis())
    angles = tuple(gonio.get_rotation_range())

    # this method returns slow then fast dimensions i.e. (y, x)

    size = tuple(reversed(cbf_handle.get_image_size(0)))
    wavelength = cbf_handle.get_wavelength()

    O = matrix.col(detector.get_pixel_coordinates(0, 0))
    fast = matrix.col(detector.get_pixel_coordinates(0, 1))
    slow = matrix.col(detector.get_pixel_coordinates(1, 0))

    X = fast - O
    Y = slow - O

    X = X.normalize()
    Y = Y.normalize()
    N = X.cross(Y)

    S0 = (1.0 / wavelength) * B

    # Need to rotate into Rossmann reference frame for phi calculation, as
    # that's code from Labelit :o(

    RB = matrix.col([0, 0, 1])

    if B.angle(RB) % math.pi:
        RtoR = RB.cross(R).axis_and_angle_as_r3_rotation_matrix(
            RB.angle(R))
    elif B.angle(RB):
        RtoR = matrix.sqr((1, 0, 0, 0, -1, 0, 0, 0, -1))
    else:
        RtoR = matrix.sqr((1, 0, 0, 0, 1, 0, 0, 0, 1))

    Raxis = RtoR * axis
    RUB = RtoR * UB

    RA = rotation_angles(wavelength, RUB, wavelength, Raxis)

    assert(RA(hkl))

    omegas = [180.0 / math.pi * a for a in RA.get_intersection_angles()]

    print '%.2f %.2f' % tuple(omegas)

    for omega in omegas:

        R = matrix.col(axis).axis_and_angle_as_r3_rotation_matrix(
            math.pi * omega / 180.0)

        q = R * UB * hkl

        p = S0 + q

        p_ = p * (1.0 / math.sqrt(p.dot()))
        P = p_ * (O.dot(N) / (p_.dot(N)))

        R = P - O

        i = R.dot(X)
        j = R.dot(Y)
        k = R.dot(N)

        print '%d %d %d %.3f %.3f %.3f %.3f %.3f' % \
              (hkl[0], hkl[1], hkl[2], i, j, omega, i / pixel[0], j / pixel[1])

    # finally, the inverse calculation - given a position on the detector,
    # and omega setting, give the Miller index of the reflection

    i = 193
    j = 267
    w = 42

    # RUBI is (R * UB).inverse()

    RUBI = (matrix.col(axis).axis_and_angle_as_r3_rotation_matrix(
        math.pi * w / 180.0) * UB).inverse()

    p = matrix.col(detector.get_pixel_coordinates(j, i)).normalize()

    q = (1.0 / wavelength) * p - S0

    h, k, l = map(nint, (RUBI * q).elems)

    assert(h == -17)
    assert(k == -10)
    assert(l == 9)

    print h, k, l

    detector.__swig_destroy__(detector)
    del(detector)

    gonio.__swig_destroy__(gonio)
    del(gonio)
Example #19
0
  def predict_observations(self):
    '''Actually perform the prediction calculations.'''

    d2r = math.pi / 180.0
    cfc = coordinate_frame_converter(self._configuration_file)

    self.img_start, self.osc_start, self.osc_range = parse_xds_xparm_scan_info(
        self._configuration_file)

    if self._dmin is None:
        self._dmin = cfc.derive_detector_highest_resolution()

    phi_start = ((self._img_range[0] - self.img_start) * self.osc_range + \
                 self.osc_start) * d2r
    phi_end = ((self._img_range[1] - self.img_start + 1) * self.osc_range + \
               self.osc_start) * d2r
    self.phi_start_rad = phi_start
    self.phi_end_rad = phi_end
    # in principle this should come from the crystal model - should that
    # crystal model record the cell parameters or derive them from the
    # axis directions?

    A = cfc.get_c('real_space_a')
    B = cfc.get_c('real_space_b')
    C = cfc.get_c('real_space_c')

    cell = (A.length(), B.length(), C.length(), B.angle(C, deg = True),
            C.angle(A, deg = True), A.angle(B, deg = True))
    self.uc = unit_cell(cell)

    # generate all of the possible indices, then pull out those which should
    # be systematically absent

    sg = cfc.get('space_group_number')

    indices = full_sphere_indices(
      unit_cell = self.uc,
      resolution_limit = self._dmin,
      space_group = space_group(space_group_symbols(sg).hall()))

    # then get the UB matrix according to the Rossmann convention which
    # is used within the Labelit code.

    u, b = cfc.get_u_b(convention = cfc.ROSSMANN)
    axis = cfc.get('rotation_axis', convention = cfc.ROSSMANN)
    ub = u * b

    wavelength = cfc.get('wavelength')
    self.wavelength = wavelength

    # work out which reflections should be observed (i.e. pass through the
    # Ewald sphere)
    ra = rotation_angles(self._dmin, ub, wavelength, axis)

    obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range(
        phi_start_rad = phi_start,
        phi_end_rad = phi_end,
        indices = indices)

    # convert all of these to full scattering vectors in a laboratory frame
    # (for which I will use the CBF coordinate frame) and calculate which
    # will intersect with the detector

    u, b = cfc.get_u_b()
    axis = cfc.get_c('rotation_axis')
    # must guarantee that sample_to_source vector is normalized so that
    #  s0 has length of 1/wavelength.
    sample_to_source_vec = cfc.get_c('sample_to_source').normalize()
    s0 = (- 1.0 / wavelength) * sample_to_source_vec
    ub = u * b

    # need some detector properties for this as well... starting to
    # abstract these to a detector model.
    df = detector_factory_from_cfc(cfc)
    d = df.build()

    # the Use Case assumes the detector consists of a single sensor
    sensor = d.sensors()[0]

    self.pixel_size_fast, self.pixel_size_slow = d.px_size_fast(), \
        d.px_size_slow()

    # used for polarization correction
    self.distance = sensor.distance

    rp = reflection_prediction(axis, s0, ub, sensor)
    if self._rocking_curve is not None:
      assert self._rocking_curve != "none"
      rp.set_rocking_curve(self._rocking_curve)
      rp.set_mosaicity(self._mosaicity_deg, degrees = True)
    return rp.predict(obs_indices, obs_angles)
Example #20
0
  def predict_observations(self):
    '''Actually perform the prediction calculations.'''

    d2r = math.pi / 180.0
    cfc = coordinate_frame_converter(self._configuration_file)

    self.img_start, self.osc_start, self.osc_range = parse_xds_xparm_scan_info(
        self._configuration_file)

    if self._dmin is None:
        self._dmin = cfc.derive_detector_highest_resolution()

    phi_start = ((self._img_range[0] - self.img_start) * self.osc_range + \
                 self.osc_start) * d2r
    phi_end = ((self._img_range[1] - self.img_start + 1) * self.osc_range + \
               self.osc_start) * d2r
    self.phi_start_rad = phi_start
    self.phi_end_rad = phi_end
    # in principle this should come from the crystal model - should that
    # crystal model record the cell parameters or derive them from the
    # axis directions?

    A = cfc.get_c('real_space_a')
    B = cfc.get_c('real_space_b')
    C = cfc.get_c('real_space_c')

    cell = (A.length(), B.length(), C.length(), B.angle(C, deg = True),
            C.angle(A, deg = True), A.angle(B, deg = True))
    self.uc = unit_cell(cell)

    # generate all of the possible indices, then pull out those which should
    # be systematically absent

    sg = cfc.get('space_group_number')

    indices = full_sphere_indices(
      unit_cell = self.uc,
      resolution_limit = self._dmin,
      space_group = space_group(space_group_symbols(sg).hall()))

    # then get the UB matrix according to the Rossmann convention which
    # is used within the Labelit code.

    u, b = cfc.get_u_b(convention = cfc.ROSSMANN)
    axis = cfc.get('rotation_axis', convention = cfc.ROSSMANN)
    ub = u * b

    wavelength = cfc.get('wavelength')
    self.wavelength = wavelength

    # work out which reflections should be observed (i.e. pass through the
    # Ewald sphere)
    ra = rotation_angles(self._dmin, ub, wavelength, axis)

    obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range(
        phi_start_rad = phi_start,
        phi_end_rad = phi_end,
        indices = indices)

    # convert all of these to full scattering vectors in a laboratory frame
    # (for which I will use the CBF coordinate frame) and calculate which
    # will intersect with the detector

    u, b = cfc.get_u_b()
    axis = cfc.get_c('rotation_axis')
    # must guarantee that sample_to_source vector is normalized so that
    #  s0 has length of 1/wavelength.
    sample_to_source_vec = cfc.get_c('sample_to_source').normalize()
    s0 = (- 1.0 / wavelength) * sample_to_source_vec
    ub = u * b

    # need some detector properties for this as well... starting to
    # abstract these to a detector model.
    df = detector_factory_from_cfc(cfc)
    d = df.build()

    # the Use Case assumes the detector consists of a single sensor
    sensor = d.sensors()[0]

    self.pixel_size_fast, self.pixel_size_slow = d.px_size_fast(), \
        d.px_size_slow()

    # used for polarization correction
    self.distance = sensor.distance

    rp = reflection_prediction(axis, s0, ub, sensor)
    if self._rocking_curve is not None:
      assert self._rocking_curve != "none"
      rp.set_rocking_curve(self._rocking_curve)
      rp.set_mosaicity(self._mosaicity_deg, degrees = True)
    return rp.predict(obs_indices, obs_angles)
Example #21
0
def regenerate_predictions_brute(xds_integrate_hkl_file, phi_range):
    from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter
    from rstbx.diffraction import rotation_angles
    from rstbx.diffraction import full_sphere_indices
    from cctbx.sgtbx import space_group, space_group_symbols
    from cctbx.uctbx import unit_cell
    import math

    cfc = coordinate_frame_converter(xds_integrate_hkl_file)

    d2r = math.pi / 180.0

    dmin = cfc.derive_detector_highest_resolution()

    A = cfc.get_c('real_space_a')
    B = cfc.get_c('real_space_b')
    C = cfc.get_c('real_space_c')

    cell = (A.length(), B.length(), C.length(), B.angle(C, deg = True),
            C.angle(A, deg = True), A.angle(B, deg = True))

    uc = unit_cell(cell)
    sg = cfc.get('space_group_number')

    indices = full_sphere_indices(
        unit_cell = uc,
        resolution_limit = dmin,
        space_group = space_group(space_group_symbols(sg).hall()))

    u, b = cfc.get_u_b(convention = cfc.ROSSMANN)
    axis = cfc.get('rotation_axis', convention = cfc.ROSSMANN)
    ub = u * b

    wavelength = cfc.get('wavelength')

    ra = rotation_angles(dmin, ub, wavelength, axis)

    obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range(
        phi_start_rad = phi_range[0] * d2r,
        phi_end_rad = phi_range[1] * d2r,
        indices = indices)

    # in here work in internal (i.e. not Rossmann) coordinate frame

    u, b = cfc.get_u_b()
    axis = cfc.get_c('rotation_axis')
    sample_to_source_vec = cfc.get_c('sample_to_source').normalize()
    s0 = (- 1.0 / wavelength) * sample_to_source_vec
    ub = u * b

    detector_origin = cfc.get_c('detector_origin')
    detector_fast = cfc.get_c('detector_fast')
    detector_slow = cfc.get_c('detector_slow')
    detector_normal = detector_fast.cross(detector_slow)
    distance = detector_origin.dot(detector_normal.normalize())
    nx, ny = cfc.get('detector_size_fast_slow')
    px, py = cfc.get('detector_pixel_size_fast_slow')

    limits = [0, nx * px, 0, ny * py]

    xyz_to_hkl = { }

    for hkl, angle in zip(obs_indices, obs_angles):
        s = (ub * hkl).rotate(axis, angle)
        q = (s + s0).normalize()

        # check if diffracted ray parallel to detector face

        q_dot_n = q.dot(detector_normal)

        if q_dot_n == 0:
            continue

        r = (q * distance / q_dot_n) - detector_origin

        x = r.dot(detector_fast)
        y = r.dot(detector_slow)

        if x < limits[0] or y < limits[2]:
            continue
        if x > limits[1] or y > limits[3]:
            continue

        xyz = (x, y, angle / d2r)
        xyz_to_hkl[xyz] = map(int, hkl)

    return xyz_to_hkl
Example #22
0
def regenerate_predictions_reeke(xds_integrate_hkl_file, phi_range):
    from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter
    from rstbx.diffraction import rotation_angles
    from cctbx.sgtbx import space_group, space_group_symbols
    from cctbx.uctbx import unit_cell
    import math
    from dials.algorithms.refinement.prediction.reeke import reeke_model
    from cctbx.array_family import flex

    cfc = coordinate_frame_converter(xds_integrate_hkl_file)

    d2r = math.pi / 180.0

    dmin = cfc.derive_detector_highest_resolution()

    A = cfc.get_c('real_space_a')
    B = cfc.get_c('real_space_b')
    C = cfc.get_c('real_space_c')

    cell = (A.length(), B.length(), C.length(), B.angle(C, deg = True),
            C.angle(A, deg = True), A.angle(B, deg = True))

    uc = unit_cell(cell)
    sg = cfc.get('space_group_number')

    u, b = cfc.get_u_b()
    axis = cfc.get_c('rotation_axis')
    sample_to_source_vec = cfc.get_c('sample_to_source').normalize()
    wavelength = cfc.get('wavelength')
    s0 = (- 1.0 / wavelength) * sample_to_source_vec
    ub = u * b
    rm = reeke_model(ub, axis, s0, dmin, phi_range[0], phi_range[1], 3)
    reeke_indices = rm.generate_indices()

    # the following are in Rossmann coordinate frame to fit in with
    # Labelit code...
    ur, br = cfc.get_u_b(convention = cfc.ROSSMANN)
    axisr = cfc.get('rotation_axis', convention = cfc.ROSSMANN)
    ubr = ur * br

    ra = rotation_angles(dmin, ubr, wavelength, axisr)

    obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range(
            phi_start_rad = phi_range[0] * d2r,
            phi_end_rad = phi_range[1] * d2r,
            indices = reeke_indices)


    detector_origin = cfc.get_c('detector_origin')
    detector_fast = cfc.get_c('detector_fast')
    detector_slow = cfc.get_c('detector_slow')
    detector_normal = detector_fast.cross(detector_slow)
    distance = detector_origin.dot(detector_normal.normalize())
    nx, ny = cfc.get('detector_size_fast_slow')
    px, py = cfc.get('detector_pixel_size_fast_slow')

    limits = [0, nx * px, 0, ny * py]

    xyz_to_hkl = { }

    for hkl, angle in zip(obs_indices, obs_angles):
        s = (ub * hkl).rotate(axis, angle)
        q = (s + s0).normalize()

        # check if diffracted ray parallel to detector face

        q_dot_n = q.dot(detector_normal)

        if q_dot_n == 0:
            continue

        r = (q * distance / q_dot_n) - detector_origin

        x = r.dot(detector_fast)
        y = r.dot(detector_slow)

        if x < limits[0] or y < limits[2]:
            continue
        if x > limits[1] or y > limits[3]:
            continue

        xyz = (x, y, angle / d2r)
        xyz_to_hkl[xyz] = map(int, hkl)

    return xyz_to_hkl
Example #23
0
mygonio = goniometer_factory.known_axis((1, 0, 0))

# generate some indices
resolution = 2.0
indices = full_sphere_indices(
    unit_cell = mycrystal.get_unit_cell(),
    resolution_limit = resolution,
    space_group = space_group(space_group_symbols(1).hall()))

# generate list of phi values
R_to_rossmann = align_reference_frame(
    mybeam.get_unit_s0(), (0.0, 0.0, 1.0),
    mygonio.get_rotation_axis(), (0.0, 1.0, 0.0))

ra = rotation_angles(resolution,
                R_to_rossmann * mycrystal.get_U() * mycrystal.get_B(),
                mybeam.get_wavelength(),
                R_to_rossmann * matrix.col(mygonio.get_rotation_axis()))

obs_indices_rstbx, obs_angles_rstbx = \
    ra.observed_indices_and_angles_from_angle_range(
      phi_start_rad = 0.0, phi_end_rad = math.pi, indices = indices)

# test my rotation_angles wrapper, AnglePredictor_rstbx
ap = AnglePredictor_rstbx(mycrystal, mybeam, mygonio, resolution)
obs_indices_wrap, obs_angles_wrap = ap.observed_indices_and_angles_from_angle_range(
    phi_start_rad = 0.0, phi_end_rad = math.pi, indices = indices)

# NB
# * obs_indices is a scitbx_array_family_flex_ext.vec3_double and contains
# floating point indices.
# * obs_indices2 is a cctbx_array_family_flex_ext.miller_index containing
Example #24
0
# generate some indices
resolution = 2.0
indices = full_sphere_indices(
    unit_cell=mycrystal.get_unit_cell(),
    resolution_limit=resolution,
    space_group=space_group(space_group_symbols(1).hall()),
)

# generate list of phi values
R_to_rossmann = align_reference_frame(
    mybeam.get_unit_s0(), (0.0, 0.0, 1.0), mygonio.get_rotation_axis(), (0.0, 1.0, 0.0)
)

ra = rotation_angles(
    resolution,
    R_to_rossmann * mycrystal.get_U() * mycrystal.get_B(),
    mybeam.get_wavelength(),
    R_to_rossmann * matrix.col(mygonio.get_rotation_axis()),
)

obs_indices_rstbx, obs_angles_rstbx = ra.observed_indices_and_angles_from_angle_range(
    phi_start_rad=0.0, phi_end_rad=math.pi, indices=indices
)

# test my rotation_angles wrapper, AnglePredictor_rstbx
ap = AnglePredictor_rstbx(mycrystal, mybeam, mygonio, resolution)
obs_indices_wrap, obs_angles_wrap = ap.observed_indices_and_angles_from_angle_range(
    phi_start_rad=0.0, phi_end_rad=math.pi, indices=indices
)

# NB
# * obs_indices is a scitbx_array_family_flex_ext.vec3_double and contains
Example #25
0
  wavelength = results['wavelength']

  start = results['starting_frame'] - 1
  phi_start = results['phi_start']
  phi_width = results['phi_width']

  # FIXME really need to rotate the reference frame to put the
  # direct beam vector along (0,0,1)

  resolution = 1.8

  orientation = A + B + C

  co = crystal_orientation(orientation, basis_type.direct)
  mm = co.unit_cell().max_miller_indices(resolution)
  ra = rotation_angles(resolution, co.reciprocal_matrix(), wavelength, axis)

  for record in open('SPOT.XDS', 'r').readlines():
    lst = record.split()
    hkl = tuple(map(int, lst[-3:]))
    if hkl == (0, 0, 0):
      continue
    image = nint(float(lst[2]))

    if ra(hkl):
      phi1, phi2 = ra.get_intersection_angles()
      i = nint(start + (rtod * phi1 - phi_start) / phi_width)
      j = nint(start + (rtod * phi2 - phi_start) / phi_width)
      if abs(i - image) <= abs(j - image):
        print '%4d %4d' % (image, i)
      else: