
     iO                         d Z ddlZddlZddlZddlZddlZddlZddlm	Z
 ddlmZmZ ddlmZ ddlmZ dd	lmZ  G d
 dej                  Z G d dej                  ZdS )a  DCD trajectory I/O  --- :mod:`MDAnalysis.coordinates.DCD`
============================================================

Classes to read and write DCD binary trajectories, the format used by
CHARMM, NAMD, and also LAMMPS. Trajectories can be read regardless of
system-endianness as this is auto-detected.

Generally, DCD trajectories produced by any code can be read (with the
:class:`DCDReader`) although there can be issues with the unitcell (simulation
box) representation (see :attr:`DCDReader.dimensions`). DCDs can also be
written but the :class:`DCDWriter` follows recent NAMD/VMD convention for the
unitcell while still writing AKMA time. Reading and writing these trajectories
within MDAnalysis will work seamlessly but if you process those trajectories
with other tools you might need to watch out that time and unitcell dimensions
are correctly interpreted.


See Also
--------
:mod:`MDAnalysis.coordinates.LAMMPS`
  module provides a more flexible DCD reader/writer.


.. _Issue 187:
   https://github.com/MDAnalysis/mdanalysis/issues/187


Classes
-------

.. autoclass:: DCDReader
   :inherited-members:
.. autoclass:: DCDWriter
   :inherited-members:

    N   )units   )basecore)DCDFile)triclinic_box)store_init_argumentsc                        e Zd ZdZdZdZdddZed fd		            Ze	d
             Z
d Zed             Zd Zd ZddZddZd Zed             Zed             Z	 	 	 	 	 	 ddZ xZS )	DCDReaderu  Reader for the DCD format.

    DCD is used by NAMD, CHARMM and LAMMPS as the default trajectory format.
    The DCD file format is not well defined. In particular, NAMD and CHARMM use
    it differently. Currently, MDAnalysis tries to guess the correct **format
    for the unitcell representation** but it can be wrong. **Check the unitcell
    dimensions**, especially for triclinic unitcells (see `Issue 187`_). DCD
    trajectories produced by CHARMM and NAMD( >2.5) record time in AKMA units.
    If other units have been recorded (e.g., ps) then employ the configurable
    :class:`MDAnalysis.coordinates.LAMMPS.DCDReader` and set the time unit as a
    optional argument. You can find a list of units used in the DCD formats on
    the MDAnalysis `wiki`_.

    MDAnalysis always uses (*A*, *B*, *C*, α, β, γ) to represent the unit
    cell. Lengths *A*, *B*, *C* are in the MDAnalysis length unit (Å), and
    angles α, β, γ are in degrees.

    The ordering of the angles in the unitcell is the same as in recent
    versions of VMD's DCDplugin_ (2013), namely the `X-PLOR DCD format`_: The
    original unitcell is read as ``[A, gamma, B, beta, alpha, C]`` from the DCD
    file. If any of these values are < 0 or if any of the angles are > 180º
    then it is assumed it is a new-style CHARMM unitcell (possibly ≥22, at
    least since c36b2) in which symmetric box vectors were recorded. If all
    angles are numbers between -1 and +1, then they are treated as cosines of
    the angle (following the modern NAMD > 2.5/VMD convention).

    Ultimately, all unitcell representations are converted to the MDAnalysis
    standard unit cell representation in :attr:`DCDReader.dimensions`.


    .. deprecated:: 2.4.0
        DCDReader currently makes independent timesteps
        by copying the :class:`Timestep` associated with the reader.
        Other readers update the :class:`Timestep` inplace meaning all
        references to the :class:`Timestep` contain the same data. The unique
        independent :class:`Timestep` behaviour of the DCDReader is deprecated
        will be changed in 3.0 to be the same as other readers

    .. warning::
        The DCD format is not well defined. Check your unit cell
        dimensions carefully, especially when using triclinic boxes.
        Different software packages implement different conventions and
        MDAnalysis is currently implementing the newer NAMD/VMD convention
        and tries to guess the new CHARMM one. Old CHARMM trajectories might
        give wrong unitcell values. For more details see `Issue 187`_.

    .. _`X-PLOR DCD format`: http://www.ks.uiuc.edu/Research/vmd/plugins/molfile/dcdplugin.html
    .. _Issue 187: https://github.com/MDAnalysis/mdanalysis/issues/187
    .. _DCDplugin: http://www.ks.uiuc.edu/Research/vmd/plugins/doxygen/dcdplugin_8c-source.html#l00947
    .. _wiki: https://github.com/MDAnalysis/mdanalysis/wiki/FileFormats#dcd

    DCDCHARMMAKMAAngstromtimelengthTNc                     t          t          |           j        |fd|i| t          | j                  | _        | j        j        d         | _        t          j	        | j        j        d         | j
        d         d          }||| j        j        d         z  }| j        j        d         | _        || j        d<    | j        | j        fi | j        | _        | j                                        }| j        j        d	k    r| j                            d	           n| j                            d
           d
