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)
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
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)
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
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)
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)
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)