def from_dict(cls, dct): error_if_no_mdtraj("MDTrajTopology") top_dict = dct['mdtraj'] atoms = pd.DataFrame( top_dict['atoms'], columns=top_dict['atom_columns']) bonds = np.array(top_dict['bonds']) try: md_topology = md.Topology.from_dataframe(atoms, bonds) return cls(md_topology) except Exception: # we try a fix and add multiples of 10000 to the resSeq logger.info('Normal reconstruction of topology failed. ' 'Trying a fix to the 10k residue ID problem.') for ci in np.unique(atoms['chainID']): chain_atoms = atoms[atoms['chainID'] == ci] indices = chain_atoms.index.tolist() old_residue_id = 0 multiplier = 0 places = [] for row, res_id in zip(indices, list(chain_atoms['resSeq'])): if res_id < old_residue_id: if multiplier > 0: atoms.loc[places, 'resSeq'] += 10000 * multiplier places = [] multiplier += 1 if multiplier > 0: places.append(row) old_residue_id = res_id if multiplier > 0: atoms.loc[places, 'resSeq'] += 10000 * multiplier # this function is really slow! Reads ~ 1000 atoms per second md_topology = md.Topology.from_dataframe(atoms, bonds) # that we have successfully created the topology using from_df # we remove the wrong multipliers # this is weird, but reproduces the current behaviour for atom in md_topology.atoms: atom.residue.resSeq %= 10000 return cls(md_topology)
def to_mdtraj(self, topology=None): """ Construct a mdtraj.Trajectory object from the Trajectory itself Parameters ---------- topology : :class:`mdtraj.Topology` If not None this topology will be used to construct the mdtraj objects otherwise the topology object will be taken from the configurations in the trajectory snapshots. Returns ------- :class:`mdtraj.Trajectory` the trajectory Notes ----- If the OPS trajectory is zero-length (has no snapshots), then this fails. OPS cannot currently convert zero-length trajectories to MDTraj, because an OPS zero-length trajectory cannot determine its MDTraj topology. """ error_if_no_mdtraj("Converting to mdtraj") try: snap = self[0] except IndexError: raise ValueError("Cannot convert zero-length trajectory " + "to MDTraj") if topology is None: # TODO: maybe add better error output? # if AttributeError here, engine doesn't support mdtraj topology = snap.engine.mdtraj_topology output = self.xyz traj = md.Trajectory(output, topology) box_vectors = self.box_vectors # box_vectors is a list with an entry for each frame of the traj # if they're all None, we return None, not [None, None, ..., None] if not np.any(box_vectors): box_vectors = None traj.unitcell_vectors = box_vectors return traj
def empty_snapshot_from_openmm_topology(topology, simple_topology=False): """ Return an empty snapshot from an openmm.Topology object Velocities will be set to zero. Parameters ---------- topology : openmm.Topology the topology representing the structure and number of atoms simple_topology : bool if `True` only a simple topology with n_atoms will be created. This cannot be used with complex CVs but loads and stores very fast Returns ------- openpathsampling.engines.Snapshot the complete snapshot with zero coordinates and velocities """ error_if_no_simtk_unit("empty_snapshot_from_openmm_topology") u_nm = unit.nanometers u_ps = unit.picoseconds n_atoms = topology.n_atoms if simple_topology: topology = Topology(n_atoms, 3) else: error_if_no_mdtraj("empty_snaphsot_from_openmm_topology") topology = MDTrajTopology(md.Topology.from_openmm(topology)) snapshot = Snapshot.construct( coordinates=unit.Quantity(np.zeros((n_atoms, 3)), u_nm), box_vectors=unit.Quantity(topology.setUnitCellDimensions(), u_nm), velocities=unit.Quantity(np.zeros((n_atoms, 3)), u_nm / u_ps), engine=TopologyEngine(topology) ) return snapshot
def ops_load_trajectory(filename, **kwargs): error_if_no_mdtraj("ops_load_trajectory") return trajectory_from_mdtraj(md.load(filename, **kwargs))