| _        |                     || j                  | _        || j        _        t+          j        dt.                     dS )a  
        Parameters
        ----------
        filename : str
            trajectory filename
        convert_units : bool (optional)
            convert units to MDAnalysis units
        dt : float (optional)
            overwrite time delta stored in DCD
        **kwargs : dict
            General reader arguments.


        .. versionchanged:: 0.17.0
           Changed to use libdcd.pyx library and removed the correl function
        convert_unitsnatomsdeltar   psNnsavcdtr   r   a,  DCDReader currently makes independent timesteps by copying self.ts while other readers update self.ts inplace. This behavior will be changed in 3.0 to be the same as other readers. Read more at https://github.com/MDAnalysis/mdanalysis/issues/3889 to learn if this change in behavior might affect you.category)superr   __init__r   filename_fileheadern_atomsmdaunitsconvertr   skip_timestep
_ts_kwargs	_Timesteptsreadn_framesseek_frame_frame_to_tsr   warningswarnDeprecationWarning)selfr   r   r   kwargsr   frame	__class__s          d/srv/www/vhosts/g4struct/public_html/venv/lib/python3.11/site-packages/MDAnalysis/coordinates/DCD.pyr   zDCDReader.__init__   s   $ 	(i'	= 	=$1	=5;	= 	= 	=T]++
z(2 !27!;!%F!3T; ;:*733B!Z.w7 " $.AAAA
!!:""JOOAJOOA##E4733
 O !3	4 	4 	4 	4 	4 	4    c                 n    t          |           5 }|j        d         }d d d            n# 1 swxY w Y   |S )Nr   )r   r!   )r   r2   fr"   s       r5   parse_n_atomszDCDReader.parse_n_atoms   ss    X 	)!hx(G	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)s   *..c                 8    | j                                          dS )zclose readerNr    closer1   s    r5   r<   zDCDReader.close       
r6   c                 *    t          | j                  S )znumber of frames in trajectory)lenr    r=   s    r5   r*   zDCDReader.n_frames   s     4:r6   c                     d| j         _        d| _        | j                                         | j                            d           dS )zreopen trajectoryr   rN)r(   r3   r,   r    r<   openr=   s    r5   _reopenzDCDReader._reopen   s@    

r6   c                 r    |dz
  | _         | j                            |           |                                 S )zread frame ir   )r,   r    r+   _read_next_timestep)r1   is     r5   _read_framezDCDReader._read_frame   s3    !e
'')))r6   c                    | j         | j        dz
  k    rt          d          || j                                        }| j                                        }| xj         dz  c_         |                     ||           || _        |S )zcopy next frame into timestepr   z"trying to go over trajectory limit)r,   r*   IOErrorr(   copyr    r)   r-   )r1   r(   r3   s      r5   rG   zDCDReader._read_next_timestep   s|    ;$-!+++>???:B
