Exemple #1
0
def get_projection_matrix(dim_pixel, dim_readout):
    """The get_projection_matrix() function returns the projection
  matrices in homogeneous coordinates between readout frame and
  fractional row and column indices.  The forward transform maps
  coordinates in the readout frame, i.e. [x, y, z, 1], to readout
  indices, i.e. [i, j, 1], where i and j are the row and column
  indices, respectively.  The backward transform provides the inverse.
  The get_projection_matrix() function assumes that coordinates in the
  readout frame are pixel centers.  XXX Bad name!  Better
  readout2metric(), readout_projection_matrices()?

  @note If coordinates in the readout frame are the top, left corner
        of the pixel, pass dim_readout=(readout_width_in_pixels + 1,
        readout_height_in_pixels + 1).

  @param dim_pixel   Two-tuple of pixel width and height, in meters
  @param dim_readout Two-tuple of readout width and height, in pixels
  @return            Two-tuple of the forward and backward projection
                     matrices
  """

    Pb = matrix.rec(
        elems=(0, +dim_pixel[0], dim_pixel[0] * (1 - dim_readout[0]) / 2,
               -dim_pixel[1], 0, dim_pixel[1] * (dim_readout[1] - 1) / 2, 0, 0,
               0, 0, 0, 1),
        n=(4, 3))
    Pf = matrix.rec(elems=(0, -1 / dim_pixel[1], 0, (dim_readout[1] - 1) / 2,
                           +1 / dim_pixel[0], 0, 0, (dim_readout[0] - 1) / 2,
                           0, 0, 0, 1),
                    n=(3, 4))
    return (Pf, Pb)
def remove_cone_around_axis (array, axis, cone_radius) :
  assert (cone_radius < 90) and (cone_radius >= 0)
  from scitbx.matrix import rec
  unit_cell = array.unit_cell()
  indices = array.indices()
  rc_vectors = unit_cell.reciprocal_space_vector(indices)
  v1 = rec(unit_cell.reciprocal_space_vector(tuple(axis)), (3,1))
  n_hkl = indices.size()
  data = array.data()
  sigmas = array.sigmas()
  angle_high = 180 - cone_radius
  i = 0
  while (i < len(indices)) :
    v2 = rec(rc_vectors[i], (3,1))
    #print v1, v2
    angle = math.degrees(v1.angle(v2))
    if (angle <= cone_radius) or (angle >= angle_high) :
      del rc_vectors[i]
      del indices[i]
      del data[i]
      if (sigmas is not None) :
        del sigmas[i]
    else :
      i += 1
  delta_n_hkl = n_hkl - indices.size()
  return (n_hkl, delta_n_hkl)
def remove_cone_around_axis(array, axis, cone_radius):
    assert (cone_radius < 90) and (cone_radius >= 0)
    from scitbx.matrix import rec
    unit_cell = array.unit_cell()
    indices = array.indices()
    rc_vectors = unit_cell.reciprocal_space_vector(indices)
    v1 = rec(unit_cell.reciprocal_space_vector(tuple(axis)), (3, 1))
    n_hkl = indices.size()
    data = array.data()
    sigmas = array.sigmas()
    angle_high = 180 - cone_radius
    i = 0
    while (i < len(indices)):
        v2 = rec(rc_vectors[i], (3, 1))
        #print v1, v2
        angle = math.degrees(v1.angle(v2))
        if (angle <= cone_radius) or (angle >= angle_high):
            del rc_vectors[i]
            del indices[i]
            del data[i]
            if (sigmas is not None):
                del sigmas[i]
        else:
            i += 1
    delta_n_hkl = n_hkl - indices.size()
    return (n_hkl, delta_n_hkl)
  def hessian_transform(self,
                        original_hessian,
                        adp_constraints):
    constraint_matrix_tensor = matrix.rec(
      adp_constraints.gradient_sum_matrix(),
      adp_constraints.gradient_sum_matrix().focus())

    hessian_matrix = matrix.rec( original_hessian,
                                 original_hessian.focus())
      ## now create an expanded matrix
    rows=adp_constraints.gradient_sum_matrix().focus()[0]+1
    columns=adp_constraints.gradient_sum_matrix().focus()[1]+1
    expanded_constraint_array = flex.double(rows*columns,0)
    count_new=0
    count_old=0
    for ii in range(rows):
      for jj in range(columns):
        if (ii>0):
          if (jj>0):
            expanded_constraint_array[count_new]=\
               constraint_matrix_tensor[count_old]
            count_old+=1
        count_new+=1
      ## place the first element please
    expanded_constraint_array[0]=1
    result=matrix.rec(  expanded_constraint_array,
                        (rows, columns) )
    #print result.mathematica_form()
    new_hessian = result *  hessian_matrix * result.transpose()
    result = flex.double(new_hessian)
    result.resize(flex.grid( new_hessian.n ) )
    return(result)
Exemple #5
0
  def hessian_transform(self,
                        original_hessian,
                        adp_constraints):
    constraint_matrix_tensor = matrix.rec(
      adp_constraints.gradient_sum_matrix(),
      adp_constraints.gradient_sum_matrix().focus())

    hessian_matrix = matrix.rec( original_hessian,
                                 original_hessian.focus())
      ## now create an expanded matrix
    rows=adp_constraints.gradient_sum_matrix().focus()[0]+1
    columns=adp_constraints.gradient_sum_matrix().focus()[1]+1
    expanded_constraint_array = flex.double(rows*columns,0)
    count_new=0
    count_old=0
    for ii in range(rows):
      for jj in range(columns):
        if (ii>0):
          if (jj>0):
            expanded_constraint_array[count_new]=\
               constraint_matrix_tensor[count_old]
            count_old+=1
        count_new+=1
      ## place the first element please
    expanded_constraint_array[0]=1
    result=matrix.rec(  expanded_constraint_array,
                        (rows, columns) )
    #print result.mathematica_form()
    new_hessian = result *  hessian_matrix * result.transpose()
    result = flex.double(new_hessian)
    result.resize(flex.grid( new_hessian.n ) )
    return(result)
def run(args):
  if (len(args) == 0): args = ["--help"]
  from libtbx.option_parser import libtbx_option_parser
  import libtbx.load_env
  command_line = (libtbx_option_parser(
    usage="%s [options] space_group_symbol ..." % libtbx.env.dispatcher_name)
      .option(None, "--primitive",
        action="store_true",
        help="Convert centred space groups to primitive setting.")
      .option(None, "--symops",
        action="store_true",
        help="Show list of symmetry operations.")
  ).process(args=args)
  co = command_line.options
  from cctbx import sgtbx
  args = command_line.args
  if (args == ["all"]):
    args = [str(no) for no in xrange(1,230+1)]
  for symbol in args:
    sgi = sgtbx.space_group_info(symbol=symbol)
    if (co.primitive):
      sgi = sgi.primitive_setting()
    sgi.show_summary()
    gr = sgi.group()
    print "  Crystal system:", gr.crystal_system()
    print "  Point group type:", gr.point_group_type()
    print "  Laue group type:", gr.laue_group_type()
    print "  Number of symmetry operations:", gr.order_z()
    print "  Lattice centering operations:", gr.n_ltr()
    if (gr.n_ltr() != 1):
      print "  Number of symmetry operations in primitive setting:", \
        gr.order_p()
    if (gr.is_centric()): s = gr(0, 1, 0)
    else:                 s = None
    print "  Center of inversion:", s
    print "  Dimensionality of continuous allowed origin shifts:", \
      sgi.number_of_continuous_allowed_origin_shifts()
    ssi_vm = sgi.structure_seminvariants().vectors_and_moduli()
    print "  Structure-seminvariant vectors and moduli:", \
      len(ssi_vm)
    if (len(ssi_vm) != 0):
      for vm in ssi_vm:
        print "    (%2d, %2d, %2d)" % vm.v, "%2d" % vm.m
    print "  Direct-space asymmetric unit:"
    dau = sgi.direct_space_asu()
    print "    Number of faces: %d" % len(dau.cuts)
    for cut in dau.cuts:
      print "    " + cut.as_xyz()
    print "  ADP constraint matrix:"
    _ = sgi.group().adp_constraints().gradient_sum_matrix()
    from scitbx import matrix
    print matrix.rec(tuple(_), _.focus()).mathematica_form(
      one_row_per_line=True,
      prefix="    ")
    if (co.symops):
      print "  List of symmetry operations:"
      for s in sgi.group():
        print "    %s" % str(s)
    print
Exemple #7
0
def get_projection_matrix(dim_pixel, dim_readout):
    """The get_projection_matrix() function returns the projection
  matrices in homogeneous coordinates between readout frame and
  fractional row and column indices.  The forward transform maps
  coordinates in the readout frame, i.e. [x, y, z, 1], to readout
  indices, i.e. [i, j, 1], where i and j are the row and column
  indices, respectively.  The backward transform provides the inverse.
  The get_projection_matrix() function assumes that coordinates in the
  readout frame are pixel centers.  XXX Bad name!  Better
  readout2metric(), readout_projection_matrices()?

  @note If coordinates in the readout frame are the top, left corner
        of the pixel, pass dim_readout=(readout_width_in_pixels + 1,
        readout_height_in_pixels + 1).

  @param dim_pixel   Two-tuple of pixel width and height, in meters
  @param dim_readout Two-tuple of readout width and height, in pixels
  @return            Two-tuple of the forward and backward projection
                     matrices
  """

    Pb = matrix.rec(
        elems=(
            0,
            +dim_pixel[0],
            dim_pixel[0] * (1 - dim_readout[0]) / 2,
            -dim_pixel[1],
            0,
            dim_pixel[1] * (dim_readout[1] - 1) / 2,
            0,
            0,
            0,
            0,
            0,
            1,
        ),
        n=(4, 3),
    )
    Pf = matrix.rec(
        elems=(
            0,
            -1 / dim_pixel[1],
            0,
            (dim_readout[1] - 1) / 2,
            +1 / dim_pixel[0],
            0,
            0,
            (dim_readout[0] - 1) / 2,
            0,
            0,
            0,
            1,
        ),
        n=(3, 4),
    )
    return (Pf, Pb)
Exemple #8
0
def exercise_rigu():
    ins = """
CELL 0.71073 7.772741 8.721603 10.863736 90 102.9832 90
ZERR 2 0.000944 0.001056 0.001068 0 0.0107 0
LATT -1
SYMM -X,0.5+Y,-Z
SFAC C H O
UNIT 24 44 22
RIGU 0.0001 0.0001 O4 C C12

C12   1    -0.12812  0.06329 -0.17592  11.00000  0.01467  0.02689  0.02780 =
 -0.00379  0.00441 -0.00377
O4    3     0.08910  0.02721  0.02186  11.00000  0.02001  0.03168  0.03125 =
 -0.00504  0.00144 -0.00274
C     1    -0.05545 -0.04221 -0.06528  11.00000  0.01560  0.02699  0.02581 =
 -0.00481  0.00597 -0.00068
HKLF 4
END
  """
    sio = StringIO(ins)
    import iotbx.shelx as shelx
    model = shelx.parse_smtbx_refinement_model(file=sio)
    sites_cart = model.structure.sites_cart()
    u_cart = model.structure.scatterers().extract_u_cart(
        model.structure.unit_cell())
    arp = adp_restraint_params(sites_cart=sites_cart, u_cart=u_cart)
    for rp in model._proxies['rigu']:
        rr = adp_restraints.rigu(arp, rp)
        U1 = matrix.sym(sym_mat3=u_cart[rp.i_seqs[0]])
        U2 = matrix.sym(sym_mat3=u_cart[rp.i_seqs[1]])
        vz = matrix.col(sites_cart[rp.i_seqs[1]]) - matrix.col(
            sites_cart[rp.i_seqs[0]])
        vy = vz.ortho()
        vx = vy.cross(vz)
        R = matrix.rec(
            vx.normalize().elems + vy.normalize().elems + vz.normalize().elems,
            (3, 3))
        # with this matrix we can only test Z component as X and Y will differ
        dU = ((R * U1) * R.transpose() -
              (R * U2) * R.transpose()).as_sym_mat3()
        assert approx_equal(dU[2], rr.delta_33())
        #with the original matrix all components should match
        R1 = matrix.rec(rr.RM(), (3, 3))
        dU = ((R1 * U1) * R1.transpose() -
              (R1 * U2) * R1.transpose()).as_sym_mat3()
        assert approx_equal(dU[2], rr.delta_33())
        assert approx_equal(dU[4], rr.delta_13())
        assert approx_equal(dU[5], rr.delta_23())
        # check the raw gradients against the reference implementation
        for x, y in zip(rr.reference_gradients(R1), rr.raw_gradients()):
            for idx in range(0, 6):
                assert approx_equal(x[idx], y[idx])
        for x, y in zip(rigu_finite_diff(R1, U1), rr.raw_gradients()):
            for idx in range(0, 6):
                assert approx_equal(x[idx], y[idx])
def exercise_impl(svd_impl_name, use_fortran):
    import scitbx.linalg

    svd_impl = getattr(scitbx.linalg, "lapack_%s" % svd_impl_name)
    from scitbx.array_family import flex
    from scitbx import matrix
    from libtbx.test_utils import approx_equal

    #
    for diag in [0, 1]:
        for n in xrange(1, 11):
            a = flex.double(flex.grid(n, n), 0)
            for i in xrange(n):
                a[(i, i)] = diag
            a_inp = a.deep_copy()
            svd = svd_impl(a=a, use_fortran=use_fortran)
            if svd is None:
                if not use_fortran:
                    print "Skipping tests: lapack_%s not available." % svd_impl_name
                return
            assert svd.info == 0
            assert approx_equal(svd.s, [diag] * n)
            assert svd.u.all() == (n, n)
            assert svd.vt.all() == (n, n)

    mt = flex.mersenne_twister(seed=0)
    for m in xrange(1, 11):
        for n in xrange(1, 11):
            a = matrix.rec(elems=tuple(mt.random_double(m * n) * 4 - 2), n=(m, n))
            svd = svd_impl(a=a.transpose().as_flex_double_matrix(), use_fortran=use_fortran)
            assert svd.info == 0
            sigma = matrix.diag(svd.s)  # min(m,n) x min(m,n)
            # FORTRAN layout, so transpose
            u = matrix.rec(svd.u, svd.u.all()).transpose()
            vt = matrix.rec(svd.vt, svd.vt.all()).transpose()
            assert approx_equal(u * sigma * vt, a)
    #
    a = matrix.rec(elems=[0.47, 0.10, -0.21, -0.21, -0.03, 0.35], n=(3, 2))
    svd = svd_impl(a=a.transpose().as_flex_double_matrix(), use_fortran=use_fortran)
    assert svd.info == 0
    assert approx_equal(svd.s, [0.55981345199567534, 0.35931726783538481])
    # again remember column-major storage
    assert approx_equal(
        svd.u,
        [
            0.81402078804155853,
            -0.5136261274467826,
            0.27121644094748704,
            -0.42424674329757839,
            -0.20684171439391938,
            0.88160717215094342,
        ],
    )
    assert approx_equal(svd.vt, [0.8615633693608673, -0.50765003750177129, 0.50765003750177129, 0.8615633693608673])
