Пример #1
0
 def __init__(self, v1, v2, frames, session):
     self.view1 = v1
     self.view2 = v2
     self.frames = frames
     self.centers = _model_motion_centers(v1.positions, v2.positions)
     if frames == 1:
         self.frame_cb(session, 0)
     else:
         from chimerax.core.commands import motion
         motion.CallForNFrames(self.frame_cb, frames, session)
Пример #2
0
def show_residue_fit(session, residues, map, range = 2, last_pos = None, motion_frames = 20):
    '''Set camera to show first residue in list and display map in zone around given residues.'''
    res = residues[0]
    ratoms = res.atoms
    anames = tuple(ratoms.names)
    try:
        i = [anames.index(aname) for aname in ('N', 'CA', 'C')]
    except ValueError:
        return None		# Missing backbone atom
    xyz = ratoms.filter(i).scene_coords

    # Align backbone to template backbone coords
    from chimerax.geometry import align_points, Place
    from numpy import array
    txyz = array([[ 12.83300018,   6.83900023,   6.73799992],
                  [ 12.80800056,   7.87400055,   5.70799971],
                  [ 11.91800022,   9.06700039,   5.9920001 ]])
    p, rms = align_points(txyz, xyz)

    # Set camera view relative to template.
    c = session.main_view.camera
    cp = c.position
    if last_pos is None:
        tc = Place(((-0.46696,0.38225,-0.79739,-3.9125),
                    (0.81905,-0.15294,-0.55296,-4.3407),
                    (-0.33332,-0.91132,-0.24166,-1.4889)))
        if c.name == 'orthographic':
            c.field_width = 12		# Set orthographic field of view, Angstroms
    else:
        # Maintain same relative camera position to backbone.
        tc = last_pos.inverse() * cp

    # Smooth interpolation
    np = p*tc
    if motion_frames > 1:
        def interpolate_camera(session, f, cp=cp, np=np, center=np.inverse()*xyz[1], frames=motion_frames):
            c = session.main_view.camera
            p = np if f+1 == frames else cp.interpolate(np, center, frac = (f+1)/frames)
            c.position = p
        from chimerax.core.commands import motion
        motion.CallForNFrames(interpolate_camera, motion_frames, session)
    else:
        c.position = np

    from numpy import concatenate
    zone_points = concatenate([r.atoms.scene_coords for r in residues])
    from chimerax.surface import zone
    for s in map.surfaces:
        zone.surface_zone(s, zone_points, range, auto_update = True)

    for r in residues:
        r.atoms.displays = True
    
    return p
Пример #3
0
 def __init__(self, session, label, color, bg_color, size, xpos, ypos,
              visibility, margin, outline_width, frames):
     self.label = label
     from numpy import array_equal
     # even if color/background not changing, need color1/2 and bg1/2 for visibility changes
     from numpy import array, uint8
     self.orig_color1 = None if label.color is None else label.color.copy()
     self.color1, self.color2 = array(
         label.drawing.label_color,
         dtype=uint8), (color.uint8x4() if color else color)
     self.bg1, self.bg2 = (None if label.background is None else
                           label.background.copy()), bg_color
     if color is None:
         # no change
         self.interp_color = False
     else:
         color2 = None if color == 'none' else color.uint8x4()
         if array_equal(label.color, color2):
             self.interp_color = False
         else:
             self.interp_color = True
     if bg_color is None:
         # no change
         self.interp_background = False
     else:
         bg2 = None if bg_color == 'none' else bg_color.uint8x4()
         if array_equal(label.background, bg2):
             self.interp_background = False
         elif label.background is None or bg2 is None:
             # abrupt transition if adding/losing background
             label.background = bg2
             self.interp_background = False
         else:
             self.bg1 = label.background
             self.bg2 = bg2
             self.interp_background = True
     self.size1, self.size2 = label.size, size
     self.xpos1, self.xpos2 = label.xpos, xpos
     self.ypos1, self.ypos2 = label.ypos, ypos
     self.visibility1, self.visibility2 = label.visibility, visibility
     if visibility is not None and self.visibility1 != self.visibility2:
         if self.label.color is None:
             # need to interpolate alpha, so set it to a real color;
             # the last frame will set it to the right final value
             self.label.color = array(self.label.drawing.label_color,
                                      dtype=uint8)
     self.margin1, self.margin2 = label.margin, margin
     self.outline_width1, self.outline_width2 = label.outline_width, outline_width
     self.frames = frames
     from chimerax.core.commands import motion
     motion.CallForNFrames(self.frame_cb, frames, session)
Пример #4
0
def cmd_bondrot_change(session, ident, angle, frames=None):
    """Wrapper called by command line."""
    if frames is not None:

        def bondrot_step(session, frame):
            cmd_bondrot_change(session, ident=ident, angle=angle, frames=None)

        from chimerax.core.commands import motion
        motion.CallForNFrames(bondrot_step, frames, session)
        return
    from .manager import BondRotationError
    mgr = session.bond_rotations
    try:
        br = mgr.rotation_for_ident(ident)
    except BondRotationError as e:
        raise UserError(str(e))
    br.angle += angle