!!q%$$$	r6   c                 T    || j         }t          |f|| j        j        | j        d|S )z#Return writer for trajectory formatN)r"   r   r   )r"   	DCDWriterr(   r   r   )r1   r   r"   r2   s       r5   WriterzDCDReader.Writer   sG    ?lGwz,	 
   	r6   c                 `   | j         |_        |j        | j        j        d         | j        j        d         z  z   | j        j        z  |_        | j                                        |j        d<   g d}t          j
        |j        |          }t          j        dz  }d|d         cxk    rdk    rn nd|d	         cxk    rdk    rn nd|d
         cxk    rdk    rvn nsdt          j        |d                   dz  |z  z
  |d<   dt          j        |d	                   dz  |z  z
  |d	<   dt          j        |d
                   dz  |z  z
  |d
<   nt          j        |dk               s t          j        |dd         dk              rI|j                                        }|g d         |g d         |g d         }	}}t!          |||	          }n	 ||_        |j        |_        | j        rC|j        "|                     |j        dd                    |                     |j                   |S )z*convert a dcd-frame to a :class:`TimeStep`istartr   step)r   r            r   r   g      rU   g      ?rT   rS        V@g        Ng     f@)r   r   rU   )r   r   rT   )rU   rT   rS   )r,   r3   r    r!   r(   r   r   telldatanptakeunitcellpiarcsinanyrL   r	   
dimensionsxyz	positionsr   convert_pos_from_native)
r1   r3   r(   	_ts_orderucpi_2He1e2e3s
             r5   r-   zDCDReader._frame_to_ts   sE   ;8dj/9$*:KG:TTTX\X_Xbb*//++ '&&	WU^Y//uqyBqE    S     tr!u';';';';';';';';';1$$$$$$$$$ 29RU++d2T99BqE29RU++d2T99BqE29RU++d2T99BqEEVBG__ 	r!""v} 5 5 	##%%A999q|Qyyy\BBr2r**BB y 	7}(,,R]2A2->???((666	r6   c                     | j         j        S )zFunitcell dimensions (*A*, *B*, *C*, *alpha*, *beta*, *gamma*)
        )r(   r_   r=   s    r5   r_   zDCDReader.dimensions  s     w!!r6   c                     | j         j        S )ztimestep between frames)r(   r   r=   s    r5   r   zDCDReader.dt  s     wzr6   afcc                    |.t          j        dt                     |rt          d          |}|                     |||          \  }}}|7t          |          dk    rt          d          t          |j                  }n!t          t          | j	                            }| j
                            |||||          }|j        S )a  Return a subset of coordinate data for an AtomGroup

        Parameters
        ----------
        asel : :class:`~MDAnalysis.core.groups.AtomGroup`
            The :class:`~MDAnalysis.core.groups.AtomGroup` to read the
            coordinates from. Defaults to None, in which case the full set of
            coordinate data is returned.
        
            .. deprecated:: 2.7.0
               asel argument will be renamed to atomgroup in 3.0.0

        atomgroup: AtomGroup (optional)
            Same as `asel`, will replace `asel` in 3.0.0
        start : int (optional)
            Begin reading the trajectory at frame index `start` (where 0 is the
            index of the first frame in the trajectory); the default ``None``
            starts at the beginning.
        stop : int (optional)
            End reading the trajectory at frame index `stop`-1, i.e, `stop` is
            excluded. The trajectory is read to the end with the default
            ``None``.
        step : int (optional)
            Step size for reading; the default ``None`` is equivalent to 1 and
            means to read every frame.
        order : str (optional)
            the order/shape of the return data array, corresponding
            to (a)tom, (f)rame, (c)oordinates all six combinations
            of 'a', 'f', 'c' are allowed ie "fac" - return array
            where the shape is (frame, number of atoms,
            coordinates)


        .. versionchanged:: 1.0.0
           `skip` and `format` keywords have been removed.
        .. versionchanged:: 2.4.0
            ValueError now raised instead of NoDataError for empty input
            AtomGroup
        NzKasel argument to timeseries will be renamed to'atomgroup' in 3.0, see #3911r   z-Cannot provide both asel and atomgroup kwargsr   z0Timeseries requires at least one atom to analyze)orderindices)r.   r/   r0   
ValueErrorcheck_slice_indicesr@   listro   ranger"   r    
readframesr`   )	r1   asel	atomgroupstartstoprR   rn   atom_numbersframess	            r5   
timeserieszDCDReader.timeseries  s    \ M0+- - - -  R !PQQQI 44UD$GGtT 9~~"" FH H H	 122LLdl 3 344L&&4UL ' B Bzr6   )TNN)NNNNNrl   )__name__
__module____qualname____doc__formatflavorr   r
   r   staticmethodr9   r<   propertyr*   rE   rI   rG   rO   r-   r_   r   r{   __classcell__)r4   s   @r5   r   r   I   sn       3 3h FFz22E.4 .4 .4 .4 .4 .4`   \
     X  * * *   	 	 	 	) ) )V " " X"
   X
 !C C C C C C C Cr6   r   c                   N    e Zd ZdZdZdZdZdddZ	 	 	 	 	 	 ddZd Z	d Z
d ZdS )rN   u  DCD Writer class

    The writer follows recent NAMD/VMD convention for the unitcell (box lengths
    in Å and angle-cosines, ``[A, cos(gamma), B, cos(beta), cos(alpha), C]``)
    and writes positions in Å and time in AKMA time units.

    .. warning::
    
       Multiple conventions exist for how unit cells are written to DCD
       files. Until 2.10.0 MDAnalysis followed the old X-PLOR/CHARMM/NAMD
       (≤2.5) convention of storing ``[A, gamma, B, beta, alpha, C]`` while
       wrongly stating that the new NAMD/VMD convention would be followed. In
       2.10.0, MDAnalysis switched to following the documented behavior and now
       stores the box with angle cosines, as described above. The MDAnalysis
       :class:`DCDReader` can correctly read either format but *if you have
       code that relies on a specific format for the box information in the raw
       DCD file, please check your results.*

       Furthermore, modern versions of CHARMM store box vectors and not box
       length/angles. When reading MDAnalysis-generated DCD files *in CHARMM*,
       carefully check your results.

    .. note::
        When writing out timesteps without ``dimensions`` (i.e. set ``None``)
        the :class:`DCDWriter` will write out a zeroed unitcell (i.e.
        ``[0, 0, 0, 0, 0, 0]``). As this behaviour is poorly defined, it may
        not match the expectations of other software.

    .. versionchanged:: 2.10.0    
       Up to 2.10.0 the :class:`DCDWriter` wrote a unit cell following old NAMD
       (≤2.5) convention, even though the docs stated that the new NAMD
       convention was being used. Now the modern NAMD > 2.5 format is
       written. See `Issue #5069`_ for details.


    .. _`Issue #5069`: https://github.com/MDAnalysis/mdanalysis/issues/5069

    r   TNAMDr   r   r   r    r   c	                 ^   || _         || _        |t          d          || _        t	          | j         d          | _        || _        || _        t          j	        |d| j
        d                   }t          |          |z  }
