Example #1
0
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)
Example #2
0
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)
Example #3
0
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)
Example #4
0
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)
Example #5
0
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
Example #6
0
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)