Пример #5
0
def zoom(session, factor=None, frames=None, pixel_size=None):
    '''
    Move the camera toward or away from the center of rotation
    to make the objects appear bigger by a specified factor.

    Parameters
    ----------
    factor : float
       Factor by which to change apparent object size.
    frames : integer
       Perform the specified zoom over N frames.
    pixel_size : float or None
       Zoom so that the pixel size in physical units (Angstroms) is this value.
       For perspective camera modes the pixel size is set at the center of rotation depth.
       If factor is also given then it multiplies pixel size.
    '''
    v = session.main_view
    cofr = v.center_of_rotation
    if pixel_size is not None:
        f = v.pixel_size(cofr) / pixel_size
        factor = f if factor is None else f * factor
    elif factor is None:
        msg = 'Pixel size at center of rotation is %.3g' % v.pixel_size(cofr)
        log = session.logger
        log.status(msg)
        log.info(msg)
        return
    c = v.camera
    if frames is None or frames <= 0:
        zoom_camera(c, cofr, factor)
    else:
        import math
        ff = math.pow(factor, 1 / frames)

        def zoom_cb(session, frame, c=c, p=cofr, f=ff):
            zoom_camera(c, p, f)

        from chimerax.core.commands import motion
        motion.CallForNFrames(zoom_cb, frames, session)
Пример #6
0
    def play(self):
        def next_time(session, time, s=self):
            s.set_time(time)

        from chimerax.core.commands import motion
        motion.CallForNFrames(next_time, self.num_times, self.session)
Пример #7
0
    def _new_camera_position(self, residue, block_spotlight=True):
        session = self.session
        r = residue
        from chimerax.atomic import Residue, Atoms
        pt = residue.polymer_type
        if pt == Residue.PT_NONE:
            # No preferred orientation
            ref_coords = None
            target_coords = r.atoms.coords
            centroid = target_coords.mean(axis=0)
        elif pt == Residue.PT_AMINO:
            ref_coords = self.peptide_ref_coords
            try:
                target_coords = Atoms(
                    [r.find_atom(name) for name in ('N', 'CA', 'C')]).coords
                centroid = target_coords[1]
            except ValueError:
                # Either a key atom is missing, or this is a special residue
                # e.g. NH2
                ref_coords = None
                target_coords = r.atoms.coords
                centroid = target_coords.mean(axis=0)
        elif pt == Residue.PT_NUCLEIC:
            ref_coords = self.nucleic_ref_coords
            try:
                target_coords = Atoms([
                    r.find_atom(name) for name in ("C2'", "C1'", "O4'")
                ]).coords
                centroid = target_coords[1]
            except ValueError:
                ref_coords = None
                target_coords = r.atoms.coords
                centroid = target_coords.mean(axis=0)

        c = session.main_view.camera
        cp = c.position
        old_cofr = session.main_view.center_of_rotation

        if ref_coords is not None:
            from chimerax.geometry import align_points, Place
            p, rms = align_points(ref_coords, target_coords)
        else:
            from chimerax.geometry import Place
            p = Place(origin=centroid)

        tc = self._camera_ref_pos(self.view_distance)
        np = p * tc
        new_cofr = centroid
        if c.name == 'orthographic':
            fw = c.field_width
        new_fw = self._view_distance * 2

        def interpolate_camera(session,
                               f,
                               cp=cp,
                               np=np,
                               oc=old_cofr,
                               nc=new_cofr,
                               fw=fw,
                               nfw=new_fw,
                               vr=self._view_distance,
                               center=np.inverse() * centroid,
                               frames=self._interpolate_frames):
            frac = (f + 1) / frames
            v = session.main_view
            c = v.camera
            p = np if f + 1 == frames else cp.interpolate(
                np, center, frac=frac)
            cofr = oc + frac * (nc - oc)
            c.position = p
            vd = c.view_direction()
            cp = v.clip_planes
            ncm, fcm = _get_clip_distances(session)
            cp.set_clip_position('near', cofr - ncm * vr * vd, v)
            cp.set_clip_position('far', cofr + fcm * vr * vd, v)
            if c.name == 'orthographic':
                c.field_width = fw + frac * (nfw - fw)

        from chimerax.geometry import distance
        if distance(new_cofr, old_cofr) < self._view_distance:
            if block_spotlight:
                self._block_clipper_spotlights()
                from .delayed_reaction import call_after_n_events
                call_after_n_events(self.session.triggers, 'frame drawn',
                                    self._interpolate_frames,
                                    self._release_clipper_spotlights, [])
            from chimerax.core.commands import motion
            motion.CallForNFrames(interpolate_camera, self._interpolate_frames,
                                  session)
        else:
            interpolate_camera(session, 0, frames=1)