||n|}| j                            || j        ||
d|           dS )a  Parameters
        ----------
        filename : str
            filename of trajectory
        n_atoms : int
            number of atoms to be written
        convert_units : bool (optional)
            convert from MDAnalysis units to format specific units
        step : int (optional)
            number of steps between frames to be written
        dt : float (optional)
            time between two frames. If ``None`` guess from first written
            :class:`TimeStep`
        remarks : str (optional)
            remarks to be stored in DCD. Shouldn't be more then 240 characters
        nsavc : int (optional)
            DCD files can also store the number of integrator time steps that
            correspond to the interval between two frames as nsavc (i.e., every
            how many MD steps is a frame saved to the DCD). By default, this
            number is just set to one and this should be sufficient for almost
            all cases but if required, `nsavc` can be changed.
        istart : int (optional)
            starting frame number in integrator timesteps. CHARMM defaults to
            `nsavc`, i.e., start at frame number 1 = `istart` / `nsavc`. The value
            ``None`` will set `istart` to `nsavc` (the CHARMM default).
            The MDAnalysis default is 0 so that the frame number and time of the first
            frame is 0.
        **kwargs : dict
            General writer arguments

        Nzn_atoms argument is requiredwr   r   r   )remarksr   r   r   is_periodicrQ   )r   _convert_unitsrp   r"   r   r    rR   r   r#   r$   r   floatwrite_header)r1   r   r"   r   rR   r   r   r   rQ   r2   r   s              r5   r   zDCDWriter.__init__  s    R !+?;<<<T]C00
	b$