Exemple #10
0
def exercise_impl(svd_impl_name, use_fortran):
    import scitbx.linalg
    svd_impl = getattr(scitbx.linalg, "lapack_%s" % svd_impl_name)
    from scitbx.array_family import flex
    from scitbx import matrix
    from libtbx.test_utils import approx_equal
    #
    for diag in [0, 1]:
        for n in range(1, 11):
            a = flex.double(flex.grid(n, n), 0)
            for i in range(n):
                a[(i, i)] = diag
            a_inp = a.deep_copy()
            svd = svd_impl(a=a, use_fortran=use_fortran)
            if (svd is None):
                if (not use_fortran):
                    print("Skipping tests: lapack_%s not available." %
                          svd_impl_name)
                return
            assert svd.info == 0
            assert approx_equal(svd.s, [diag] * n)
            assert svd.u.all() == (n, n)
            assert svd.vt.all() == (n, n)

    mt = flex.mersenne_twister(seed=0)
    for m in range(1, 11):
        for n in range(1, 11):
            a = matrix.rec(elems=tuple(mt.random_double(m * n) * 4 - 2),
                           n=(m, n))
            svd = svd_impl(a=a.transpose().as_flex_double_matrix(),
                           use_fortran=use_fortran)
            assert svd.info == 0
            sigma = matrix.diag(svd.s)  # min(m,n) x min(m,n)
            # FORTRAN layout, so transpose
            u = matrix.rec(svd.u, svd.u.all()).transpose()
            vt = matrix.rec(svd.vt, svd.vt.all()).transpose()
            assert approx_equal(u * sigma * vt, a)
    #
    a = matrix.rec(elems=[0.47, 0.10, -0.21, -0.21, -0.03, 0.35], n=(3, 2))
    svd = svd_impl(a=a.transpose().as_flex_double_matrix(),
                   use_fortran=use_fortran)
    assert svd.info == 0
    assert approx_equal(svd.s, [0.55981345199567534, 0.35931726783538481])
    # again remember column-major storage
    assert approx_equal(svd.u, [
        0.81402078804155853, -0.5136261274467826, 0.27121644094748704,
        -0.42424674329757839, -0.20684171439391938, 0.88160717215094342
    ])
    assert approx_equal(svd.vt, [
        0.8615633693608673, -0.50765003750177129, 0.50765003750177129,
        0.8615633693608673
    ])
Exemple #11
0
    def get_flex_image(self, brightness, **kwargs):
        # This functionality has migrated to
        # rstbx.slip_viewer.tile_generation._get_flex_image_multitile().
        # XXX Still used by iotbx/command_line/detector_image_as_png.py
        #raise DeprecationWarning(
        #  "xfel.cftbx.cspad_detector.get_flex_image() is deprecated")

        # no kwargs supported at present

        from xfel.cftbx.detector.metrology import get_projection_matrix

        # E maps picture coordinates onto metric Cartesian coordinates,
        # i.e. [row, column, 1 ] -> [x, y, z, 1].  Both frames share the
        # same origin, but the first coordinate of the screen coordinate
        # system increases downwards, while the second increases towards
        # the right.  XXX Is this orthographic projection the only one
        # that makes any sense?
        E = rec(elems=[
            0, +self._pixel_size[1], 0, -self._pixel_size[0], 0, 0, 0, 0, 0, 0,
            0, 1
        ],
                n=[4, 3])

        # P: [x, y, z, 1] -> [row, column, 1].  Note that self._asic_focus
        # needs to be flipped.
        Pf = get_projection_matrix(
            self._pixel_size, (self._asic_focus[1], self._asic_focus[0]))[0]

        # XXX Add ASIC:s in order?  If a point is contained in two ASIC:s
        # simultaneously, it will be assigned to the ASIC defined first.
        # XXX Use a Z-buffer instead?
        nmemb = 0
        for key, asic in six.iteritems(self._tiles):
            # Create my_flex_image and rawdata on the first iteration.
            if ("rawdata" not in locals()):
                rawdata = flex.double(flex.grid(self.size1, self.size2))
                my_flex_image = generic_flex_image(
                    rawdata=rawdata,
                    binning=1,
                    size1_readout=self._asic_focus[0],
                    size2_readout=self._asic_focus[1],
                    brightness=brightness,
                    saturation=self._saturation)

            rawdata.matrix_paste_block_in_place(block=asic,
                                                i_row=nmemb *
                                                self._asic_padded[0],
                                                i_column=0)
            nmemb += 1

            # key is guaranteed to exist in self._matrices as per
            # readHeader().  Last row of self._matrices[key][0] is always
            # [0, 0, 0, 1].
            T = Pf * self._matrices[key][0] * E
            R = sqr([T(0, 0), T(0, 1), T(1, 0), T(1, 1)])
            t = col([T(0, 2), T(1, 2)])

            my_flex_image.add_transformation_and_translation(R, t)
        my_flex_image.followup_brightness_scale()
        return my_flex_image
Exemple #12
0
 def __init__(O, type, qE):
   assert type in ["euler_params", "euler_angles_xyz"]
   if (type == "euler_params"):
     if (len(qE.elems) == 3):
       qE = euler_angles_xyz_qE_as_euler_params_qE(qE=qE)
   else:
     if (len(qE.elems) == 4):
       qE = euler_params_qE_as_euler_angles_xyz_qE(qE=qE)
   O.type = type
   O.qE = qE
   O.q_size = len(qE)
   #
   if (type == "euler_params"):
     O.unit_quaternion = qE.normalize() # RBDA, bottom of p. 86
     O.E = RBDA_Eq_4_12(q=O.unit_quaternion)
   else:
     O.E = RBDA_Eq_4_7(q=qE)
   #
   O.Tps = matrix.rt((O.E, (0,0,0)))
   O.Tsp = matrix.rt((O.E.transpose(), (0,0,0)))
   O.Xj = T_as_X(O.Tps)
   O.S = matrix.rec((
     1,0,0,
     0,1,0,
     0,0,1,
     0,0,0,
     0,0,0,
     0,0,0), n=(6,3))
Exemple #13
0
def glm(x, p=None):
    from math import exp, sqrt, log, factorial, lgamma
    from scitbx import matrix
    from scipy.stats import poisson

    beta0 = 0

    if p is None:
        p = [1.0] * len(x)

    X = matrix.rec([1] * len(x), (len(x), 1))
    c = 1.345

    while True:
        n = beta0
        mu = exp(n)
        z = [n + (xx - mu) / mu for xx in x]
        w = [pp * mu for pp in p]
        r = [(xx - mu) / sqrt(mu) for xx in x]
        w2 = [huber(rr, c) for rr in r]

        W = matrix.diag(w)
        # W2 = matrix.diag(w2)
        Z = matrix.col(z)
        beta = (X.transpose() * W * X).inverse() * X.transpose() * W * z
        print(beta)
        if abs(beta[0] - beta0) < 1e-3:
            break
        beta0 = beta[0]

    # W12 = matrix.diag([sqrt(ww) for ww in w])
    # H = W12 * X * (X.transpose() * W * X).inverse() * X.transpose() * W12

    mu = exp(n)
    return mu
  def get_panel_fast_slow(self, serial):
    """Get the average x- and y-coordinates of all the ASIC:s in the
    panel with serial @p serial.  This is done by back-transforming
    the centre's of each ASIC to the screen (sort of) coordinate
    system.  This is more robust than getting the panel positions
    directly.
    """

    from xfel.cftbx.detector.metrology import get_projection_matrix

    center = col([self._asic_focus[0] / 2, self._asic_focus[1] / 2, 1])
    fast, nmemb, slow = 0, 0, 0

    # Use the pixel size for the ASIC to construct the final
    # projection matrix.
    for p in self._metrology_params.detector.panel:
      if (p.serial != serial):
        continue
      for s in p.sensor:
        for a in s.asic:
          E = rec(elems=[+1 / a.pixel_size[0], 0, 0, 0,
                         0, -1 / a.pixel_size[1], 0, 0],
                  n=[2, 4])

          Pb = get_projection_matrix(a.pixel_size, a.dimension)[1]
          Tb = self._matrices[(0, p.serial, s.serial, a.serial)][1]

          t = E * Tb * Pb * center
          fast += t(0, 0)
          slow += t(1, 0)
          nmemb += 1
    if (nmemb == 0):
      return (0, 0)
    return (fast / nmemb, slow / nmemb)
Exemple #15
0
def glm33(X, Y, B, P):
    from math import exp, sqrt, log, factorial, lgamma
    from scitbx import matrix
    from scipy.stats import poisson

    X = matrix.rec(list(X), X.all())
    Y = matrix.col(list(Y))
    B = matrix.col(list(B))
    P = matrix.col(list(P))

    while True:
        n = X * B
        mu = matrix.col([exp(nn) for nn in n])

        z = [(yy - mui) / mui for yy, mui in zip(Y, mu)]
        w = [pp * mui for pp, mui in zip(P, mu)]

        W = matrix.diag(w)
        Z = matrix.col(z)
        delta = (X.transpose() * W * X).inverse() * X.transpose() * W * z

        relE = sqrt(
            sum([d * d for d in delta]) / max(1e-10, sum([d * d for d in B])))
        B = B + delta

        # print relE
        if relE < 1e-3:
            break

    return B
Exemple #16
0
    def update_rot_tran(self, x):
        """
    Convert the refinable parameters, rotations angles and
    scaled translations, back to rotation matrices and translation vectors and
    updates the transforms_obj (ncs_restraints_group_list)
    !!! IN PLACE !!!

    Args:
      x : a flex.double of the form (theta_1,psi_1,phi_1,tx_1,ty_1,tz_1,..
        theta_n,psi_n,phi_n,tx_n/s,ty_n/s,tz_n/s). where n is the number of
        transformations.

    Returns:
      Nothing
    """
        i = 0
        for gr in self:
            copies = []
            for tr in gr.copies:
                the, psi, phi = x[i * 6:i * 6 + 3]
                rot = scitbx.rigid_body.rb_mat_xyz(the=the,
                                                   psi=psi,
                                                   phi=phi,
                                                   deg=False)
                tran = matrix.rec(x[i * 6 + 3:i * 6 + 6], (3, 1))
                tr.r = (rot.rot_mat())
                tr.t = tran
                copies.append(tr)
                i += 1
            gr.copies = copies
