def XTCread(filename, frame=None, topoloc=None): """ Reads XTC file Parameters ---------- filename : str Path of xtc file. frame : list A list of integer frames which we want to read from the file. If None will read all. Returns ------- coords : nd.array box : nd.array boxangles : nd.array step : nd.array time : nd.array """ givenframes = frame class __xtc(ct.Structure): _fields_ = [("box", (ct.c_float * 3)), ("natoms", ct.c_int), ("step", ct.c_ulong), ("time", ct.c_double), ("pos", ct.POINTER(ct.c_float))] lib = xtc_lib() nframes = pack_ulong_buffer([0]) natoms = pack_int_buffer([0]) deltastep = pack_int_buffer([0]) deltat = pack_double_buffer([0]) lib['libxtc'].xtc_read.restype = ct.POINTER(__xtc) lib['libxtc'].xtc_read_frame.restype = ct.POINTER(__xtc) coords = None if givenframes is None: # Read the whole XTC file at once retval = lib['libxtc'].xtc_read( ct.c_char_p(filename.encode("ascii")), natoms, nframes, deltat, deltastep) if not retval: raise IOError('XTC file {} possibly corrupt.'.format(filename)) nframes = nframes[0] frames = range(nframes) coords = np.zeros((natoms[0], 3, nframes), dtype=np.float32) else: if not isinstance(givenframes, list) and not isinstance(givenframes, np.ndarray): givenframes = [givenframes] nframes = len(givenframes) frames = givenframes step = np.zeros(nframes, dtype=np.uint64) time = np.zeros(nframes, dtype=np.float32) box = np.zeros((3, nframes), dtype=np.float32) boxangles = np.zeros((3, nframes), dtype=np.float32) for i, f in enumerate(frames): if givenframes is not None: # If frames were given, read specific frame retval = lib['libxtc'].xtc_read_frame( ct.c_char_p(filename.encode("ascii")), natoms, ct.c_int(f)) if not retval: raise IOError('XTC file {} possibly corrupt.'.format(filename)) if coords is None: coords = np.zeros((natoms[0], 3, nframes), dtype=np.float32) fidx = 0 else: fidx = f step[i] = retval[fidx].step time[i] = retval[fidx].time box[:, i] = retval[fidx].box coords[:, :, i] = np.ctypeslib.as_array(retval[fidx].pos, shape=(natoms[0], 3)) if givenframes is not None: lib['libc'].free(retval[0].pos) lib['libc'].free(retval) if givenframes is None: for f in range(len(frames)): lib['libc'].free(retval[f].pos) lib['libc'].free(retval) if np.size(coords, 2) == 0: raise NameError('Malformed XTC file. No frames read from: {}'.format(filename)) if np.size(coords, 0) == 0: raise NameError('Malformed XTC file. No atoms read from: {}'.format(filename)) coords *= 10. # Convert from nm to Angstrom box *= 10. # Convert from nm to Angstrom nframes = coords.shape[2] if len(step) != nframes or np.sum(step) == 0: step = np.arange(nframes) if len(time) != nframes or np.sum(time) == 0: logger.warning('No time information read from {}. Defaulting to 0.1ns framestep.'.format(filename)) time = np.arange(nframes) * 1E5 # Default is 0.1ns in femtoseconds = 100.000 fs return None, Trajectory(coords=coords, box=box, boxangles=boxangles, step=step, time=time)
def vmdselection(selection, coordinates, atomname, atomtype, resname, resid, chain=None, segname=None, insert=None, altloc=None, beta=None, occupancy=None, bonds=None): import platform libdir = htmd.home(libDir=True) if coordinates.ndim == 2: coordinates = np.atleast_3d(coordinates) if coordinates.shape[1] != 3: print(coordinates.shape) raise NameError("Coordinates needs to be natoms x 3 x nframes") if coordinates.dtype != np.float32: raise ValueError("Coordinates is not float32") if (coordinates.strides[0] != 12 or coordinates.strides[1] != 4): # It's a view -- need to make a copy to ensure contiguity of memory coordinates = np.array(coordinates, dtype=np.float32) if (coordinates.strides[0] != 12 or coordinates.strides[1] != 4): raise ValueError("Coordinates is a view with unsupported strides") natoms = coordinates.shape[0] nframes = coordinates.shape[2] # Sanity check the inputs # print(natoms) # print (len(atomname)) if bonds is not None and bonds.shape[1] != 2: raise NameError("'bonds' not nbonds x 2 in length") if len(atomname) != natoms: # print(natoms) # print(len(atomname)) raise NameError("'atomname' not natoms in length") if len(atomtype) != natoms: raise NameError("'atomtype' not natoms in length") if len(resname) != natoms: raise NameError("'resname' not natoms in length") if len(resid) != natoms: raise NameError("'resid' not natoms in length") if chain is not None and len(chain) != natoms: raise NameError("'chain' not natoms in length") if segname is not None and len(segname) != natoms: raise NameError("'segname' not natoms in length") if insert is not None and len(insert) != natoms: raise NameError("'insert' not natoms in length") if altloc is not None and len(altloc) != natoms: raise NameError("'altloc' not natoms in length") if beta is not None and len(beta) != natoms: raise NameError("'beta' not natoms in length") if occupancy is not None and len(occupancy) != natoms: raise NameError("'occupancy' not natoms in length") if platform.system() == "Windows": ct.cdll.LoadLibrary(os.path.join(libdir, "libgcc_s_seh-1.dll")) if (os.path.exists(os.path.join(libdir, "psprolib.dll"))): ct.cdll.LoadLibrary(os.path.join(libdir, "psprolib.dll")) parser = ct.cdll.LoadLibrary(os.path.join(libdir, "libvmdparser.so")) c_selection = ct.create_string_buffer(selection.encode('ascii'), len(selection) + 1) c_natoms = ct.c_int(natoms) c_nframes = ct.c_int(nframes) c_atomname = pack_string_buffer(atomname) c_atomtype = pack_string_buffer(atomtype) c_resname = pack_string_buffer(resname) c_resid = pack_int_buffer(resid) c_chain = None c_segname = None c_insert = None c_altloc = None c_beta = None c_occupancy = None c_coords = None c_nbonds = None c_bonds = None if chain is not None: c_chain = pack_string_buffer(chain) if segname is not None: c_segname = pack_string_buffer(segname) if insert is not None: c_insert = pack_string_buffer(insert) if altloc is not None: c_altloc = pack_string_buffer(altloc) if beta is not None: c_beta = pack_double_buffer(beta) if occupancy is not None: c_occupancy = pack_double_buffer(occupancy) c_bonds = None nbonds = 0 if bonds is not None: # TODO: Replace the loops for bonds with ravel nbonds = bonds.shape[0] if nbonds > 0: ll = nbonds * 2 c_bonds = (ct.c_int * ll)() for z in range(0, nbonds): for y in [0, 1]: c_bonds[z * 2 + y] = bonds[z, y] c_nbonds = ct.c_int(nbonds) ll = natoms * nframes c_output_buffer = (ct.c_int * ll)() lenv = natoms * 3 * nframes c_coords = coordinates.ctypes.data_as(ct.POINTER(ct.c_float)) retval = parser.atomselect(c_selection, c_natoms, c_beta, c_occupancy, c_atomtype, c_atomname, c_resname, c_resid, c_chain, c_segname, c_insert, c_altloc, c_coords, c_nframes, c_nbonds, c_bonds, c_output_buffer) if retval != 0: raise NameError('Could not parse selection "' + selection + '". Is the selection a valid VMD atom selection?') retval = np.empty((natoms, nframes), dtype=np.bool_) for frame in range(nframes): for atom in range(natoms): retval[atom, frame] = c_output_buffer[frame * natoms + atom] return np.squeeze(retval)
def vmdselection(selection, coordinates, atomname, atomtype, resname, resid, chain=None, segname=None, insert=None, altloc=None, beta=None, occupancy=None, bonds=None): if coordinates.ndim == 2: coordinates = np.atleast_3d(coordinates) if coordinates.shape[1] != 3: print(coordinates.shape) raise NameError("Coordinates needs to be natoms x 3 x nframes") if coordinates.dtype != np.float32: raise ValueError("Coordinates is not float32") if(coordinates.strides[0] != 12 or coordinates.strides[1] != 4 ): # It's a view -- need to make a copy to ensure contiguity of memory coordinates = np.array( coordinates, dtype=np.float32 ) if(coordinates.strides[0] != 12 or coordinates.strides[1] != 4 ): raise ValueError("Coordinates is a view with unsupported strides" ) natoms = coordinates.shape[0] nframes = coordinates.shape[2] # Sanity check the inputs # print(natoms) # print (len(atomname)) if bonds is not None and bonds.shape[1] != 2: raise NameError("'bonds' not nbonds x 2 in length") if len(atomname) != natoms: # print(natoms) # print(len(atomname)) raise NameError("'atomname' not natoms in length") if len(atomtype) != natoms: raise NameError("'atomtype' not natoms in length") if len(resname) != natoms: raise NameError("'resname' not natoms in length") if len(resid) != natoms: raise NameError("'resid' not natoms in length") if chain is not None and len(chain) != natoms: raise NameError("'chain' not natoms in length") if segname is not None and len(segname) != natoms: raise NameError("'segname' not natoms in length") if insert is not None and len(insert) != natoms: raise NameError("'insert' not natoms in length") if altloc is not None and len(altloc) != natoms: raise NameError("'altloc' not natoms in length") if beta is not None and len(beta) != natoms: raise NameError("'beta' not natoms in length") if occupancy is not None and len(occupancy) != natoms: raise NameError("'occupancy' not natoms in length") c_selection = ct.create_string_buffer(selection.encode('ascii'), len(selection) + 1) c_natoms = ct.c_int(natoms) c_nframes = ct.c_int(nframes) c_atomname = pack_string_buffer(atomname) c_atomtype = pack_string_buffer(atomtype) c_resname = pack_string_buffer(resname) c_resid = pack_int_buffer(resid) c_chain = None c_segname = None c_insert = None c_altloc = None c_beta = None c_occupancy = None c_coords = None c_nbonds = None c_bonds = None if chain is not None: c_chain = pack_string_buffer(chain) if segname is not None: c_segname = pack_string_buffer(segname) if insert is not None: c_insert = pack_string_buffer(insert) if altloc is not None: c_altloc = pack_string_buffer(altloc) if beta is not None: c_beta = pack_double_buffer(beta) if occupancy is not None: c_occupancy = pack_double_buffer(occupancy) c_bonds = None nbonds = 0 if bonds is not None: # TODO: Replace the loops for bonds with ravel nbonds = bonds.shape[0] if nbonds > 0: ll = nbonds * 2 c_bonds = (ct.c_int * ll)() for z in range(0, nbonds): for y in [0, 1]: c_bonds[z * 2 + y] = bonds[z, y] c_nbonds = ct.c_int(nbonds) ll = natoms * nframes c_output_buffer = (ct.c_int * ll)() lenv = natoms * 3 * nframes c_coords = coordinates.ctypes.data_as(ct.POINTER(ct.c_float)) retval = parser.atomselect( c_selection, c_natoms, c_beta, c_occupancy, c_atomtype, c_atomname, c_resname, c_resid, c_chain, c_segname, c_insert, c_altloc, c_coords, c_nframes, c_nbonds, c_bonds, c_output_buffer) if retval != 0: raise NameError('Could not parse selection "' + selection + '". Is the selection a valid VMD atom selection?') retval = np.empty((natoms, nframes), dtype=np.bool_) for frame in range(nframes): for atom in range(natoms): retval[atom, frame] = c_output_buffer[frame * natoms + atom] return np.squeeze(retval)
def vmdselection(selection, coordinates, atomname, atomtype, resname, resid, chain=None, segname=None, insert=None, altloc=None, beta=None, occupancy=None, bonds=None): maxseglen = np.max([len(x) for x in segname]) if maxseglen > 4: logger.warning( 'More than 4 characters were used for segids. ' 'Due to limitations in VMD atomselect segids will be ignored for the atomselection.' ) segname = segname.copy() segname[:] = '' if coordinates.ndim == 2: coordinates = np.atleast_3d(coordinates) if coordinates.shape[1] != 3: print(coordinates.shape) raise NameError("Coordinates needs to be natoms x 3 x nframes") if coordinates.dtype != np.float32: raise ValueError("Coordinates is not float32") if (coordinates.strides[0] != 12 or coordinates.strides[1] != 4): # It's a view -- need to make a copy to ensure contiguity of memory coordinates = np.array(coordinates, dtype=np.float32) if (coordinates.strides[0] != 12 or coordinates.strides[1] != 4): raise ValueError("Coordinates is a view with unsupported strides") natoms = coordinates.shape[0] nframes = coordinates.shape[2] # Sanity check the inputs # print(natoms) # print (len(atomname)) if bonds is not None and bonds.shape[1] != 2: raise NameError("'bonds' not nbonds x 2 in length") if len(atomname) != natoms: # print(natoms) # print(len(atomname)) raise NameError("'atomname' not natoms in length") if len(atomtype) != natoms: raise NameError("'atomtype' not natoms in length") if len(resname) != natoms: raise NameError("'resname' not natoms in length") if len(resid) != natoms: raise NameError("'resid' not natoms in length") if chain is not None and len(chain) != natoms: raise NameError("'chain' not natoms in length") if segname is not None and len(segname) != natoms: raise NameError("'segname' not natoms in length") if insert is not None and len(insert) != natoms: raise NameError("'insert' not natoms in length") if altloc is not None and len(altloc) != natoms: raise NameError("'altloc' not natoms in length") if beta is not None and len(beta) != natoms: raise NameError("'beta' not natoms in length") if occupancy is not None and len(occupancy) != natoms: raise NameError("'occupancy' not natoms in length") c_selection = ct.create_string_buffer(selection.encode('ascii'), len(selection) + 1) c_natoms = ct.c_int(natoms) c_nframes = ct.c_int(nframes) c_atomname = pack_string_buffer(atomname) c_atomtype = pack_string_buffer(atomtype) c_resname = pack_string_buffer(resname) c_resid = pack_int_buffer(resid) c_chain = None c_segname = None c_insert = None c_altloc = None c_beta = None c_occupancy = None c_coords = None c_nbonds = None c_bonds = None if chain is not None: c_chain = pack_string_buffer(chain) if segname is not None: c_segname = pack_string_buffer(segname) if insert is not None: c_insert = pack_string_buffer(insert) if altloc is not None: c_altloc = pack_string_buffer(altloc) if beta is not None: c_beta = pack_double_buffer(beta) if occupancy is not None: c_occupancy = pack_double_buffer(occupancy) c_bonds = None nbonds = 0 if bonds is not None: # TODO: Replace the loops for bonds with ravel nbonds = bonds.shape[0] if nbonds > 0: ll = nbonds * 2 c_bonds = (ct.c_int * ll)() for z in range(0, nbonds): for y in [0, 1]: c_bonds[z * 2 + y] = bonds[z, y] c_nbonds = ct.c_int(nbonds) ll = natoms * nframes c_output_buffer = (ct.c_int * ll)() lenv = natoms * 3 * nframes c_coords = coordinates.ctypes.data_as(ct.POINTER(ct.c_float)) retval = parser.atomselect(c_selection, c_natoms, c_beta, c_occupancy, c_atomtype, c_atomname, c_resname, c_resid, c_chain, c_segname, c_insert, c_altloc, c_coords, c_nframes, c_nbonds, c_bonds, c_output_buffer) if retval != 0: raise NameError('Could not parse selection "' + selection + '". Is the selection a valid VMD atom selection?') retval = np.empty((natoms, nframes), dtype=np.bool_) for frame in range(nframes): for atom in range(natoms): retval[atom, frame] = c_output_buffer[frame * natoms + atom] return np.squeeze(retval)
def XTCread(filename, frames=None): class __xtc(ct.Structure): _fields_ = [("box", (ct.c_float * 3)), ("natoms", ct.c_int), ("step", ct.c_ulong), ("time", ct.c_double), ("pos", ct.POINTER(ct.c_float))] lib = xtc_lib() nframes = pack_ulong_buffer([0]) natoms = pack_int_buffer([0]) deltastep = pack_int_buffer([0]) deltat = pack_double_buffer([0]) lib['libxtc'].xtc_read.restype = ct.POINTER(__xtc) lib['libxtc'].xtc_read_frame.restype = ct.POINTER(__xtc) if frames is None: retval = lib['libxtc'].xtc_read(ct.c_char_p(filename.encode("ascii")), natoms, nframes, deltat, deltastep) if not retval: raise IOError('XTC file {} possibly corrupt.'.format(filename)) frames = range(nframes[0]) t = Trajectory() t.natoms = natoms[0] t.nframes = len(frames) t.coords = np.zeros((natoms[0], 3, t.nframes), dtype=np.float32) t.step = np.zeros(t.nframes, dtype=np.uint64) t.time = np.zeros(t.nframes, dtype=np.float32) t.box = np.zeros((3, t.nframes), dtype=np.float32) for i, f in enumerate(frames): if f >= nframes[0] or f < 0: raise RuntimeError( 'Frame index out of range in XTCread with given frames') t.step[i] = retval[f].step t.time[i] = retval[f].time t.box[0, i] = retval[f].box[0] t.box[1, i] = retval[f].box[1] t.box[2, i] = retval[f].box[2] # print( t.coords[:,:,f].shape) # print ( t.box[:,f] ) # t.step[i] = deltastep[0] * i t.coords[:, :, i] = np.ctypeslib.as_array(retval[f].pos, shape=(natoms[0], 3)) for f in range(len(frames)): lib['libc'].free(retval[f].pos) lib['libc'].free(retval) else: if not isinstance(frames, list) and not isinstance(frames, np.ndarray): frames = [frames] t = Trajectory() t.natoms = 0 t.nframes = len(frames) t.coords = None t.step = None t.time = None t.box = None nframes = len(frames) i = 0 for f in frames: retval = lib['libxtc'].xtc_read_frame( ct.c_char_p(filename.encode("ascii")), natoms, ct.c_int(f)) if t.coords is None: t.natoms = natoms[0] t.coords = np.zeros((natoms[0], 3, nframes), dtype=np.float32) t.step = np.zeros(nframes, dtype=np.uint64) t.time = np.zeros(nframes, dtype=np.float32) t.box = np.zeros((3, nframes), dtype=np.float32) t.step[i] = retval[0].step t.time[i] = retval[0].time t.box[0, i] = retval[0].box[0] t.box[1, i] = retval[0].box[1] t.box[2, i] = retval[0].box[2] t.coords[:, :, i] = np.ctypeslib.as_array(retval[0].pos, shape=(natoms[0], 3)) i += 1 lib['libc'].free(retval[0].pos) lib['libc'].free(retval) if np.size(t.coords, 2) == 0: raise NameError( 'Malformed XTC file. No frames read from: {}'.format(filename)) if np.size(t.coords, 0) == 0: raise NameError( 'Malformed XTC file. No atoms read from: {}'.format(filename)) # print( t.step ) # print( t.time ) # print( t.coords[:,:,0] ) # print(t.coords.shape) t.coords *= 10. # Convert from nm to Angstrom t.box *= 10. # Convert from nm to Angstrom return t