6(:;;b		E!!-5
< 	  	 	 	 	 	r6   c                    	 |j         }n># t          $ r1 	 |j        j         }n # t          $ r d}t          |          dw xY wY nw xY w|j                                        }	 |j                                        }n:# t          $ r- d}t          j        |           t          j
        d          }Y nw xY w| j        r.|                     |d          }|                     |d          }g d}t          j        ||          }t          j        t          j        d|g d	         z
                      |g d	<   | j                            ||
           dS )aD  Write information associated with ``obj`` at current frame into trajectory

        Parameters
        ----------
        ag : AtomGroup or Universe

        See Also
        --------
        :meth:`DCDWriter.write`  takes a more general input


        .. versionchanged:: 1.0.0
           Added ability to pass AtomGroup or Universe.
           Renamed from `write_next_timestep` to `_write_next_frame`.
        .. versionchanged:: 2.0.0
           Deprecated support for Timestep argument has now been removed.
           Use AtomGroup or Universe as an input instead.
        z-Input obj is neither an AtomGroup or UniverseNzDNo dimensions set for current frame, zeroed unitcell will be written   T)inplace)r   rS   r   rT   rU   r   rV   )r   rU   rT   )r`   box)r(   AttributeError
trajectory	TypeErrorra   rL   r_   r.   r/   rY   zerosr   convert_pos_to_nativeconvert_dimensions_to_unitcellrZ   sindeg2radr    write)	r1   agr(   errmsgr`   r_   wmsgrc   r   s	            r5   _write_next_framezDCDWriter._write_next_frame  s   &	2BB 	2 	2 	22]%! 2 2 2H''T12 	2 l!!	%++--JJ 	% 	% 	%&DM$!JJJ		%  	O,,S$,??C<<R<NNJ '&&	gj),, 
4#iii.+@ A ABBIII
Sc*****s3   
 
A"A?AA"A< <4B32B3c                 8    | j                                          dS )zclose trajectoryNr;   r=   s    r5   r<   zDCDWriter.close  r>   r6   c                 .    |                                   d S r|   )r<   r=   s    r5   __del__zDCDWriter.__del__  s    

r6   N)Tr   r   r   r   r   )r}   r~   r   r   r   
multiframer   r   r   r   r<   r    r6   r5   rN   rN   c  s        % %L FJFz22E
  $: : : :x2+ 2+ 2+h      r6   rN   )r   oserrnonumpyrY   structtypesr.   r   r   r#   r   r   lib.formats.libdcdr   lib.mdamathr	   lib.utilr
   
ReaderBaser   
WriterBaserN   r   r6   r5   <module>r      s   .# #H 
			                             ( ( ( ( ( ( ' ' ' ' ' ' + + + + + +W W W W W W W Wta a a a a a a a a ar6   