Exemple #17
0
def exercise_derivatives(space_group_info, out):
  crystal_symmetry = space_group_info.any_compatible_crystal_symmetry(
    volume=1000)
  space_group = space_group_info.group()
  adp_constraints = space_group.adp_constraints()
  m = adp_constraints.row_echelon_form()
  print >> out, matrix.rec(m, (m.size()//6, 6)).mathematica_form(
    one_row_per_line=True)
  print >> out, list(adp_constraints.independent_indices)
  u_cart_p1 = adptbx.random_u_cart()
  u_star_p1 = adptbx.u_cart_as_u_star(crystal_symmetry.unit_cell(), u_cart_p1)
  u_star = space_group.average_u_star(u_star_p1)
  miller_set = miller.build_set(
    crystal_symmetry=crystal_symmetry, d_min=3, anomalous_flag=False)
  for h in miller_set.indices():
    grads_fin = d_dw_d_u_star_finite(h=h, u_star=u_star)
    print >> out, "grads_fin:", list(grads_fin)
    grads_ana = d_dw_d_u_star_analytical(h=h, u_star=u_star)
    print >> out, "grads_ana:", list(grads_ana)
    compare_derivatives(grads_ana, grads_fin)
    curvs_fin = d2_dw_d_u_star_d_u_star_finite(h=h, u_star=u_star)
    print >> out, "curvs_fin:", list(curvs_fin)
    curvs_ana = d2_dw_d_u_star_d_u_star_analytical(h=h, u_star=u_star)
    print >> out, "curvs_ana:", list(curvs_ana)
    compare_derivatives(curvs_ana, curvs_fin)
    #
    u_indep = adp_constraints.independent_params(u_star)
    grads_indep_fin = d_dw_d_u_indep_finite(
      adp_constraints=adp_constraints, h=h, u_indep=u_indep)
    print >> out, "grads_indep_fin:", list(grads_indep_fin)
    grads_indep_ana = flex.double(adp_constraints.independent_gradients(
      all_gradients=list(grads_ana)))
    print >> out, "grads_indep_ana:", list(grads_indep_ana)
    compare_derivatives(grads_indep_ana, grads_indep_fin)
    curvs_indep_fin = d2_dw_d_u_indep_d_u_indep_finite(
      adp_constraints=adp_constraints, h=h, u_indep=u_indep)
    print >> out, "curvs_indep_fin:", list(curvs_indep_fin)
    curvs_indep_ana = adp_constraints.independent_curvatures(
      all_curvatures=curvs_ana)
    print >> out, "curvs_indep_ana:", list(curvs_indep_ana)
    compare_derivatives(curvs_indep_ana, curvs_indep_fin)
    #
    curvs_indep_mm = None
    if (str(space_group_info) == "P 1 2 1"):
      assert list(adp_constraints.independent_indices) == [0,1,2,4]
      curvs_indep_mm = p2_curv(h, u_star)
    elif (str(space_group_info) == "P 4"):
      assert list(adp_constraints.independent_indices) == [1,2]
      curvs_indep_mm = p4_curv(h, u_star)
    elif (str(space_group_info) in ["P 3", "P 6"]):
      assert list(adp_constraints.independent_indices) == [2,3]
      curvs_indep_mm = p3_curv(h, u_star)
    elif (str(space_group_info) == "P 2 3"):
      assert list(adp_constraints.independent_indices) == [2]
      curvs_indep_mm = p23_curv(h, u_star)
    if (curvs_indep_mm is not None):
      curvs_indep_mm = flex.double(
        curvs_indep_mm).matrix_symmetric_as_packed_u()
      print >> out, "curvs_indep_mm:", list(curvs_indep_mm)
      compare_derivatives(curvs_indep_ana, curvs_indep_mm)
Exemple #18
0
def glm33(X, Y, B, P):
  from math import exp , sqrt, log, factorial, lgamma
  from scitbx import matrix
  from scipy.stats import poisson

  X = matrix.rec(list(X), X.all())
  Y = matrix.col(list(Y))
  B = matrix.col(list(B))
  P = matrix.col(list(P))

  while True:
    n = X * B
    mu = matrix.col([exp(nn) for nn in n])

    z = [(yy - mui) / mui for yy, mui in zip(Y, mu)]
    w = [pp * mui for pp, mui in zip(P, mu)]

    W = matrix.diag(w)
    Z = matrix.col(z)
    delta = (X.transpose() * W * X).inverse() * X.transpose()*W*z

    relE = sqrt(sum([d*d for d in delta])/max(1e-10, sum([d*d for d in B])))
    B = B + delta

    # print relE
    if relE < 1e-3:
      break

  return B
Exemple #19
0
def glm(x, p=None):
    from math import exp, sqrt, log, factorial, lgamma
    from scitbx import matrix
    from scipy.stats import poisson

    beta0 = 0

    if p is None:
        p = [1.0] * len(x)

    X = matrix.rec([1] * len(x), (len(x), 1))
    c = 1.345

    while True:
        n = beta0
        mu = exp(n)
        z = [n + (xx - mu) / mu for xx in x]
        w = [pp * mu for pp in p]
        r = [(xx - mu) / sqrt(mu) for xx in x]
        w2 = [huber(rr, c) for rr in r]

        W = matrix.diag(w)
        # W2 = matrix.diag(w2)
        Z = matrix.col(z)
        beta = (X.transpose() * W * X).inverse() * X.transpose() * W * z
        print beta
        if abs(beta[0] - beta0) < 1e-3:
            break
        beta0 = beta[0]

    # W12 = matrix.diag([sqrt(ww) for ww in w])
    # H = W12 * X * (X.transpose() * W * X).inverse() * X.transpose() * W12

    mu = exp(n)
    return mu
  def get_flex_image(self, brightness, **kwargs):
    # This functionality has migrated to
    # rstbx.slip_viewer.tile_generation._get_flex_image_multitile().
    # XXX Still used by iotbx/command_line/detector_image_as_png.py
    #raise DeprecationWarning(
    #  "xfel.cftbx.cspad_detector.get_flex_image() is deprecated")

    # no kwargs supported at present

    from xfel.cftbx.detector.metrology import get_projection_matrix

    # E maps picture coordinates onto metric Cartesian coordinates,
    # i.e. [row, column, 1 ] -> [x, y, z, 1].  Both frames share the
    # same origin, but the first coordinate of the screen coordinate
    # system increases downwards, while the second increases towards
    # the right.  XXX Is this orthographic projection the only one
    # that makes any sense?
    E = rec(elems=[0, +self._pixel_size[1], 0,
                   -self._pixel_size[0], 0, 0,
                   0, 0, 0,
                   0, 0, 1],
            n=[4, 3])

    # P: [x, y, z, 1] -> [row, column, 1].  Note that self._asic_focus
    # needs to be flipped.
    Pf = get_projection_matrix(self._pixel_size,
                               (self._asic_focus[1], self._asic_focus[0]))[0]

    # XXX Add ASIC:s in order?  If a point is contained in two ASIC:s
    # simultaneously, it will be assigned to the ASIC defined first.
    # XXX Use a Z-buffer instead?
    nmemb = 0
    for key, asic in self._tiles.iteritems():
      # Create my_flex_image and rawdata on the first iteration.
      if ("rawdata" not in locals()):
        rawdata = flex.double(flex.grid(self.size1, self.size2))
        my_flex_image = generic_flex_image(
          rawdata=rawdata,
          size1_readout=self._asic_focus[0],
          size2_readout=self._asic_focus[1],
          brightness=brightness,
          saturation=self._saturation)

      rawdata.matrix_paste_block_in_place(
        block=asic,
        i_row=nmemb * self._asic_padded[0],
        i_column=0)
      nmemb += 1

      # key is guaranteed to exist in self._matrices as per
      # readHeader().  Last row of self._matrices[key][0] is always
      # [0, 0, 0, 1].
      T = Pf * self._matrices[key][0] * E
      R = sqr([T(0, 0), T(0, 1),
               T(1, 0), T(1, 1)])
      t = col([T(0, 2), T(1, 2)])

      my_flex_image.add_transformation_and_translation(R, t)
    my_flex_image.followup_brightness_scale()
    return my_flex_image
Exemple #21
0
def RBDA_Eq_4_13(q):
  p0, p1, p2, p3 = q
  return matrix.rec((
    -p1, -p2, -p3,
    p0, -p3, p2,
    p3, p0, -p1,
    -p2, p1, p0), n=(4,3)) * 0.5
Exemple #22
0
def exercise_isotropic_adp():
  i_seqs = (0,)
  weight = 2
  u_cart = ((1,2,3,5,2,8),)
  u_iso = (0,)
  use_u_aniso = (True,)
  p = adp_restraints.isotropic_adp_proxy(
    i_seqs=i_seqs,
    weight=weight)
  assert p.i_seqs == i_seqs
  assert approx_equal(p.weight, weight)
  i = adp_restraints.isotropic_adp(u_cart=u_cart[0], weight=weight)
  expected_deltas = (-1, 0, 1, 5, 2, 8)
  expected_gradients = (-4, 0, 4, 40, 16, 64)
  assert approx_equal(i.weight, weight)
  assert approx_equal(i.deltas(), expected_deltas)
  assert approx_equal(i.rms_deltas(), 4.5704364002673632)
  assert approx_equal(i.residual(), 376.0)
  assert approx_equal(i.gradients(), expected_gradients)
  gradients_aniso_cart = flex.sym_mat3_double(1, (0,0,0,0,0,0))
  gradients_iso = flex.double(1,0)
  proxies = adp_restraints.shared_isotropic_adp_proxy([p,p])
  u_cart = flex.sym_mat3_double(u_cart)
  u_iso = flex.double(u_iso)
  use_u_aniso = flex.bool(use_u_aniso)
  params = adp_restraint_params(u_cart=u_cart, u_iso=u_iso, use_u_aniso=use_u_aniso)
  residuals = adp_restraints.isotropic_adp_residuals(params, proxies=proxies)
  assert approx_equal(residuals, (i.residual(),i.residual()))
  deltas_rms = adp_restraints.isotropic_adp_deltas_rms(params, proxies=proxies)
  assert approx_equal(deltas_rms, (i.rms_deltas(),i.rms_deltas()))
  residual_sum = adp_restraints.isotropic_adp_residual_sum(
    params,
    proxies=proxies,
    gradients_aniso_cart=gradients_aniso_cart
  )
  assert approx_equal(residual_sum, 752.0)
  fd_grads_aniso, fd_grads_iso = finite_difference_gradients(
    restraint_type=adp_restraints.isotropic_adp,
    proxy=p,
    u_cart=u_cart,
    u_iso=u_iso,
    use_u_aniso=use_u_aniso
  )
  for g,e in zip(gradients_aniso_cart, fd_grads_aniso):
    assert approx_equal(g, matrix.col(e)*2)
  #
  # check frame invariance of residual
  #
  u_cart = matrix.sym(sym_mat3=(0.1,0.2,0.05,0.03,0.02,0.01))
  a = adp_restraints.isotropic_adp(
    u_cart=u_cart.as_sym_mat3(), weight=1)
  expected_residual = a.residual()
  gen = flex.mersenne_twister()
  for i in range(20):
    R = matrix.rec(gen.random_double_r3_rotation_matrix(),(3,3))
    u_cart_rot = R * u_cart * R.transpose()
    a = adp_restraints.isotropic_adp(
      u_cart=u_cart_rot.as_sym_mat3(), weight=1)
    assert approx_equal(a.residual(), expected_residual)
Exemple #23
0
def exercise_isotropic_adp():
  i_seqs = (0,)
  weight = 2
  u_cart = ((1,2,3,5,2,8),)
  u_iso = (0,)
  use_u_aniso = (True,)
  p = adp_restraints.isotropic_adp_proxy(
    i_seqs=i_seqs,
    weight=weight)
  assert p.i_seqs == i_seqs
  assert approx_equal(p.weight, weight)
  i = adp_restraints.isotropic_adp(u_cart=u_cart[0], weight=weight)
  expected_deltas = (-1, 0, 1, 5, 2, 8)
  expected_gradients = (-4, 0, 4, 40, 16, 64)
  assert approx_equal(i.weight, weight)
  assert approx_equal(i.deltas(), expected_deltas)
  assert approx_equal(i.rms_deltas(), 4.5704364002673632)
  assert approx_equal(i.residual(), 376.0)
  assert approx_equal(i.gradients(), expected_gradients)
  gradients_aniso_cart = flex.sym_mat3_double(1, (0,0,0,0,0,0))
  gradients_iso = flex.double(1,0)
  proxies = adp_restraints.shared_isotropic_adp_proxy([p,p])
  u_cart = flex.sym_mat3_double(u_cart)
  u_iso = flex.double(u_iso)
  use_u_aniso = flex.bool(use_u_aniso)
  params = adp_restraint_params(u_cart=u_cart, u_iso=u_iso, use_u_aniso=use_u_aniso)
  residuals = adp_restraints.isotropic_adp_residuals(params, proxies=proxies)
  assert approx_equal(residuals, (i.residual(),i.residual()))
  deltas_rms = adp_restraints.isotropic_adp_deltas_rms(params, proxies=proxies)
  assert approx_equal(deltas_rms, (i.rms_deltas(),i.rms_deltas()))
  residual_sum = adp_restraints.isotropic_adp_residual_sum(
    params,
    proxies=proxies,
    gradients_aniso_cart=gradients_aniso_cart
  )
  assert approx_equal(residual_sum, 752.0)
  fd_grads_aniso, fd_grads_iso = finite_difference_gradients(
    restraint_type=adp_restraints.isotropic_adp,
    proxy=p,
    u_cart=u_cart,
    u_iso=u_iso,
    use_u_aniso=use_u_aniso
  )
  for g,e in zip(gradients_aniso_cart, fd_grads_aniso):
    assert approx_equal(g, matrix.col(e)*2)
  #
  # check frame invariance of residual
  #
  u_cart = matrix.sym(sym_mat3=(0.1,0.2,0.05,0.03,0.02,0.01))
  a = adp_restraints.isotropic_adp(
    u_cart=u_cart.as_sym_mat3(), weight=1)
  expected_residual = a.residual()
  gen = flex.mersenne_twister()
  for i in range(20):
    R = matrix.rec(gen.random_double_r3_rotation_matrix(),(3,3))
    u_cart_rot = R * u_cart * R.transpose()
    a = adp_restraints.isotropic_adp(
      u_cart=u_cart_rot.as_sym_mat3(), weight=1)
    assert approx_equal(a.residual(), expected_residual)
Exemple #24
0
 def as_4x4_rational(self):
     r = self.r().as_rational().elems
     t = self.t().as_rational().elems
     zero = rational.int(0)
     one = rational.int(1)
     return matrix.rec((r[0], r[1], r[2], t[0], r[3], r[4], r[5], t[1],
                        r[6], r[7], r[8], t[2], zero, zero, zero, one),
                       (4, 4))
Exemple #25
0
def determine_effective_scan_axis(gonio):
    x = gonio.rotate_vector(0.0, 1, 0, 0)
    y = gonio.rotate_vector(0.0, 0, 1, 0)
    z = gonio.rotate_vector(0.0, 0, 0, 1)

    R = matrix.rec(x + y + z, (3, 3)).transpose()

    x1 = gonio.rotate_vector(1.0, 1, 0, 0)
    y1 = gonio.rotate_vector(1.0, 0, 1, 0)
    z1 = gonio.rotate_vector(1.0, 0, 0, 1)

    R1 = matrix.rec(x1 + y1 + z1, (3, 3)).transpose()

    RA = R1 * R.inverse()

    rot = r3_rotation_axis_and_angle_from_matrix(RA)

    return rot.axis, rot.angle(deg = True)
Exemple #26
0
def cbf_gonio_to_effective_axis_fixed_old(cbf_gonio):
    '''Given a cbf goniometer handle, first determine the real rotation
  axis, then determine the fixed component of rotation which is rotated
  about this axis.'''

    # First construct the real rotation axis, as the difference in rotating
    # the identity matrix at the end of the scan and the beginning.

    x = cbf_gonio.rotate_vector(0.0, 1, 0, 0)
    y = cbf_gonio.rotate_vector(0.0, 0, 1, 0)
    z = cbf_gonio.rotate_vector(0.0, 0, 0, 1)

    R = matrix.rec(x + y + z, (3, 3)).transpose()

    x1 = cbf_gonio.rotate_vector(1.0, 1, 0, 0)
    y1 = cbf_gonio.rotate_vector(1.0, 0, 1, 0)
    z1 = cbf_gonio.rotate_vector(1.0, 0, 0, 1)

    R1 = matrix.rec(x1 + y1 + z1, (3, 3)).transpose()

    RA = R1 * R.inverse()

    rot = r3_rotation_axis_and_angle_from_matrix(RA)

    # Then, given this, determine the component of the scan which is fixed -
    # which will need to be with respect to the unrotated axis. N.B. this
    # will not be unique, but should be correct modulo a free rotation about
    # the shifted axis.

    start = cbf_gonio.get_rotation_range()[0]

    # want positive rotations => if negative invert axis
    axis = matrix.col(rot.axis)
    angle = rot.angle()
    if angle < 0:
        axis = -1 * axis
        # common sense would suggest in here that if the angle is -ve should
        # be made +ve - works OK for omega scans but not phi scans, probably
        # incomplete goniometer definition problem...
        # start = -start

    S = axis.axis_and_angle_as_r3_rotation_matrix(start, deg=True)

    return axis, S.inverse() * R
  def setUp(self):
    # set_test_matrix
    self.rot1 = flex.vec3_double([
      (-0.317946, -0.173437, 0.932111),
      ( 0.760735, -0.633422, 0.141629),
      ( 0.565855,  0.754120, 0.333333)])
    self.rot2 = flex.vec3_double([
      (0       ,  0       , 1),
      (0.784042, -0.620708, 0),
      (0.620708,  0.784042, 0)])
    self.rot3 = flex.vec3_double([
      ( 0       ,  0       , -1),
      ( 0.097445, -0.995241,  0),
      (-0.995241, -0.097445,  0)])
    # Angles for rot, in radians
    self.rot_angles1 = flex.double(
      (-0.4017753, 1.2001985, 2.6422171))
    self.rot_angles2 = flex.double(
      (-0.4017753, math.pi/2, 2.6422171))
    self.rot_angles3 = flex.double(
      (-0.4017753, -math.pi/2, 2.6422171))
    self.rot_angles1_deg = flex.double(
      (-0.4017753, 1.2001985, 2.6422171)) * 180/math.pi
    self.rotation1 = matrix.sqr(self.rot1.as_double())
    self.rotation2 = matrix.sqr(self.rot2.as_double())
    self.rotation3 = matrix.sqr(self.rot3.as_double())
    self.translation1 = matrix.rec((0.5,-0.5,0),(3,1))
    self.translation2 = matrix.rec((0,0,0),(3,1))
    self.translation3 = matrix.rec((0,1,2),(3,1))
    self.r_t = [[self.rotation1, self.translation1],
                [self.rotation2, self.translation2],
                [self.rotation3, self.translation3]]

    self.pdb_inp = iotbx.pdb.input(source_info=None, lines=test_pdb_str)
    self.tr_obj1 = ncs.input(
      hierarchy=self.pdb_inp.construct_hierarchy(),
      rotations=[self.rotation1,self.rotation2],
      translations=[self.translation1,self.translation2])
    self.tr_obj2 = ncs.input(
      hierarchy=self.pdb_inp.construct_hierarchy(),
      rotations=[self.rotation1,self.rotation2,self.rotation3],
      translations=[self.translation1,self.translation2,self.translation3])
    self.ncs_restraints_group_list = \
      self.tr_obj1.get_ncs_restraints_group_list()
def cbf_gonio_to_effective_axis_fixed_old(cbf_gonio):
  '''Given a cbf goniometer handle, first determine the real rotation
  axis, then determine the fixed component of rotation which is rotated
  about this axis.'''

  # First construct the real rotation axis, as the difference in rotating
  # the identity matrix at the end of the scan and the beginning.

  x = cbf_gonio.rotate_vector(0.0, 1, 0, 0)
  y = cbf_gonio.rotate_vector(0.0, 0, 1, 0)
  z = cbf_gonio.rotate_vector(0.0, 0, 0, 1)

  R = matrix.rec(x + y + z, (3, 3)).transpose()

  x1 = cbf_gonio.rotate_vector(1.0, 1, 0, 0)
  y1 = cbf_gonio.rotate_vector(1.0, 0, 1, 0)
  z1 = cbf_gonio.rotate_vector(1.0, 0, 0, 1)

  R1 = matrix.rec(x1 + y1 + z1, (3, 3)).transpose()

  RA = R1 * R.inverse()

  rot = r3_rotation_axis_and_angle_from_matrix(RA)

  # Then, given this, determine the component of the scan which is fixed -
  # which will need to be with respect to the unrotated axis. N.B. this
  # will not be unique, but should be correct modulo a free rotation about
  # the shifted axis.

  start = cbf_gonio.get_rotation_range()[0]

  # want positive rotations => if negative invert axis
  axis = matrix.col(rot.axis)
  angle = rot.angle()
  if angle < 0:
    axis = -1 * axis
    # common sense would suggest in here that if the angle is -ve should
    # be made +ve - works OK for omega scans but not phi scans, probably
    # incomplete goniometer definition problem...
    # start = -start

  S = axis.axis_and_angle_as_r3_rotation_matrix(start, deg=True)

  return axis, S.inverse() * R
Exemple #29
0
 def as_4x4_rational(self):
   r = self.r().as_rational().elems
   t = self.t().as_rational().elems
   zero = rational.int(0)
   one = rational.int(1)
   return matrix.rec((
     r[0], r[1], r[2], t[0],
     r[3], r[4], r[5], t[1],
     r[6], r[7], r[8], t[2],
     zero, zero, zero,  one), (4, 4))
Exemple #30
0
def cbf_gonio_to_effective_axis(cbf_gonio):
  '''Given a cbf goniometer handle, determine the real rotation axis.'''

  x = cbf_gonio.rotate_vector(0.0, 1, 0, 0)
  y = cbf_gonio.rotate_vector(0.0, 0, 1, 0)
  z = cbf_gonio.rotate_vector(0.0, 0, 0, 1)

  R = matrix.rec(x + y + z, (3, 3)).transpose()

  x1 = cbf_gonio.rotate_vector(1.0, 1, 0, 0)
  y1 = cbf_gonio.rotate_vector(1.0, 0, 1, 0)
  z1 = cbf_gonio.rotate_vector(1.0, 0, 0, 1)

  R1 = matrix.rec(x1 + y1 + z1, (3, 3)).transpose()

  RA = R1 * R.inverse()

  axis = r3_rotation_axis_and_angle_from_matrix(RA).axis

  return axis
Exemple #31
0
def cbf_gonio_to_effective_axis(cbf_gonio):
    '''Given a cbf goniometer handle, determine the real rotation axis.'''

    x = cbf_gonio.rotate_vector(0.0, 1, 0, 0)
    y = cbf_gonio.rotate_vector(0.0, 0, 1, 0)
    z = cbf_gonio.rotate_vector(0.0, 0, 0, 1)

    R = matrix.rec(x + y + z, (3, 3)).transpose()

    x1 = cbf_gonio.rotate_vector(1.0, 1, 0, 0)
    y1 = cbf_gonio.rotate_vector(1.0, 0, 1, 0)
    z1 = cbf_gonio.rotate_vector(1.0, 0, 0, 1)

    R1 = matrix.rec(x1 + y1 + z1, (3, 3)).transpose()

    RA = R1 * R.inverse()

    axis = r3_rotation_axis_and_angle_from_matrix(RA).axis

    return axis
Exemple #32
0
    def run_cplusplus(self):

        decomp = decompose_tls_matrices(
            T=self.T_M.as_sym_mat3(),
            L=self.L_M.as_sym_mat3(),
            S=self.S_M.as_mat3(),
            l_and_s_in_degrees=False,
            verbose=False,
            tol=self.
            eps,  # This is used through the code to determine when something is non-zero
            eps=
            1e-08,  # This is currently hardcoded in the truncate function as a separate value
            t_S_formula=(self.find_t_S_using_formula if
                         self.find_t_S_using_formula is not None else 'Force'),
            t_S_value=(self.force_t_S if self.force_t_S is not None else 0.0),
        )

        # Check result
        if not decomp.is_valid():
            raise Sorry(decomp.error())

        # Unpack results required for finalise object

        # Invert the rotation matrices from the c++ implementation as R_ML defined differently
        self.R_ML = matrix.sqr(decomp.R_ML).transpose()
        self.R_MV = matrix.sqr(decomp.R_MV).transpose()

        R_MtoL = self.R_ML.transpose()

        # Libration rms around L-axes
        self.Lxx = decomp.l_amplitudes[0]**2
        self.Lyy = decomp.l_amplitudes[1]**2
        self.Lzz = decomp.l_amplitudes[2]**2
        # Unit vectors defining three Libration axes
        self.l_x = matrix.rec(decomp.l_axis_directions[0], (3, 1))
        self.l_y = matrix.rec(decomp.l_axis_directions[1], (3, 1))
        self.l_z = matrix.rec(decomp.l_axis_directions[2], (3, 1))
        # Rotation axes pass through the points in the L base
        self.w = group_args(
            w_lx=R_MtoL *
            decomp.l_axis_intersections[0],  # Transform output to L frame
            w_ly=R_MtoL * decomp.l_axis_intersections[1],
            w_lz=R_MtoL * decomp.l_axis_intersections[2],
        )
        # Correlation shifts sx,sy,sz for libration
        self.sx = decomp.s_amplitudes[0]
        self.sy = decomp.s_amplitudes[1]
        self.sz = decomp.s_amplitudes[2]
        # Vectors defining three Vibration axes
        self.v_x_M = matrix.rec(decomp.v_axis_directions[0], (3, 1))
        self.v_y_M = matrix.rec(decomp.v_axis_directions[1], (3, 1))
        self.v_z_M = matrix.rec(decomp.v_axis_directions[2], (3, 1))
        # Vibrational axes in the M basis
        self.v_x = R_MtoL * decomp.v_axis_directions[0]
        self.v_y = R_MtoL * decomp.v_axis_directions[1]
        self.v_z = R_MtoL * decomp.v_axis_directions[2]
        # Vibration rms along V-axes
        self.tx = decomp.v_amplitudes[0]
        self.ty = decomp.v_amplitudes[1]
        self.tz = decomp.v_amplitudes[2]
Exemple #33
0
    def setUp(self):
        # set_test_matrix
        self.rot1 = flex.vec3_double([(-0.317946, -0.173437, 0.932111),
                                      (0.760735, -0.633422, 0.141629),
                                      (0.565855, 0.754120, 0.333333)])
        self.rot2 = flex.vec3_double([(0, 0, 1), (0.784042, -0.620708, 0),
                                      (0.620708, 0.784042, 0)])
        self.rot3 = flex.vec3_double([(0, 0, -1), (0.097445, -0.995241, 0),
                                      (-0.995241, -0.097445, 0)])
        # Angles for rot, in radians
        self.rot_angles1 = flex.double((-0.4017753, 1.2001985, 2.6422171))
        self.rot_angles2 = flex.double((-0.4017753, math.pi / 2, 2.6422171))
        self.rot_angles3 = flex.double((-0.4017753, -math.pi / 2, 2.6422171))
        self.rot_angles1_deg = flex.double(
            (-0.4017753, 1.2001985, 2.6422171)) * 180 / math.pi
        self.rotation1 = matrix.sqr(self.rot1.as_double())
        self.rotation2 = matrix.sqr(self.rot2.as_double())
        self.rotation3 = matrix.sqr(self.rot3.as_double())
        self.translation1 = matrix.rec((0.5, -0.5, 0), (3, 1))
        self.translation2 = matrix.rec((0, 0, 0), (3, 1))
        self.translation3 = matrix.rec((0, 1, 2), (3, 1))
        self.r_t = [[self.rotation1, self.translation1],
                    [self.rotation2, self.translation2],
                    [self.rotation3, self.translation3]]

        self.pdb_inp = iotbx.pdb.input(source_info=None, lines=test_pdb_str)
        self.tr_obj1 = ncs.input(
            hierarchy=self.pdb_inp.construct_hierarchy(),
            rotations=[self.rotation1, self.rotation2],
            translations=[self.translation1, self.translation2])
        self.tr_obj2 = ncs.input(
            hierarchy=self.pdb_inp.construct_hierarchy(),
            rotations=[self.rotation1, self.rotation2, self.rotation3],
            translations=[
                self.translation1, self.translation2, self.translation3
            ])
        self.ncs_restraints_group_list = \
          self.tr_obj1.get_ncs_restraints_group_list()
Exemple #34
0
 def check(a, b, c, expected_free_vars, expected_sol):
   m = []
   t = []
   for i in range(3):
     m.append([a[i], b[i]])
     t.append(c[i])
   m_orig = matrix.rec(flat_list(m), (3,2))
   t_orig = list(t)
   free_vars = row_echelon.form_rational(m, t)
   assert free_vars == expected_free_vars
   sol = row_echelon.back_substitution_rational(m, t, free_vars, [3, 11])
   assert sol == expected_sol
   if (sol is not None):
     assert list(m_orig * sol) == t_orig
 def check(a, b, c, expected_free_vars, expected_sol):
   m = []
   t = []
   for i in xrange(3):
     m.append([a[i], b[i]])
     t.append(c[i])
   m_orig = matrix.rec(flat_list(m), (3,2))
   t_orig = list(t)
   free_vars = row_echelon.form_rational(m, t)
   assert free_vars == expected_free_vars
   sol = row_echelon.back_substitution_rational(m, t, free_vars, [3, 11])
   assert sol == expected_sol
   if (sol is not None):
     assert list(m_orig * sol) == t_orig
Exemple #36
0
 def shape_vertices(self):
   result = set()
   cuts = self.cuts
   n_cuts = len(cuts)
   for i0 in xrange(0,n_cuts-2):
     for i1 in xrange(i0+1,n_cuts-1):
       for i2 in xrange(i1+1,n_cuts):
         m = matrix.rec(cuts[i0].n+cuts[i1].n+cuts[i2].n,(3,3))
         d = m.determinant()
         if (d != 0):
           m_inv = m.co_factor_matrix_transposed() * (r1/d)
           b = matrix.col([-cuts[i0].c,-cuts[i1].c,-cuts[i2].c])
           vertex = m_inv * b
           if (self.is_inside(vertex, shape_only=True)):
             result.add(vertex.elems)
   return sorted(result)
def cbf_gonio_to_effective_axis_fixed(cbf_gonio):
  axis = matrix.col(cbf_gonio.get_rotation_axis())
  start, increment = cbf_gonio.get_rotation_range()

  # xia2-56 handle gracefully reverse turning goniometers - this assumes
  # that the angles will be correctly inverted in the scan factory
  if increment < 0:
    start = -start
    increment = -increment
    axis = -axis

  x = cbf_gonio.rotate_vector(0.0, 1, 0, 0)
  y = cbf_gonio.rotate_vector(0.0, 0, 1, 0)
  z = cbf_gonio.rotate_vector(0.0, 0, 0, 1)
  R = matrix.rec(x + y + z, (3, 3)).transpose()
  S = axis.axis_and_angle_as_r3_rotation_matrix(start, deg=True)

  fixed = S.inverse() * R
  return axis, fixed
Exemple #38
0
def update_rot_tran(x, transforms_obj=None, ncs_restraints_group_list=None):
    """
  Convert the refinable parameters, rotations angles and
  scaled translations, back to rotation matrices and translation vectors and
  updates the transforms_obj (ncs_restraints_group_list)

  Args:
    x : a flex.double of the form (theta_1,psi_1,phi_1,tx_1,ty_1,tz_1,..
      theta_n,psi_n,phi_n,tx_n/s,ty_n/s,tz_n/s). where n is the number of
      transformations.
    transforms_obj : (ncs_group_object) containing information on Rotation
      matrices, Translation vectors and NCS
  ncs_restraints_group_list : a list of ncs_restraint_group objects

  Returns:
    The same type of input object with converted transforms
  """
    assert bool(transforms_obj) == (not bool(ncs_restraints_group_list))
    if transforms_obj:
        ncs_restraints_group_list = transforms_obj.get_ncs_restraints_group_list(
        )
    if ncs_restraints_group_list:
        i = 0
        for gr in ncs_restraints_group_list:
            copies = []
            for tr in gr.copies:
                the, psi, phi = x[i * 6:i * 6 + 3]
                rot = scitbx.rigid_body.rb_mat_xyz(the=the,
                                                   psi=psi,
                                                   phi=phi,
                                                   deg=False)
                tran = matrix.rec(x[i * 6 + 3:i * 6 + 6], (3, 1))
                tr.r = (rot.rot_mat())
                tr.t = tran
                copies.append(tr)
                i += 1
            gr.copies = copies
        if transforms_obj:
            transforms_obj.update_using_ncs_restraints_group_list(
                ncs_restraints_group_list)
            return transforms_obj
        else:
            return ncs_restraints_group_list
Exemple #39
0
def cbf_gonio_to_effective_axis_fixed(cbf_gonio):
    axis = matrix.col(cbf_gonio.get_rotation_axis())
    start, increment = cbf_gonio.get_rotation_range()

    # xia2-56 handle gracefully reverse turning goniometers - this assumes
    # that the angles will be correctly inverted in the scan factory
    if increment < 0:
        start = -start
        increment = -increment
        axis = -axis

    x = cbf_gonio.rotate_vector(0.0, 1, 0, 0)
    y = cbf_gonio.rotate_vector(0.0, 0, 1, 0)
    z = cbf_gonio.rotate_vector(0.0, 0, 0, 1)
    R = matrix.rec(x + y + z, (3, 3)).transpose()
    S = axis.axis_and_angle_as_r3_rotation_matrix(start, deg=True)

    fixed = S.inverse() * R
    return axis, fixed
def update_rot_tran(x,transforms_obj=None,ncs_restraints_group_list=None):
  """
  Convert the refinable parameters, rotations angles and
  scaled translations, back to rotation matrices and translation vectors and
  updates the transforms_obj (ncs_restraints_group_list)

  Args:
    x : a flex.double of the form (theta_1,psi_1,phi_1,tx_1,ty_1,tz_1,..
      theta_n,psi_n,phi_n,tx_n/s,ty_n/s,tz_n/s). where n is the number of
      transformations.
    transforms_obj : (ncs_group_object) containing information on Rotation
      matrices, Translation vectors and NCS
  ncs_restraints_group_list : a list of ncs_restraint_group objects

  Returns:
    The same type of input object with converted transforms
  """
  assert bool(transforms_obj) == (not bool(ncs_restraints_group_list))
  if transforms_obj:
    ncs_restraints_group_list = transforms_obj.get_ncs_restraints_group_list()
  if ncs_restraints_group_list:
    i = 0
    for gr in ncs_restraints_group_list:
      copies = []
      for tr in gr.copies:
        the,psi,phi =x[i*6:i*6+3]
        rot = scitbx.rigid_body.rb_mat_xyz(
          the=the, psi=psi, phi=phi, deg=False)
        tran = matrix.rec(x[i*6+3:i*6+6],(3,1))
        tr.r = (rot.rot_mat())
        tr.t = tran
        copies.append(tr)
        i += 1
      gr.copies = copies
    if transforms_obj:
      transforms_obj.update_using_ncs_restraints_group_list(
        ncs_restraints_group_list)
      return transforms_obj
    else:
      return ncs_restraints_group_list
Exemple #41
0
def roundoff(val, precision=3, as_string=False):
    '''
  round off all floats in a list (or tuple) of list (or tuples)
  recursively using round2() defined above as in:
  >>> math_utils.roundoff( [12.3454, 7.4843, ["foo", (35.3581, -0.3856, [4.2769, 3.2147] )] ])
  [12.345, 7.484, ['foo', (35.358, -0.386, [4.277, 3.215])]]
  If value is less than 10**-precision or greater than 10**precision then return with scientific notation
  '''
    if isinstance(val, float):
        if math.isnan(val):
            return float("nan")
        if abs(val) < float("1e-%d" % precision) or abs(val) > float(
                "9e%d" % precision):
            fstr = "%" + "%d" % precision
            fstr += ".%de" % precision
            val2str = fstr % val
            if as_string:
                return val2str
            return float(val2str)
        return round2(val, precision)
    if isinstance(val, list):
        for i, v in enumerate(val):
            val[i] = roundoff(v, precision)
    if isinstance(val, tuple):
        val = list(val)
        for i, v in enumerate(val):
            val[i] = roundoff(v, precision)
        val = tuple(val)
    if isinstance(val, matrix.sqr):
        val = list(val)
        for i, v in enumerate(val):
            val[i] = roundoff(v, precision)
        val = matrix.sqr(val)
    if isinstance(val, matrix.rec):
        valn = val.n
        val = list(val)
        for i, v in enumerate(val):
            val[i] = roundoff(v, precision)
        val = matrix.rec(elems=val, n=valn)
    return val
Exemple #42
0
def glm33(x, p):
    from math import exp, sqrt, log, factorial, lgamma
    from scitbx import matrix
    from scipy.stats import poisson

    beta0 = 0

    while True:
        n = beta0
        mu = exp(n)

        z = [(xx - mu) / mu for xx in x]
        w = [pp * mu for pp in p]

        W = matrix.diag(w)
        Z = matrix.col(z)
        X = matrix.rec([1] * len(z), (len(z), 1))
        H = X * (X.transpose() * W * X).inverse() * X.transpose() * W
        H = [H[i + i * len(z)] for i in range(len(z))]
        MSE = sum((xx - mu)**2 for xx in x) / len(x)
        r = [xx - mu for xx in x]
        D = [rr * rr / (1 * MSE) * (hh / (1 - hh)**2) for rr, hh in zip(r, H)]
        N = sum(1 for d in D if d > 4 / len(x))
        # print X.transpose()*W*z
        # print (W*X)[0]
        # print (X.transpose()*W*X).inverse()[0]
        delta = (X.transpose() * W * X).inverse() * X.transpose() * W * z
        # print delta

        relE = sqrt(
            sum([d * d
                 for d in delta]) / max(1e-10, sum([d * d for d in [beta0]])))
        beta0 = beta0 + delta[0]

        # print relE
        if relE < 1e-3:
            break

    return exp(beta0)
Exemple #43
0
 def __init__(O, type, qE):
     assert type in ["euler_params", "euler_angles_xyz"]
     if (type == "euler_params"):
         if (len(qE.elems) == 3):
             qE = euler_angles_xyz_qE_as_euler_params_qE(qE=qE)
     else:
         if (len(qE.elems) == 4):
             qE = euler_params_qE_as_euler_angles_xyz_qE(qE=qE)
     O.type = type
     O.qE = qE
     O.q_size = len(qE)
     #
     if (type == "euler_params"):
         O.unit_quaternion = qE.normalize()  # RBDA, bottom of p. 86
         O.E = RBDA_Eq_4_12(q=O.unit_quaternion)
     else:
         O.E = RBDA_Eq_4_7(q=qE)
     #
     O.Tps = matrix.rt((O.E, (0, 0, 0)))
     O.Tsp = matrix.rt((O.E.transpose(), (0, 0, 0)))
     O.Xj = T_as_X(O.Tps)
     O.S = matrix.rec(
         (1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0), n=(6, 3))
Exemple #44
0
def glm33(x, p):
  from math import exp , sqrt, log, factorial, lgamma
  from scitbx import matrix
  from scipy.stats import poisson
  beta0 = 0

  while True:
    n = beta0
    mu = exp(n)

    z = [(xx - mu) / mu for xx in x]
    w = [pp * mu for pp in p]

    W = matrix.diag(w)
    Z = matrix.col(z)
    X = matrix.rec([1]*len(z), (len(z),1))
    H = X*(X.transpose() *W* X).inverse() * X.transpose()*W
    H = [H[i+i*len(z)] for i in range(len(z))]
    MSE = sum((xx-mu)**2 for xx in x) / len(x)
    r = [xx - mu for xx in x]
    D = [rr*rr / (1 * MSE) * (hh / (1-hh)**2) for rr, hh in zip(r, H)]
    N = sum(1 for d in D if d > 4 / len(x))
    # print X.transpose()*W*z
    # print (W*X)[0]
    # print (X.transpose()*W*X).inverse()[0]
    delta = (X.transpose() * W * X).inverse() * X.transpose()*W*z
    # print delta

    relE = sqrt(sum([d*d for d in delta])/max(1e-10, sum([d*d for d in [beta0]])))
    beta0 = beta0 + delta[0]

    # print relE
    if relE < 1e-3:
      break

  return exp(beta0)
    def get_panel_fast_slow(self, serial):
        """Get the average x- and y-coordinates of all the ASIC:s in the
    panel with serial @p serial.  This is done by back-transforming
    the centre's of each ASIC to the screen (sort of) coordinate
    system.  This is more robust than getting the panel positions
    directly.
    """

        from xfel.cftbx.detector.metrology import get_projection_matrix

        center = col([self._asic_focus[0] / 2, self._asic_focus[1] / 2, 1])
        fast, nmemb, slow = 0, 0, 0

        # Use the pixel size for the ASIC to construct the final
        # projection matrix.
        for p in self._metrology_params.detector.panel:
            if (p.serial != serial):
                continue
            for s in p.sensor:
                for a in s.asic:
                    E = rec(elems=[
                        +1 / a.pixel_size[0], 0, 0, 0, 0, -1 / a.pixel_size[1],
                        0, 0
                    ],
                            n=[2, 4])

                    Pb = get_projection_matrix(a.pixel_size, a.dimension)[1]
                    Tb = self._matrices[(0, p.serial, s.serial, a.serial)][1]

                    t = E * Tb * Pb * center
                    fast += t(0, 0)
                    slow += t(1, 0)
                    nmemb += 1
        if (nmemb == 0):
            return (0, 0)
        return (fast / nmemb, slow / nmemb)
Exemple #46
0
  def _calc_cell_parameter_sd(self):

    from scitbx.math.lefebvre import matrix_inverse_error_propagation
    from scitbx.math import angle_derivative_wrt_vectors
    from math import pi, acos, sqrt

    # self._cov_B is the covariance matrix of elements of the B matrix. We
    # need to construct the covariance matrix of elements of the
    # transpose of B. The vector of elements of B is related to the
    # vector of elements of its transpose by a permutation, P.
    P = matrix.sqr((1,0,0,0,0,0,0,0,0,
                    0,0,0,1,0,0,0,0,0,
                    0,0,0,0,0,0,1,0,0,
                    0,1,0,0,0,0,0,0,0,
                    0,0,0,0,1,0,0,0,0,
                    0,0,0,0,0,0,0,1,0,
                    0,0,1,0,0,0,0,0,0,
                    0,0,0,0,0,1,0,0,0,
                    0,0,0,0,0,0,0,0,1))

    # We can use P to replace var_cov with the covariance matrix of
    # elements of the transpose of B.
    var_cov = P*self._cov_B*P

    # From B = (O^-1)^T we can convert this
    # to the covariance matrix of the real space orthogonalisation matrix
    Bt = self._B.transpose()
    O = Bt.inverse()
    cov_O = matrix_inverse_error_propagation(Bt, var_cov)

    # The real space unit cell vectors are given by
    vec_a = (O * matrix.col((1,0,0)))
    vec_b = (O * matrix.col((0,1,0)))
    vec_c = (O * matrix.col((0,0,1)))

    # So the unit cell parameters are
    a, b, c = vec_a.length(), vec_b.length(), vec_c.length()
    alpha = acos(vec_b.dot(vec_c) / (b*c))
    beta =  acos(vec_a.dot(vec_c) / (a*c))
    gamma = acos(vec_a.dot(vec_b) / (a*b))

    # The estimated errors are calculated by error propagation from cov_O. In
    # each case we define a function F(O) that converts the matrix O into the
    # unit cell parameter of interest. To do error propagation to get the
    # variance of that cell parameter we need the Jacobian of the function.
    # This is a 1*9 matrix of derivatives in the order of the elements of O
    #
    #     / dF   dF   dF   dF   dF   dF   dF   dF   dF  \
    # J = | ---, ---, ---, ---, ---, ---, ---, ---, --- |
    #     \ da1  db1  dc1  da2  db2  dc2  da3  db3  dc3 /
    #

    # For cell length |a|, F = sqrt(a1^2 + a2^2 + a3^2)
    jacobian = matrix.rec(
      (vec_a[0]/a, 0, 0, vec_a[1]/a, 0, 0, vec_a[2]/a, 0, 0), (1, 9))
    var_a = (jacobian * cov_O * jacobian.transpose())[0]

    # For cell length |b|, F = sqrt(b1^2 + b2^2 + b3^2)
    jacobian = matrix.rec(
      (0, vec_b[0]/b, 0, 0, vec_b[1]/b, 0, 0, vec_b[2]/b, 0), (1, 9))
    var_b = (jacobian * cov_O * jacobian.transpose())[0]

    # For cell length |c|, F = sqrt(c1^2 + c2^2 + c3^2)
    jacobian = matrix.rec(
      (0, 0, vec_c[0]/c, 0, 0, vec_c[1]/c, 0, 0, vec_c[2]/c), (1, 9))
    jacobian_t = jacobian.transpose()
    var_c = (jacobian * cov_O * jacobian.transpose())[0]

    # For cell volume (a X b).c,
    # F = c1(a2*b3 - b2*a3) + c2(a3*b1 - b3*a1) + c3(a1*b2 - b1*a2)
    a1, a2, a3 = vec_a
    b1, b2, b3 = vec_b
    c1, c2, c3 = vec_c
    jacobian = matrix.rec((c3*b2 - c2*b3,
                           c1*b3 - c3*b1,
                           c2*b1 - c1*b2,
                           c2*a3 - c3*a2,
                           c3*a1 - c1*a3,
                           c1*a2 - c2*a1,
                           a2*b3 - b2*a3,
                           a3*b1 - b3*a1,
                           a1*b2 - b1*a2), (1,9))
    jacobian_t = jacobian.transpose()
    var_V = (jacobian * cov_O * jacobian.transpose())[0]
    self._cell_volume_sd = sqrt(var_V)

    # For the unit cell angles we need to calculate derivatives of the angles
    # with respect to the elements of O
    dalpha_db, dalpha_dc = angle_derivative_wrt_vectors(vec_b, vec_c)
    dbeta_da, dbeta_dc = angle_derivative_wrt_vectors(vec_a, vec_c)
    dgamma_da, dgamma_db = angle_derivative_wrt_vectors(vec_a, vec_b)

    # For angle alpha, F = acos( b.c / |b||c|)
    jacobian = matrix.rec(
      (0, dalpha_db[0], dalpha_dc[0], 0, dalpha_db[1], dalpha_dc[1], 0,
      dalpha_db[2], dalpha_dc[2]), (1, 9))
    var_alpha = (jacobian * cov_O * jacobian.transpose())[0]

    # For angle beta, F = acos( a.c / |a||c|)
    jacobian = matrix.rec(
      (dbeta_da[0], 0, dbeta_dc[0], dbeta_da[1], 0, dbeta_dc[1], dbeta_da[2],
      0, dbeta_dc[2]), (1, 9))
    var_beta = (jacobian * cov_O * jacobian.transpose())[0]

    # For angle gamma, F = acos( a.b / |a||b|)
    jacobian = matrix.rec(
      (dgamma_da[0], dgamma_db[0], 0, dgamma_da[1], dgamma_db[1], 0,
      dgamma_da[2], dgamma_db[2], 0), (1, 9))
    var_gamma = (jacobian * cov_O * jacobian.transpose())[0]

    # Symmetry constraints may mean variances of the angles should be zero.
    # Floating point error could lead to negative variances. Ensure these are
    # caught before taking their square root!
    var_alpha = max(0, var_alpha)
    var_beta = max(0, var_beta)
    var_gamma = max(0, var_gamma)

    from math import pi
    rad2deg = 180. / pi
    self._cell_sd = (sqrt(var_a),
                     sqrt(var_b),
                     sqrt(var_c),
                     sqrt(var_alpha) * rad2deg,
                     sqrt(var_beta) * rad2deg,
                     sqrt(var_gamma) * rad2deg)
    return
Exemple #47
0
  def __init__(self, ub_beg, ub_end, axis, s0, dmin, margin = 3):

    # the source vector and wavelength
    self._source = -s0
    self._wavelength = 1 / sqrt(s0.dot(s0))
    self._wavelength_sq = self._wavelength**2

    # the rotation axis
    self._axis = axis

    # the resolution limit
    self._dstarmax = 1 / dmin
    self._dstarmax2 = self._dstarmax**2

    # Margin by which to expand limits. Mosflm uses 3.
    self._margin = int(margin)

    # Determine the permutation order of columns of the setting matrix. Use
    # the setting from the beginning for this.
    # As a side-effect set self._permutation.
    col1, col2, col3 = self._permute_axes(ub_beg)

    # Thus set the reciprocal lattice axis vectors, in permuted order
    # p, q and r for both orientations
    rl_vec = [ub_beg.extract_block(start=(0,0), stop=(3,1)),
              ub_beg.extract_block(start=(0,1), stop=(3,2)),
              ub_beg.extract_block(start=(0,2), stop=(3,3))]
    self._rlv_beg = [rl_vec[col1],
                     rl_vec[col2],
                     rl_vec[col3]]
    rl_vec = [ub_end.extract_block(start=(0,0), stop=(3,1)),
              ub_end.extract_block(start=(0,1), stop=(3,2)),
              ub_end.extract_block(start=(0,2), stop=(3,3))]
    self._rlv_end = [rl_vec[col1],
                     rl_vec[col2],
                     rl_vec[col3]]

    # Set permuted setting matrices
    self._p_beg = matrix.sqr(self._rlv_beg[0].elems +
                             self._rlv_beg[1].elems +
                             self._rlv_beg[2].elems).transpose()
    self._p_end = matrix.sqr(self._rlv_end[0].elems +
                             self._rlv_end[1].elems +
                             self._rlv_end[2].elems).transpose()

    ## Define a new coordinate system concentric with the Ewald sphere.
    ##
    ## X' = X - source_x
    ## Y' = Y - source_y
    ## Z' = Z - source_z
    ##
    ## X = P' h'
    ## -   =  -
    ##                                    / p11 p12 p13 -source_X \
    ## where h' = (p, q, r, 1)^T and P' = | p21 p22 p23 -source_y |
    ##       -                       =    \ p31 p32 p33 -source_z /
    ##

    # Calculate P' matrices for the beginning and end settings
    pp_beg = matrix.rec(self._p_beg.elems[0:3] + (-1.*self._source[0],) +
                        self._p_beg.elems[3:6] + (-1.*self._source[1],) +
                        self._p_beg.elems[6:9] + (-1.*self._source[2],),
                        n=(3, 4))
    pp_end = matrix.rec(self._p_end.elems[0:3] + (-1.*self._source[0],) +
                        self._p_end.elems[3:6] + (-1.*self._source[1],) +
                        self._p_end.elems[6:9] + (-1.*self._source[2],),
                        n=(3, 4))

    # Various quantities of interest are obtained from the reciprocal metric
    # tensor T of P'. These quantities are to be used (later) for solving
    # the intersection of a line of constant p, q index with the Ewald
    # sphere. It is efficient to calculate these before the outer loop. So,
    # calculate T for both beginning and end settings

    t_beg = (pp_beg.transpose() * pp_beg).as_list_of_lists()
    t_end = (pp_end.transpose() * pp_end).as_list_of_lists()

    # quantities that are constant with p, beginning orientation
    self._cp_beg = [t_beg[2][2],
                    t_beg[2][3]**2,
                    t_beg[0][2] * t_beg[2][3] - t_beg[0][3] * t_beg[2][2],
                    t_beg[0][2]**2 - t_beg[0][0] * t_beg[2][2],
                    t_beg[1][2] * t_beg[2][3] - t_beg[1][3] * t_beg[2][2],
                    t_beg[0][2] * t_beg[1][2] - t_beg[0][1] * t_beg[2][2],
                    t_beg[1][2]**2 - t_beg[1][1] * t_beg[2][2],
                    2.0 * t_beg[0][2],
                    2.0 * t_beg[1][2],
                    t_beg[0][0],
                    t_beg[1][1],
                    2.0 * t_beg[0][1],
                    2.0 * t_beg[2][3],
                    2.0 * t_beg[1][3],
                    2.0 * t_beg[0][3]]

    # quantities that are constant with p, end orientation
    self._cp_end = [t_end[2][2],
                    t_end[2][3]**2,
                    t_end[0][2] * t_end[2][3] - t_end[0][3] * t_end[2][2],
                    t_end[0][2]**2 - t_end[0][0] * t_end[2][2],
                    t_end[1][2] * t_end[2][3] - t_end[1][3] * t_end[2][2],
                    t_end[0][2] * t_end[1][2] - t_end[0][1] * t_end[2][2],
                    t_end[1][2]**2 - t_end[1][1] * t_end[2][2],
                    2.0 * t_end[0][2],
                    2.0 * t_end[1][2],
                    t_end[0][0],
                    t_end[1][1],
                    2.0 * t_end[0][1],
                    2.0 * t_end[2][3],
                    2.0 * t_end[1][3],
                    2.0 * t_end[0][3]]

    ## The following are set during the generation of indices

    # planes of constant p tangential to the Ewald sphere
    self._ewald_p_lim_beg = None
    self._ewald_p_lim_end = None

    # planes of constant p touching the circle of intersection between the
    # Ewald and resolution limiting spheres
    self._res_p_lim_beg = None
    self._res_p_lim_end = None

    # looping p limits
    self._p_lim = None

    return
Exemple #48
0
def exercise_rational():
  from scitbx.matrix import row_echelon
  from scitbx import matrix
  from libtbx.utils import flat_list
  from boost_adaptbx.boost import rational
  import random
  rng = random.Random(0)
  #
  m = [[0]]
  t = [0]
  free_vars = row_echelon.form_rational(m, t)
  assert m == [[0]]
  assert t == [0]
  assert free_vars == [0]
  sol = row_echelon.back_substitution_rational(m, t, free_vars, [1])
  assert sol == [1]
  sol = row_echelon.back_substitution_rational(m, None, free_vars, [2])
  assert sol == [2]
  #
  m = [[0]]
  t = [1]
  free_vars = row_echelon.form_rational(m, t)
  assert m == [[0]]
  assert t == [1]
  assert free_vars == [0]
  sol = row_echelon.back_substitution_rational(m, t, free_vars, [1])
  assert sol is None
  #
  m = [[1]]
  t = [2]
  free_vars = row_echelon.form_rational(m, t)
  assert m == [[1]]
  assert t == [2]
  assert free_vars == []
  sol = row_echelon.back_substitution_rational(m, t, free_vars, [1])
  assert sol == [2]
  #
  def rr():
    return rational.int(rng.randrange(-5,6), rng.randrange(1,10))
  #
  for i_trial in range(10):
    for nr in [1,2,3]:
      for nc in [1,2,3]:
        m = []
        for ir in range(nr):
          m.append([rr() for ic in range(nc)])
        m_orig = matrix.rec(flat_list(m), (nr,nc))
        sol_orig = [rr() for ic in range(nc)]
        t_orig = list(m_orig * matrix.col(sol_orig))
        t = list(t_orig)
        free_vars = row_echelon.form_rational(m, t)
        sol = [None] * nc
        for ic in free_vars:
          sol[ic] = sol_orig[ic]
        sol = row_echelon.back_substitution_rational(m, t, free_vars, sol)
        assert sol is not None
        assert sol.count(None) == 0
        assert sol == sol_orig
        sol = [1] * nc
        sol = row_echelon.back_substitution_rational(m, None, free_vars, sol)
        assert sol is not None
        assert (m_orig * matrix.col(sol)).dot() == 0
  #
  for i_trial in range(10):
    from itertools import count
    for i in count(10):
      a = matrix.col([rr(), rr(), rr()])
      b = matrix.col([rr(), rr(), rr()])
      if (a.cross(b).dot() != 0):
        break
    else:
      raise RuntimeError
    p = rng.randrange(-5,6)
    q = rng.randrange(-5,6)
    def check(a, b, c, expected_free_vars, expected_sol):
      m = []
      t = []
      for i in range(3):
        m.append([a[i], b[i]])
        t.append(c[i])
      m_orig = matrix.rec(flat_list(m), (3,2))
      t_orig = list(t)
      free_vars = row_echelon.form_rational(m, t)
      assert free_vars == expected_free_vars
      sol = row_echelon.back_substitution_rational(m, t, free_vars, [3, 11])
      assert sol == expected_sol
      if (sol is not None):
        assert list(m_orig * sol) == t_orig
    check(a, b, p*a+q*b, [], [p,q])
    check(a, b, a.cross(b), [], None)
    check(a, 5*a, -7*a, [1], [-62,11])
    check(a, 5*a, b, [1], None)
    check([0,0,0], [0,0,0], [0,0,0], [0,1], [3,11])
  def __init__(self, xray_structure, name='??',
               **kwds):
    super(xray_structure_viewer, self).__init__(
      unit_cell=xray_structure.unit_cell(),
      orthographic=True,
      light_position=(-1, 1, 1, 0),
      **kwds)
    assert self.bonding in ("covalent", "all")
    assert self.bonding != "all" or self.distance_cutoff is not None
    self.xray_structure = xs = xray_structure
    self.setWindowTitle("%s in %s" % (name,
                                      xs.space_group().type().hall_symbol()))
    sites_frac = xs.sites_frac()
    self.set_extent(sites_frac.min(), sites_frac.max())
    self.is_unit_cell_shown = False

    sites_cart = self.sites_cart = xs.sites_cart()
    thermal_tensors = xs.extract_u_cart_plus_u_iso()
    self.ellipsoid_to_sphere_transforms = {}
    self.scatterer_indices = flex.std_string()
    self.scatterer_labels = flex.std_string()
    for i, (sc, site, u_cart) in enumerate(itertools.izip(xs.scatterers(),
                                                          sites_cart,
                                                          thermal_tensors)):
      t = quadrics.ellipsoid_to_sphere_transform(site, u_cart)
      self.ellipsoid_to_sphere_transforms.setdefault(
        sc.element_symbol(),
        quadrics.shared_ellipsoid_to_sphere_transforms()).append(t)
      self.scatterer_indices.append("# %i" % i)
      self.scatterer_labels.append(sc.label)
    self.labels = None
    self.label_font = QtGui.QFont("Arial Black", pointSize=18)

    if self.bonding == "covalent":
      radii = [
        covalent_radii.table(elt).radius()
        for elt in xs.scattering_type_registry().type_index_pairs_as_dict() ]
      buffer_thickness = 2*max(radii) + self.covalent_bond_tolerance
      asu_mappings = xs.asu_mappings(buffer_thickness=buffer_thickness)
      bond_table = crystal.pair_asu_table(asu_mappings)
      bond_table.add_covalent_pairs(xs.scattering_types(),
                                    tolerance=self.covalent_bond_tolerance)
    elif self.bonding == "all":
      asu_mappings = xs.asu_mappings(buffer_thickness=self.distance_cutoff)
      bond_table = crystal.pair_asu_table(asu_mappings)
      bond_table.add_all_pairs(self.distance_cutoff)

    pair_sym_table = bond_table.extract_pair_sym_table(
      all_interactions_from_inside_asu=True)
    self.bonds = flex.vec3_double()
    self.bonds.reserve(len(xs.scatterers()))
    uc = self.xray_structure.unit_cell()
    frac = mat.rec(uc.fractionalization_matrix(), (3,3))
    inv_frac = frac.inverse()
    site_symms = xs.site_symmetry_table()
    scatt = self.xray_structure.scatterers()
    for i, neighbours in enumerate(pair_sym_table):
      x0 = sites_cart[i]
      sc0 = scatt[i]
      for j, ops in neighbours.items():
        sc1 = scatt[j]
        if sc0.scattering_type == 'H' and sc1.scattering_type == 'H':
          continue
        for op in ops:
          if op.is_unit_mx():
            x1 = sites_cart[j]
          else:
            x1 = uc.orthogonalize(op*sites_frac[j])
            op_cart = inv_frac*mat.rec(op.r().as_double(), (3,3))*frac
            u1 = (op_cart
                  *mat.sym(sym_mat3=thermal_tensors[j])
                  *op_cart.transpose())
            t = quadrics.ellipsoid_to_sphere_transform(x1, u1.as_sym_mat3())
            self.ellipsoid_to_sphere_transforms[sc1.element_symbol()].append(t)
            self.sites_cart.append(x1)
            op_lbl = (" [%s]" % op).lower()
            self.scatterer_indices.append("# %i%s" % (j, op_lbl))
            self.scatterer_labels.append("%s%s" % (sc1.label, op_lbl))
          self.bonds.append(x0)
          self.bonds.append(x1)
Exemple #50
0
def glm2(y):
    from math import sqrt, exp, floor, log
    from scipy.stats import poisson
    from scitbx import matrix
    from dials.array_family import flex

    y = flex.double(y)

    x = flex.double([1.0 for yy in y])
    w = flex.double([1.0 for yy in y])

    X = matrix.rec(x, (len(x), 1))

    c = 1.345

    beta = matrix.col([0])

    maxiter = 10
    accuracy = 1e-3

    for iter in range(maxiter):

        ni = flex.double([1.0 for xx in x])
        sni = flex.sqrt(ni)

        eta = flex.double(X * beta)

        mu = flex.exp(eta)
        dmu_deta = flex.exp(eta)

        Vmu = mu
        sVF = flex.sqrt(Vmu)
        residP = (y - mu) * sni / sVF

        phi = 1
        sV = sVF * sqrt(phi)
        residPS = residP / sqrt(phi)

        H = flex.floor(mu * ni - c * sni * sV)
        K = flex.floor(mu * ni + c * sni * sV)
        # print min(H)
        dpH = flex.double([poisson(mui).pmf(Hi) for mui, Hi in zip(mu, H)])
        dpH1 = flex.double([poisson(mui).pmf(Hi - 1) for mui, Hi in zip(mu, H)])
        dpK = flex.double([poisson(mui).pmf(Ki) for mui, Ki in zip(mu, K)])
        dpK1 = flex.double([poisson(mui).pmf(Ki - 1) for mui, Ki in zip(mu, K)])
        pHm1 = flex.double([poisson(mui).cdf(Hi - 1) for mui, Hi in zip(mu, H)])
        pKm1 = flex.double([poisson(mui).cdf(Ki - 1) for mui, Ki in zip(mu, K)])
        pH = pHm1 + dpH  # = ppois(H,*)
        pK = pKm1 + dpK  # = ppois(K,*)
        E2f = mu * (dpH1 - dpH - dpK1 + dpK) + pKm1 - pHm1
        Epsi = c * (1.0 - pK - pH) + (mu / sV) * (dpH - dpK)
        Epsi2 = c * c * (pH + 1.0 - pK) + E2f
        EpsiS = c * (dpH + dpK) + E2f / sV

        psi = flex.double([huber(rr, c) for rr in residPS])
        cpsi = psi - Epsi
        temp = cpsi * w * sni / sV * dmu_deta
        EEqMat = [0] * len(X)
        for j in range(X.n_rows()):
            for i in range(X.n_columns()):
                k = i + j * X.n_columns()
                EEqMat[k] = X[k] * temp[j]
        EEqMat = matrix.rec(EEqMat, (X.n_rows(), X.n_columns()))
        EEq = []
        for i in range(EEqMat.n_columns()):
            col = []
            for j in range(EEqMat.n_rows()):
                k = i + j * EEqMat.n_columns()
                col.append(EEqMat[k])
            EEq.append(sum(col) / len(col))
        EEq = matrix.col(EEq)
        DiagB = EpsiS / (sni * sV) * w * (ni * dmu_deta) ** 2
        B = matrix.diag(DiagB)
        H = (X.transpose() * B * X) / len(y)

        dbeta = H.inverse() * EEq
        beta_new = beta + dbeta

        relE = sqrt(sum([d * d for d in dbeta]) / max(1e-10, sum([d * d for d in beta])))
        beta = beta_new

        # print relE
        if relE < accuracy:
            break

    weights = [min(1, c / abs(r)) for r in residPS]

    eta = flex.double(X * beta)

    mu = flex.exp(eta)
    return beta
Exemple #51
0
from scipy.stats import linregress
from scipy.spatial.transform import Rotation
from simtbx.nanoBragg import sim_data
from scitbx.matrix import sqr, rec
from cctbx import uctbx
from dxtbx.model import Crystal

ucell = (70, 60, 50, 90.0, 110, 90.0)
symbol = "C121"

a_real, b_real, c_real = sqr(uctbx.unit_cell(ucell).orthogonalization_matrix()).transpose().as_list_of_lists()
C = Crystal(a_real, b_real, c_real, symbol)

# random raotation
rotation = Rotation.random(num=1, random_state=101)[0]
Q = rec(rotation.as_quat(), n=(4, 1))
rot_ang, rot_axis = Q.unit_quaternion_as_axis_and_angle()
C.rotate_around_origin(rot_axis, rot_ang)

S = sim_data.SimData(use_default_crystal=True)
S.crystal.dxtbx_crystal = C
spectrum = S.beam.spectrum
wave, flux = spectrum[0]
Nwave = 5
waves = np.linspace(wave-wave*0.002, wave+wave*0.002, Nwave)
fluxes = np.ones(Nwave) * flux / Nwave

lambda0_GT = 0
lambda1_GT = 1

S.beam.spectrum = list(zip(waves, fluxes))
def exercise_rational():
  from scitbx.matrix import row_echelon
  from scitbx import matrix
  from libtbx.utils import flat_list
  from boost import rational
  import random
  rng = random.Random(0)
  #
  m = [[0]]
  t = [0]
  free_vars = row_echelon.form_rational(m, t)
  assert m == [[0]]
  assert t == [0]
  assert free_vars == [0]
  sol = row_echelon.back_substitution_rational(m, t, free_vars, [1])
  assert sol == [1]
  sol = row_echelon.back_substitution_rational(m, None, free_vars, [2])
  assert sol == [2]
  #
  m = [[0]]
  t = [1]
  free_vars = row_echelon.form_rational(m, t)
  assert m == [[0]]
  assert t == [1]
  assert free_vars == [0]
  sol = row_echelon.back_substitution_rational(m, t, free_vars, [1])
  assert sol is None
  #
  m = [[1]]
  t = [2]
  free_vars = row_echelon.form_rational(m, t)
  assert m == [[1]]
  assert t == [2]
  assert free_vars == []
  sol = row_echelon.back_substitution_rational(m, t, free_vars, [1])
  assert sol == [2]
  #
  def rr():
    return rational.int(rng.randrange(-5,6), rng.randrange(1,10))
  #
  for i_trial in xrange(10):
    for nr in [1,2,3]:
      for nc in [1,2,3]:
        m = []
        for ir in xrange(nr):
          m.append([rr() for ic in xrange(nc)])
        m_orig = matrix.rec(flat_list(m), (nr,nc))
        sol_orig = [rr() for ic in xrange(nc)]
        t_orig = list(m_orig * matrix.col(sol_orig))
        t = list(t_orig)
        free_vars = row_echelon.form_rational(m, t)
        sol = [None] * nc
        for ic in free_vars:
          sol[ic] = sol_orig[ic]
        sol = row_echelon.back_substitution_rational(m, t, free_vars, sol)
        assert sol is not None
        assert sol.count(None) == 0
        assert sol == sol_orig
        sol = [1] * nc
        sol = row_echelon.back_substitution_rational(m, None, free_vars, sol)
        assert sol is not None
        assert (m_orig * matrix.col(sol)).dot() == 0
  #
  for i_trial in xrange(10):
    from itertools import count
    for i in count(10):
      a = matrix.col([rr(), rr(), rr()])
      b = matrix.col([rr(), rr(), rr()])
      if (a.cross(b).dot() != 0):
        break
    else:
      raise RuntimeError
    p = rng.randrange(-5,6)
    q = rng.randrange(-5,6)
    def check(a, b, c, expected_free_vars, expected_sol):
      m = []
      t = []
      for i in xrange(3):
        m.append([a[i], b[i]])
        t.append(c[i])
      m_orig = matrix.rec(flat_list(m), (3,2))
      t_orig = list(t)
      free_vars = row_echelon.form_rational(m, t)
      assert free_vars == expected_free_vars
      sol = row_echelon.back_substitution_rational(m, t, free_vars, [3, 11])
      assert sol == expected_sol
      if (sol is not None):
        assert list(m_orig * sol) == t_orig
    check(a, b, p*a+q*b, [], [p,q])
    check(a, b, a.cross(b), [], None)
    check(a, 5*a, -7*a, [1], [-62,11])
    check(a, 5*a, b, [1], None)
    check([0,0,0], [0,0,0], [0,0,0], [0,1], [3,11])
Exemple #53
0
 def df_d_params(self):
     tphkl = 2 * math.pi * matrix.col(self.hkl)
     h, k, l = self.hkl
     d_exp_huh_d_u_star = matrix.col(
         [h**2, k**2, l**2, 2 * h * k, 2 * h * l, 2 * k * l])
     for i_scatterer, scatterer in enumerate(self.scatterers):
         site_symmetry_ops = None
         if (self.site_symmetry_table.is_special_position(i_scatterer)):
             site_symmetry_ops = self.site_symmetry_table.get(i_scatterer)
             site_constraints = site_symmetry_ops.site_constraints()
             if (scatterer.flags.use_u_aniso()):
                 adp_constraints = site_symmetry_ops.adp_constraints()
         w = scatterer.weight()
         wwo = scatterer.weight_without_occupancy()
         if (not scatterer.flags.use_u_aniso()):
             huh = scatterer.u_iso * self.d_star_sq
             dw = math.exp(mtps * huh)
         gaussian = self.scattering_type_registry.gaussian_not_optional(
             scattering_type=scatterer.scattering_type)
         f0 = gaussian.at_d_star_sq(self.d_star_sq)
         ffp = f0 + scatterer.fp
         fdp = scatterer.fdp
         ff = ffp + 1j * fdp
         d_site = matrix.col([0, 0, 0])
         if (not scatterer.flags.use_u_aniso()):
             d_u_iso = 0
             d_u_star = None
         else:
             d_u_iso = None
             d_u_star = matrix.col([0, 0, 0, 0, 0, 0])
         d_occ = 0j
         d_fp = 0j
         d_fdp = 0j
         for s in self.space_group:
             r = s.r().as_rational().as_float()
             s_site = s * scatterer.site
             alpha = matrix.col(s_site).dot(tphkl)
             if (scatterer.flags.use_u_aniso()):
                 s_u_star_s = r * matrix.sym(
                     sym_mat3=scatterer.u_star) * r.transpose()
                 huh = (matrix.row(self.hkl) * s_u_star_s).dot(
                     matrix.col(self.hkl))
                 dw = math.exp(mtps * huh)
             e = cmath.exp(1j * alpha)
             site_gtmx = r.transpose()
             d_site += site_gtmx * (w * dw * ff * e * 1j * tphkl)
             if (not scatterer.flags.use_u_aniso()):
                 d_u_iso += w * dw * ff * e * mtps * self.d_star_sq
             else:
                 u_star_gtmx = matrix.sqr(
                     tensor_rank_2_gradient_transform_matrix(r))
                 d_u_star += u_star_gtmx * (w * dw * ff * e * mtps *
                                            d_exp_huh_d_u_star)
             d_occ += wwo * dw * ff * e
             d_fp += w * dw * e
             d_fdp += w * dw * e * 1j
         if (site_symmetry_ops is not None):
             gsm = site_constraints.gradient_sum_matrix()
             gsm = matrix.rec(elems=gsm, n=gsm.focus())
             d_site = gsm * d_site
             if (scatterer.flags.use_u_aniso()):
                 gsm = adp_constraints.gradient_sum_matrix()
                 gsm = matrix.rec(elems=gsm, n=gsm.focus())
                 d_u_star = gsm * d_u_star
         result = flex.complex_double(d_site)
         if (not scatterer.flags.use_u_aniso()):
             result.append(d_u_iso)
         else:
             result.extend(flex.complex_double(d_u_star))
         result.extend(flex.complex_double([d_occ, d_fp, d_fdp]))
         yield result
def _get_flex_image_multipanel(panels, raw_data, brightness=1.0, show_untrusted=False):
  # From xfel.cftbx.cspad_detector.readHeader() and
  # xfel.cftbx.cspad_detector.get_flex_image().  XXX Is it possible to
  # merge this with _get_flex_image() above?  XXX Move to dxtbx Format
  # class (or a superclass for multipanel images)?

  from math import ceil

  from iotbx.detectors import generic_flex_image
  from libtbx.test_utils import approx_equal
  from scitbx.array_family import flex
  from scitbx.matrix import col, rec, sqr
  from xfel.cftbx.detector.metrology import get_projection_matrix

  assert len(panels) == len(raw_data)

  # Determine next multiple of eight of the largest panel size.
  for data in raw_data:
    if 'data_max_focus' not in locals():
      data_max_focus = data.focus()
    else:
      data_max_focus = (max(data_max_focus[0], data.focus()[0]),
                        max(data_max_focus[1], data.focus()[1]))
  data_padded = (8 * int(ceil(data_max_focus[0] / 8)),
                 8 * int(ceil(data_max_focus[1] / 8)))

  # Assert that all saturated values are equal and not None.  While
  # dxtbx records a separated trusted_range for each panel,
  # generic_flex_image supports only accepts a single common value for
  # the saturation.
  for panel in panels:
    if 'saturation' not in locals():
      saturation = panel.get_trusted_range()[1]
    else:
      assert approx_equal(saturation, panel.get_trusted_range()[1])
  assert 'saturation' in locals() and saturation is not None

  # Create rawdata and my_flex_image before populating it.
  rawdata = flex.double(
    flex.grid(len(panels) * data_padded[0], data_padded[1]))
  my_flex_image = generic_flex_image(
    rawdata=rawdata,
    size1_readout=data_max_focus[0],
    size2_readout=data_max_focus[1],
    brightness=brightness,
    saturation=saturation,
    show_untrusted=show_untrusted
  )

  # XXX If a point is contained in two panels simultaneously, it will
  # be assigned to the panel defined first.  XXX Use a Z-buffer
  # instead?
  for i in range(len(panels)):
    # Determine the pixel size for the panel (in meters), as pixel
    # sizes need not be identical.
    data = raw_data[i]
    panel = panels[i]
    pixel_size = (panel.get_pixel_size()[0] * 1e-3,
                  panel.get_pixel_size()[1] * 1e-3)

    if len(panels) == 24 and panels[0].get_image_size() == (2463,195):
      #print "DLS I23 12M"
      rawdata.matrix_paste_block_in_place(
        block=data.as_double(),
        i_row=i * data_padded[0],
        i_column=0)
      # XXX hardcoded panel height and row gap
      my_flex_image.add_transformation_and_translation((1,0,0,1), (-i*(195+17),0))

      continue

    elif len(panels) == 120 and panels[0].get_image_size() == (487,195):
      i_row = i // 5
      i_col = i % 5
      #print i_row, i_col
      #print data_padded
      #print "DLS I23 12M"
      rawdata.matrix_paste_block_in_place(
        block=data.as_double(),
        i_row=i * data_padded[0],
        i_column=0)
      # XXX hardcoded panel height and row gap
      my_flex_image.add_transformation_and_translation(
        (1,0,0,1), (-i_row*(195+17),-i_col*(487+7)))

      continue

    # Get unit vectors in the fast and slow directions, as well as the
    # the locations of the origin and the center of the panel, in
    # meters.
    fast = col(panel.get_fast_axis())
    slow = col(panel.get_slow_axis())
    origin = col(panel.get_origin()) * 1e-3

    # Viewer will show an orthographic projection of the data onto a plane perpendicular to 0 0 1
    projection_normal = col((0.,0.,1.))
    beam_to_origin_proj = origin.dot(projection_normal)*projection_normal
    projected_origin = origin - beam_to_origin_proj

    center = projected_origin \
             + (data.focus()[0] - 1) / 2 * pixel_size[1] * slow \
             + (data.focus()[1] - 1) / 2 * pixel_size[0] * fast
    normal = slow.cross(fast).normalize()

    # Determine rotational and translational components of the
    # homogeneous transformation that maps the readout indices to the
    # three-dimensional laboratory frame.
    Rf = sqr((  fast(0, 0),   fast(1, 0),   fast(2, 0),
               -slow(0, 0),  -slow(1, 0),  -slow(2, 0),
              normal(0, 0), normal(1, 0), normal(2, 0)))
    tf = -Rf * center
    Tf = sqr((Rf(0, 0), Rf(0, 1), Rf(0, 2), tf(0, 0),
              Rf(1, 0), Rf(1, 1), Rf(1, 2), tf(1, 0),
              Rf(2, 0), Rf(2, 1), Rf(2, 2), tf(2, 0),
              0,        0,        0,        1))

    # E maps picture coordinates onto metric Cartesian coordinates,
    # i.e. [row, column, 1 ] -> [x, y, z, 1].  Both frames share the
    # same origin, but the first coordinate of the screen coordinate
    # system increases downwards, while the second increases towards
    # the right.  XXX Is this orthographic projection the only one
    # that makes any sense?
    E = rec(elems=[0, +pixel_size[1], 0,
                   -pixel_size[0], 0, 0,
                   0, 0, 0,
                   0, 0, 1],
            n=[4, 3])

    # P: [x, y, z, 1] -> [row, column, 1].  Note that data.focus()
    # needs to be flipped to give (horizontal, vertical) size,
    # i.e. (width, height).
    Pf = get_projection_matrix(
      pixel_size, (data.focus()[1], data.focus()[0]))[0]

    rawdata.matrix_paste_block_in_place(
      block=data.as_double(),
      i_row=i * data_padded[0],
      i_column=0)

    # Last row of T is always [0, 0, 0, 1].
    T = Pf * Tf * E
    R = sqr((T(0, 0), T(0, 1),
             T(1, 0), T(1, 1)))
    t = col((T(0, 2), T(1, 2)))
    #print i,R[0],R[1],R[2],R[3],t[0],t[1]

    my_flex_image.add_transformation_and_translation(R, t)
  my_flex_image.followup_brightness_scale()
  return my_flex_image
Exemple #55
0
def glm(x, p = None):
  from math import exp , sqrt, log, factorial, lgamma
  from scitbx import matrix
  from scipy.stats import poisson
  beta0 = 0

  if p is None:
    p = [1.0] * len(x)

  while True:
    n = beta0
    mu = exp(n)
    z = [n + (xx - mu) / mu for xx in x]
    w = [pp * mu for pp in p]

    W = matrix.diag(w)
    Z = matrix.col(z)
    X = matrix.rec([1]*len(z), (len(z),1))

    beta = (X.transpose() * W * X).inverse() * X.transpose()*W*z

    if abs(beta[0] - beta0) < 1e-3:
      break
    beta0 = beta[0]

  n = beta[0]
  mu = exp(n)
  z = [n + (xx - mu) / mu for xx in x]
  w = [pp * mu for pp in p]

  W = matrix.diag(w)
  Z = matrix.col(z)
  X = matrix.rec([1]*len(z), (len(z),1))
  W12 = matrix.diag([sqrt(ww) for ww in w])
  H = X * (X.transpose()*W*X).inverse() * X.transpose()

  r = [(xx - mu) / mu for xx in x]
  sum1 = 0
  sum2 = 0
  sum3 = 0
  D = []
  for xx in x:
    d = 0
    if xx != 0:
      d += xx * log(xx)
      d -= xx * log(mu)
    d -= (xx - mu)
    D.append(2*d)
  # r = []
  # for xx in x:
  #   if xx == 0:
  #     r.append(0)
  #   else:
  #     r.append(2*(log(xx) - log(mu)))
  # D = []
  # for i in range(len(r)):
  #   h = H[i+i*H.n[0]]
  #   d = (r[i]/(1 - h))**2 * h/1.0
  #   D.append(d)

  # print min(x), max(x)
  print min(D), max(D), F(1, len(x))

  return exp(beta[0]), max(D) > F(1, len(x))
def _get_flex_image_multipanel(
    panels,
    raw_data,
    beam,
    brightness=1.0,
    binning=1,
    show_untrusted=False,
    color_scheme=0,
):
    # From xfel.cftbx.cspad_detector.readHeader() and
    # xfel.cftbx.cspad_detector.get_flex_image().  XXX Is it possible to
    # merge this with _get_flex_image() above?  XXX Move to dxtbx Format
    # class (or a superclass for multipanel images)?

    from math import ceil

    from iotbx.detectors import generic_flex_image
    from libtbx.test_utils import approx_equal
    from scitbx.array_family import flex
    from scitbx.matrix import col, rec, sqr
    from xfel.cftbx.detector.metrology import get_projection_matrix

    assert len(panels) == len(raw_data), (len(panels), len(raw_data))

    # Determine next multiple of eight of the largest panel size.
    for data in raw_data:
        if "data_max_focus" not in locals():
            data_max_focus = data.focus()
        else:
            data_max_focus = (
                max(data_max_focus[0],
                    data.focus()[0]),
                max(data_max_focus[1],
                    data.focus()[1]),
            )
    data_padded = (
        8 * int(ceil(data_max_focus[0] / 8)),
        8 * int(ceil(data_max_focus[1] / 8)),
    )

    # Assert that all saturated values are equal and not None.  While
    # dxtbx records a separated trusted_range for each panel,
    # generic_flex_image supports only accepts a single common value for
    # the saturation.
    for panel in panels:
        if "saturation" not in locals():
            saturation = panel.get_trusted_range()[1]
        else:
            assert approx_equal(saturation, panel.get_trusted_range()[1])
    assert "saturation" in locals() and saturation is not None

    # Create rawdata and my_flex_image before populating it.
    rawdata = flex.double(
        flex.grid(len(panels) * data_padded[0], data_padded[1]))
    my_flex_image = generic_flex_image(
        rawdata=rawdata,
        binning=binning,
        size1_readout=data_max_focus[0],
        size2_readout=data_max_focus[1],
        brightness=brightness,
        saturation=saturation,
        show_untrusted=show_untrusted,
        color_scheme=color_scheme,
    )

    # Calculate the average beam center across all panels, in meters
    # not sure this makes sense for detector which is not on a plane?
    beam_center = col((0, 0, 0))
    npanels = 0
    for panel in panels:
        try:
            beam_center += col(panel.get_beam_centre_lab(beam.get_s0()))
            npanels += 1
        except RuntimeError:  # catch DXTBX_ASSERT for no intersection
            pass
    beam_center /= npanels / 1e-3

    # XXX If a point is contained in two panels simultaneously, it will
    # be assigned to the panel defined first.  XXX Use a Z-buffer
    # instead?
    for i, panel in enumerate(panels):
        # Determine the pixel size for the panel (in meters), as pixel
        # sizes need not be identical.
        data = raw_data[i]
        pixel_size = (
            panel.get_pixel_size()[0] * 1e-3,
            panel.get_pixel_size()[1] * 1e-3,
        )

        if len(panels) == 24 and panels[0].get_image_size() == (2463, 195):
            rawdata.matrix_paste_block_in_place(block=data.as_double(),
                                                i_row=i * data_padded[0],
                                                i_column=0)
            # XXX hardcoded panel height and row gap
            my_flex_image.add_transformation_and_translation(
                (1, 0, 0, 1), (-i * (195 + 17), 0))

            continue

        elif len(panels) == 120 and panels[0].get_image_size() == (487, 195):
            i_row = i // 5
            i_col = i % 5
            rawdata.matrix_paste_block_in_place(block=data.as_double(),
                                                i_row=i * data_padded[0],
                                                i_column=0)
            # XXX hardcoded panel height and row gap
            my_flex_image.add_transformation_and_translation(
                (1, 0, 0, 1), (-i_row * (195 + 17), -i_col * (487 + 7)))

            continue

        # Get unit vectors in the fast and slow directions, as well as the
        # the locations of the origin and the center of the panel, in
        # meters. The origin is taken w.r.t. to average beam center of all
        # panels. This avoids excessive translations that can result from
        # rotations around the laboratory origin. Related to beam centre above
        # and dials#380 not sure this is right for detectors which are not
        # coplanar since system derived from first panel...
        fast = col(panel.get_fast_axis())
        slow = col(panel.get_slow_axis())
        origin = col(panel.get_origin()) * 1e-3 - beam_center

        center = (origin + (data.focus()[0] - 1) / 2 * pixel_size[1] * slow +
                  (data.focus()[1] - 1) / 2 * pixel_size[0] * fast)
        normal = slow.cross(fast).normalize()

        # Determine rotational and translational components of the
        # homogeneous transformation that maps the readout indices to the
        # three-dimensional laboratory frame.
        Rf = sqr((
            fast(0, 0),
            fast(1, 0),
            fast(2, 0),
            -slow(0, 0),
            -slow(1, 0),
            -slow(2, 0),
            normal(0, 0),
            normal(1, 0),
            normal(2, 0),
        ))
        tf = -Rf * center
        Tf = sqr((
            Rf(0, 0),
            Rf(0, 1),
            Rf(0, 2),
            tf(0, 0),
            Rf(1, 0),
            Rf(1, 1),
            Rf(1, 2),
            tf(1, 0),
            Rf(2, 0),
            Rf(2, 1),
            Rf(2, 2),
            tf(2, 0),
            0,
            0,
            0,
            1,
        ))

        # E maps picture coordinates onto metric Cartesian coordinates,
        # i.e. [row, column, 1 ] -> [x, y, z, 1].  Both frames share the
        # same origin, but the first coordinate of the screen coordinate
        # system increases downwards, while the second increases towards
        # the right.  XXX Is this orthographic projection the only one
        # that makes any sense?
        E = rec(
            elems=[
                0, +pixel_size[1], 0, -pixel_size[0], 0, 0, 0, 0, 0, 0, 0, 1
            ],
            n=[4, 3],
        )

        # P: [x, y, z, 1] -> [row, column, 1].  Note that data.focus()
        # needs to be flipped to give (horizontal, vertical) size,
        # i.e. (width, height).
        Pf = get_projection_matrix(pixel_size,
                                   (data.focus()[1], data.focus()[0]))[0]

        rawdata.matrix_paste_block_in_place(block=data.as_double(),
                                            i_row=i * data_padded[0],
                                            i_column=0)

        # Last row of T is always [0, 0, 0, 1].
        T = Pf * Tf * E
        R = sqr((T(0, 0), T(0, 1), T(1, 0), T(1, 1)))
        t = col((T(0, 2), T(1, 2)))
        my_flex_image.add_transformation_and_translation(R, t)
    my_flex_image.followup_brightness_scale()
    return my_flex_image
Exemple #57
0
    def __init__(self, ub_beg, ub_end, axis, s0, dmin, margin=3):

        # the source vector and wavelength
        self._source = -s0
        self._wavelength = 1 / sqrt(s0.dot(s0))
        self._wavelength_sq = self._wavelength**2

        # the rotation axis
        self._axis = axis

        # the resolution limit
        self._dstarmax = 1 / dmin
        self._dstarmax2 = self._dstarmax**2

        # Margin by which to expand limits. Mosflm uses 3.
        self._margin = int(margin)

        # Determine the permutation order of columns of the setting matrix. Use
        # the setting from the beginning for this.
        # As a side-effect set self._permutation.
        col1, col2, col3 = self._permute_axes(ub_beg)

        # Thus set the reciprocal lattice axis vectors, in permuted order
        # p, q and r for both orientations
        rl_vec = [
            ub_beg.extract_block(start=(0, 0), stop=(3, 1)),
            ub_beg.extract_block(start=(0, 1), stop=(3, 2)),
            ub_beg.extract_block(start=(0, 2), stop=(3, 3))
        ]
        self._rlv_beg = [rl_vec[col1], rl_vec[col2], rl_vec[col3]]
        rl_vec = [
            ub_end.extract_block(start=(0, 0), stop=(3, 1)),
            ub_end.extract_block(start=(0, 1), stop=(3, 2)),
            ub_end.extract_block(start=(0, 2), stop=(3, 3))
        ]
        self._rlv_end = [rl_vec[col1], rl_vec[col2], rl_vec[col3]]

        # Set permuted setting matrices
        self._p_beg = matrix.sqr(self._rlv_beg[0].elems +
                                 self._rlv_beg[1].elems +
                                 self._rlv_beg[2].elems).transpose()
        self._p_end = matrix.sqr(self._rlv_end[0].elems +
                                 self._rlv_end[1].elems +
                                 self._rlv_end[2].elems).transpose()

        ## Define a new coordinate system concentric with the Ewald sphere.
        ##
        ## X' = X - source_x
        ## Y' = Y - source_y
        ## Z' = Z - source_z
        ##
        ## X = P' h'
        ## -   =  -
        ##                                    / p11 p12 p13 -source_X \
        ## where h' = (p, q, r, 1)^T and P' = | p21 p22 p23 -source_y |
        ##       -                       =    \ p31 p32 p33 -source_z /
        ##

        # Calculate P' matrices for the beginning and end settings
        pp_beg = matrix.rec(
            self._p_beg.elems[0:3] + (-1. * self._source[0], ) +
            self._p_beg.elems[3:6] + (-1. * self._source[1], ) +
            self._p_beg.elems[6:9] + (-1. * self._source[2], ),
            n=(3, 4))
        pp_end = matrix.rec(
            self._p_end.elems[0:3] + (-1. * self._source[0], ) +
            self._p_end.elems[3:6] + (-1. * self._source[1], ) +
            self._p_end.elems[6:9] + (-1. * self._source[2], ),
            n=(3, 4))

        # Various quantities of interest are obtained from the reciprocal metric
        # tensor T of P'. These quantities are to be used (later) for solving
        # the intersection of a line of constant p, q index with the Ewald
        # sphere. It is efficient to calculate these before the outer loop. So,
        # calculate T for both beginning and end settings

        t_beg = (pp_beg.transpose() * pp_beg).as_list_of_lists()
        t_end = (pp_end.transpose() * pp_end).as_list_of_lists()

        # quantities that are constant with p, beginning orientation
        self._cp_beg = [
            t_beg[2][2], t_beg[2][3]**2,
            t_beg[0][2] * t_beg[2][3] - t_beg[0][3] * t_beg[2][2],
            t_beg[0][2]**2 - t_beg[0][0] * t_beg[2][2],
            t_beg[1][2] * t_beg[2][3] - t_beg[1][3] * t_beg[2][2],
            t_beg[0][2] * t_beg[1][2] - t_beg[0][1] * t_beg[2][2],
            t_beg[1][2]**2 - t_beg[1][1] * t_beg[2][2], 2.0 * t_beg[0][2],
            2.0 * t_beg[1][2], t_beg[0][0], t_beg[1][1], 2.0 * t_beg[0][1],
            2.0 * t_beg[2][3], 2.0 * t_beg[1][3], 2.0 * t_beg[0][3]
        ]

        # quantities that are constant with p, end orientation
        self._cp_end = [
            t_end[2][2], t_end[2][3]**2,
            t_end[0][2] * t_end[2][3] - t_end[0][3] * t_end[2][2],
            t_end[0][2]**2 - t_end[0][0] * t_end[2][2],
            t_end[1][2] * t_end[2][3] - t_end[1][3] * t_end[2][2],
            t_end[0][2] * t_end[1][2] - t_end[0][1] * t_end[2][2],
            t_end[1][2]**2 - t_end[1][1] * t_end[2][2], 2.0 * t_end[0][2],
            2.0 * t_end[1][2], t_end[0][0], t_end[1][1], 2.0 * t_end[0][1],
            2.0 * t_end[2][3], 2.0 * t_end[1][3], 2.0 * t_end[0][3]
        ]

        ## The following are set during the generation of indices

        # planes of constant p tangential to the Ewald sphere
        self._ewald_p_lim_beg = None
        self._ewald_p_lim_end = None

        # planes of constant p touching the circle of intersection between the
        # Ewald and resolution limiting spheres
        self._res_p_lim_beg = None
        self._res_p_lim_end = None

        # looping p limits
        self._p_lim = None

        return
Exemple #58
0
    def _calc_cell_parameter_sd(self):

        # self._cov_B is the covariance matrix of elements of the B matrix. We
        # need to construct the covariance matrix of elements of the
        # transpose of B. The vector of elements of B is related to the
        # vector of elements of its transpose by a permutation, P.
        P = matrix.sqr((
            1,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            1,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            1,
            0,
            0,
            0,
            1,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            1,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            1,
            0,
            0,
            0,
            1,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            1,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            1,
        ))

        # We can use P to replace var_cov with the covariance matrix of
        # elements of the transpose of B.
        var_cov = P * self._cov_B * P

        # From B = (O^-1)^T we can convert this
        # to the covariance matrix of the real space orthogonalisation matrix
        Bt = self._B.transpose()
        O = Bt.inverse()  # noqa: E741, is name of the matrix
        cov_O = matrix_inverse_error_propagation(Bt, var_cov)

        # The real space unit cell vectors are given by
        vec_a = O * matrix.col((1, 0, 0))
        vec_b = O * matrix.col((0, 1, 0))
        vec_c = O * matrix.col((0, 0, 1))

        # So the unit cell parameters are
        a, b, c = vec_a.length(), vec_b.length(), vec_c.length()
        # alpha = acos(vec_b.dot(vec_c) / (b * c))
        # beta = acos(vec_a.dot(vec_c) / (a * c))
        # gamma = acos(vec_a.dot(vec_b) / (a * b))

        # The estimated errors are calculated by error propagation from cov_O. In
        # each case we define a function F(O) that converts the matrix O into the
        # unit cell parameter of interest. To do error propagation to get the
        # variance of that cell parameter we need the Jacobian of the function.
        # This is a 1*9 matrix of derivatives in the order of the elements of O
        #
        #     / dF   dF   dF   dF   dF   dF   dF   dF   dF  \
        # J = | ---, ---, ---, ---, ---, ---, ---, ---, --- |
        #     \ da1  db1  dc1  da2  db2  dc2  da3  db3  dc3 /
        #

        # For cell length |a|, F = sqrt(a1^2 + a2^2 + a3^2)
        jacobian = matrix.rec(
            (vec_a[0] / a, 0, 0, vec_a[1] / a, 0, 0, vec_a[2] / a, 0, 0),
            (1, 9))
        var_a = (jacobian * cov_O * jacobian.transpose())[0]

        # For cell length |b|, F = sqrt(b1^2 + b2^2 + b3^2)
        jacobian = matrix.rec(
            (0, vec_b[0] / b, 0, 0, vec_b[1] / b, 0, 0, vec_b[2] / b, 0),
            (1, 9))
        var_b = (jacobian * cov_O * jacobian.transpose())[0]

        # For cell length |c|, F = sqrt(c1^2 + c2^2 + c3^2)
        jacobian = matrix.rec(
            (0, 0, vec_c[0] / c, 0, 0, vec_c[1] / c, 0, 0, vec_c[2] / c),
            (1, 9))
        var_c = (jacobian * cov_O * jacobian.transpose())[0]

        # For cell volume (a X b).c,
        # F = c1(a2*b3 - b2*a3) + c2(a3*b1 - b3*a1) + c3(a1*b2 - b1*a2)
        a1, a2, a3 = vec_a
        b1, b2, b3 = vec_b
        c1, c2, c3 = vec_c
        jacobian = matrix.rec(
            (
                c3 * b2 - c2 * b3,
                c1 * b3 - c3 * b1,
                c2 * b1 - c1 * b2,
                c2 * a3 - c3 * a2,
                c3 * a1 - c1 * a3,
                c1 * a2 - c2 * a1,
                a2 * b3 - b2 * a3,
                a3 * b1 - b3 * a1,
                a1 * b2 - b1 * a2,
            ),
            (1, 9),
        )
        var_V = (jacobian * cov_O * jacobian.transpose())[0]
        self._cell_volume_sd = sqrt(var_V)

        # For the unit cell angles we need to calculate derivatives of the angles
        # with respect to the elements of O
        dalpha_db, dalpha_dc = angle_derivative_wrt_vectors(vec_b, vec_c)
        dbeta_da, dbeta_dc = angle_derivative_wrt_vectors(vec_a, vec_c)
        dgamma_da, dgamma_db = angle_derivative_wrt_vectors(vec_a, vec_b)

        # For angle alpha, F = acos( b.c / |b||c|)
        jacobian = matrix.rec(
            (
                0,
                dalpha_db[0],
                dalpha_dc[0],
                0,
                dalpha_db[1],
                dalpha_dc[1],
                0,
                dalpha_db[2],
                dalpha_dc[2],
            ),
            (1, 9),
        )
        var_alpha = (jacobian * cov_O * jacobian.transpose())[0]

        # For angle beta, F = acos( a.c / |a||c|)
        jacobian = matrix.rec(
            (
                dbeta_da[0],
                0,
                dbeta_dc[0],
                dbeta_da[1],
                0,
                dbeta_dc[1],
                dbeta_da[2],
                0,
                dbeta_dc[2],
            ),
            (1, 9),
        )
        var_beta = (jacobian * cov_O * jacobian.transpose())[0]

        # For angle gamma, F = acos( a.b / |a||b|)
        jacobian = matrix.rec(
            (
                dgamma_da[0],
                dgamma_db[0],
                0,
                dgamma_da[1],
                dgamma_db[1],
                0,
                dgamma_da[2],
                dgamma_db[2],
                0,
            ),
            (1, 9),
        )
        var_gamma = (jacobian * cov_O * jacobian.transpose())[0]

        # Symmetry constraints may mean variances of the angles should be zero.
        # Floating point error could lead to negative variances. Ensure these are
        # caught before taking their square root!
        var_alpha = max(0, var_alpha)
        var_beta = max(0, var_beta)
        var_gamma = max(0, var_gamma)

        rad2deg = 180.0 / pi
        self._cell_sd = (
            sqrt(var_a),
            sqrt(var_b),
            sqrt(var_c),
            sqrt(var_alpha) * rad2deg,
            sqrt(var_beta) * rad2deg,
            sqrt(var_gamma) * rad2deg,
        )