
     imJ                         d 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
Zg dZg dZd Z G d dej                  Z G d dej                  ZdS )a		  
GRO file format --- :mod:`MDAnalysis.coordinates.GRO`
======================================================

Classes to read and write Gromacs_ GRO_ coordinate files; see the notes on the
`GRO format`_ which includes a conversion routine for the box.


Writing GRO files
-----------------

By default any written GRO files will renumber the atom ids to move sequentially
from 1.  This can be disabled, and instead the original atom ids kept, by
using the `reindex=False` keyword argument.  This is useful when writing a
subsection of a larger Universe while wanting to preserve the original
identities of atoms.

For example::

   >>> u = mda.Universe()`

   >>> u.atoms.write('out.gro', reindex=False)

   # OR
   >>> with mda.Writer('out.gro', reindex=False) as w:
   ...     w.write(u.atoms)


Classes
-------

.. autoclass:: GROReader
   :members:

.. autoclass:: GROWriter
   :members:


Developer notes: ``GROWriter`` format strings
---------------------------------------------

The :class:`GROWriter` class has a :attr:`GROWriter.fmt` attribute, which is a dictionary of different
strings for writing lines in ``.gro`` files.  These are as follows:

``n_atoms``
  For the first line of the gro file, supply the number of atoms in the system.
  E.g.::

      fmt['n_atoms'].format(42)

``xyz``
  An atom line without velocities.  Requires that the 'resid', 'resname',
  'name', 'index' and 'pos' keys be supplied.
  E.g.::

     fmt['xyz'].format(resid=1, resname='SOL', name='OW2', index=2, pos=(0.0, 1.0, 2.0))

``xyz_v``
  As above, but with velocities.  Needs an additional keyword 'vel'.

``box_orthorhombic``
  The final line of the gro file which gives box dimensions.  Requires
  the box keyword to be given, which should be the three cartesian dimensions.
  E.g.::

     fmt['box_orthorhombic'].format(box=(10.0, 10.0, 10.0))

``box_triclinic``
  As above, but for a non orthorhombic box. Requires the box keyword, but this
  time as a length 9 vector.  This is a flattened version of the (3,3) triclinic
  vector representation of the unit cell.  The rearrangement into the odd
  gromacs order is done automatically.


.. _Gromacs: http://www.gromacs.org
.. _GRO: https://manual.gromacs.org/current/reference-manual/file-formats.html#gro
.. _GRO format: http://chembytes.wikidot.com/g-grofile

    N   )base)triclinic_boxtriclinic_vectors   )NoDataError)util)Timestep)r         )   r      )      r   c                 r    | t                    }| t                   }| t                   }t          |||          S N)_TS_ORDER_X_TS_ORDER_Y_TS_ORDER_Zr   )boxxyzs       d/srv/www/vhosts/g4struct/public_html/venv/lib/python3.11/site-packages/MDAnalysis/coordinates/GRO.py_gmx_to_dimensionsr      s2    KAKAKAAq!!!    c                   4    e Zd ZdZdZddddZeZd Zd	dZ	dS )
	GROReadera  Reader for the Gromacs GRO structure format.

    .. note::
       This Reader will only read the first frame present in a file.


    .. note::
       GRO files with zeroed 3 entry unit cells (i.e. ``0.0   0.0   0.0``)
       are read as missing unit cell information. In these cases ``dimensions``
       will be set to ``None``.

    .. versionchanged:: 0.11.0
       Frames now 0-based instead of 1-based
    .. versionchanged:: 2.0.0
       Reader now only parses boxes defined with 3 or 9 fields.
       Reader now reads a 3 entry zero unit cell (i.e. ``[0, 0, 0]``) as a
       being without dimension information (i.e. will the timestep dimension
       to ``None``).
    GRONnmnm/pstimelengthvelocityc           	        
 t          j        | j        d          5 }|                                 t	          |                                          x| _        } | j        |fi | j        x| _        }t          j
        |dft          j                  }d}|                                dd                              d          dz   

fdt          d          D             |j        d	<   	 
fd
t          dd          D             |d	<   n# t          $ r d}Y nw xY wt!          |d          D ]\  }||k    ra	 t          j                                                  }n7# t          $ r* t          j        t%          j        d                    }Y nw xY w nX
fdt          d          D             |j        |<   	 
fdt          dd          D             ||<   # t          $ r d}Y w xY wd d d            n# 1 swxY w Y   t          j        |          r||_        |rt-          j        d           d	| j        _        t3          |          dk    r[t          j        |g d          r#d}t-          j        |           d | j        _        n_t          j        |g df         | j        _        n>t3          |          dk    rt;          |          | j        _        nd}	t          |	          | j        r|                     | j        j                   | j        j        '|                     | j        j        d d                    | j        j         r#| !                    | j        j"                   d S d S d S )Nrtr   )dtypeF   .r   c                 B    g | ]}d |z  z   d |dz   z  z            S    r    .0icsfirst_atomlines     r   
<listcomp>z/GROReader._read_first_frame.<locals>.<listcomp>   sH        rBF{R"A,->>?  r   r   c                 B    g | ]}d |z  z   d |dz   z  z            S r,   r.   r/   s     r   r4   z/GROReader._read_first_frame.<locals>.<listcomp>   sH     ! ! ! #2Q;bAEl1B#BC! ! !r   r   T)startz(\d+\.\d{5})c                 B    g | ]}d |z  z   d |dz   z  z            S r,   r.   r0   r1   r2   lines     r   r4   z/GROReader._read_first_frame.<locals>.<listcomp>   sE          >?Db1frB!a%L'889     r   c                 B    g | ]}d |z  z   d |dz   z  z            S r,   r.   r8   s     r   r4   z/GROReader._read_first_frame.<locals>.<listcomp>   sH     ' ' ' R"q&[2a!e+<<=' ' 'r   z?Not all velocities were present.  Unset velocities set to zero.)        r;   r;   zWEmpty box [0., 0., 0.] found - treating as missing unit cell. Dimensions set to `None`.     V@r=   r=   	   z)GRO unitcell has neither 3 nor 9 entries.)#r	   openanyfilenamereadlineintn_atoms	_Timestep
_ts_kwargstsnpzerosfloat32findrange_pos
ValueError	enumeratesplitrefindallany
velocitieswarningswarnframelenallclose
dimensionsr_r   convert_unitsconvert_pos_from_nativehas_velocitiesconvert_velocities_from_native_velocities)selfgrofilerC   rF   rS   
missed_velposunitcellwmsgerrmsgr2   r3   r9   s             @@@r   _read_first_framezGROReader._read_first_frame   su   \$-.. 1	&'%()9)9););%<%<<DL7)4>'EET_EEEDGb7A,bjAAAJJ %--//N$))#..2B    q  BGAJ"! ! ! ! !"1a[[! ! !
1  " " "!


"
 'wa888 & &	T'>>#%:djjll#;#;%   #%:J==$ $
 E         CH88     &' ' ' ' '!&q!' ' 'JsOO " & & &!%JJJ&_1	& 1	& 1	& 1	& 1	& 1	& 1	& 1	& 1	& 1	& 1	& 1	& 1	& 1	& 1	&f 6* 	&BM 4  
 x==A {8___55 I;  d###%)""%'U85G5G5G+G%H""]]a!3H!=!=DG@FV$$$ 	I((666w!-,,G&rr*   w% I33DG4GHHHHH	I 	II Is~   CH2 DHD"H!D""H&E)(H)1FHF)H G('H(G74H6G77HH
H
c                 2    || j         }t          |fd|i|S )zReturns a CRDWriter for *filename*.

        Parameters
        ----------
        filename: str
            filename of the output GRO file

        Returns
        -------
        :class:`GROWriter`

        NrC   )rC   	GROWriter)r`   r@   rC   kwargss       r   WriterzGROReader.Writer	  s+     ?lG==7=f===r   r   )
__name__
__module____qualname____doc__formatunitsr
   rD   rg   rk   r.   r   r   r   r      sc         ( FTw??EIYI YI YIv> > > > > >r   r   c                   t    e Zd ZdZdZddddZddd	Zd
ddddZed         dd         dz   ed<   ddZd Z	dS )ri   a/  GRO Writer that conforms to the Trajectory API.

    Will attempt to write the following information from the topology:
     - atom name (defaults to 'X')
     - resnames (defaults to 'UNK')
     - resids (defaults to '1')


    .. note::
        The precision is hard coded to three decimal places.


    .. note::
        When dimensions are missing (i.e. set to `None`), a zero width
        unit cell box will be written (i.e. [0.0, 0.0, 0.0]).


    .. versionchanged:: 0.11.0
       Frames now 0-based instead of 1-based
    .. versionchanged:: 0.13.0
       Now strictly writes positions with 3dp precision.
       and velocities with 4dp.
       Removed the `convert_dimensions_to_unitcell` method,
       use `Timestep.triclinic_dimensions` instead.
       Now now writes velocities where possible.
    .. versionchanged:: 0.18.0
       Added `reindex` keyword argument to allow original atom
       ids to be kept.
    .. versionchanged:: 2.0.0
       Raises a warning when writing timestep with missing dimension
       information (i.e. set to ``None``).
    r   Nr    r!   r"   g"?g-@)minmaxz{0:5d}
zY{resid:>5d}{resname:<5.5s}{name:>5.5s}{index:>5d}{pos[0]:8.3f}{pos[1]:8.3f}{pos[2]:8.3f}
z+{box[0]:10.5f} {box[1]:9.5f} {box[2]:9.5f}
z{box[0]:10.5f} {box[4]:9.5f} {box[8]:9.5f} {box[1]:9.5f} {box[2]:9.5f} {box[3]:9.5f} {box[5]:9.5f} {box[6]:9.5f} {box[7]:9.5f}
)rC   xyzbox_orthorhombicbox_triclinicru   z({vel[0]:8.4f}{vel[1]:8.4f}{vel[2]:8.4f}
xyz_vTc                     t          j        |dd          | _        || _        |                    dd          | _        || _        dS )a  Set up a GROWriter with a precision of 3 decimal places.

        Parameters
        -----------
        filename : str
            output filename
        n_atoms : int (optional)
            number of atoms
        convert_units : bool (optional)
            units are converted to the MDAnalysis base format; [``True``]
        reindex : bool (optional)
            By default, all the atoms were reindexed to have a atom id starting
            from 1. [``True``] However, this behaviour can be turned off by
            specifying `reindex` ``=False``.

        Note
        ----
        To use the reindex keyword, user can follow the two examples given
        below.::

           u = mda.Universe()

        Usage 1::

           u.atoms.write('out.gro', reindex=False)

        Usage 2::

           with mda.Writer('out.gro', reindex=False) as w:
               w.write(u.atoms)

        groT)extkeepreindexN)r	   r@   rC   popr~   r[   )r`   r@   r[   rC   rj   s        r   __init__zGROWriter.__init__O  sL    B hEEEEzz)T22  	r   c                  
   	 |j         }n # t          $ r d}t          |          dw xY w	 |j        }d}n# t          $ r d}Y nw xY wg }	 |j        }n@# t          t          f$ r, t          j        d          }|                    d           Y nw xY w	 |j	        }n@# t          t          f$ r, t          j        d          }|                    d           Y nw xY w	 |j
        }	n@# t          t          f$ r, t          j        d	          }	|                    d
           Y nw xY w| j        sM	 |j        }
n\# t          t          f$ r0 t          d|j        dz             }
|                    d           Y nw xY wt          d|j        dz             }
|r;t          j        d                    d                    |                               |j        }| j        r0|                     |d          }|r|                     |d          }|                     | j        |          s9t3          d                    | j        d         | j        d                             t5          j        | j        d          5 }|                    d           |                    | j        d                             |j                             t?          t          |j                  |	||          D ]\  }}}}t5          j         |
|         d          }t5          j         |d          }|rF|                    | j        d                             ||||||         ||                              |                    | j        d                             ||||||                              |j!        $tE          j#        |j!        dd         g d          r|j!        +d}t          j        |           tE          j$        d          }n$|                     |j!        dd         d          }|                    | j        d                             |                      n	 |j%        j&        j'        }n# t          $ r
 |j'        }Y nw xY w|                     |(                                d          }|                    | j        d!                             |                      ddd           dS # 1 swxY w Y   dS )"a  Write selection at current trajectory frame to file.

        Parameters
        -----------
        obj : AtomGroup or Universe

        Note
        ----
        The GRO format only allows 5 digits for *resid* and *atom
        number*. If these numbers become larger than 99,999 then this
        routine will chop off the leading digits.


        .. versionchanged:: 0.7.6
           *resName* and *atomName* are truncated to a maximum of 5 characters
        .. versionchanged:: 0.16.0
           `frame` kwarg has been removed
        .. versionchanged:: 2.0.0
           Deprecated support for calling with Timestep has nwo been removed.
           Use AtomGroup or Universe as an input instead.
        z-Input obj is neither an AtomGroup or UniverseNTF)Xnames)UNKresnames)r   residsr   idszSupplied AtomGroup was missing the following attributes: {miss}. These will be written with default values. Alternatively these can be supplied as keyword arguments.z, )miss)inplacezZGRO files must have coordinate values between {0:.3f} and {1:.3f} nm: No file was written.rs   rt   wtzWritten by MDAnalysis
rC   r   ry   )residresnameindexnamerc   velru   )r   r   r   r   rc   r   r<   z@missing dimension - setting unit cell to zeroed box [0., 0., 0.]rv   )r   rw   ))atomsAttributeError	TypeErrorrS   r   r   	itertoolscycleappendr   r   r~   r   rK   rC   rT   rU   rp   join	positionsr[   convert_pos_to_nativeconvert_velocities_to_nativehas_valid_coordinatesgro_coor_limitsrM   r	   r?   r@   writefmtzipltruncate_intrY   rG   rX   rH   universecoordtriclinic_dimensionsflatten)r`   objagrf   rS   r]   missing_topologyr   r   r   atom_indicesr   
output_gro
atom_indexr   r   r   truncated_atom_indextruncated_residre   r   tri_dimss                         r   r   zGROWriter.writex  s7   0	. BB  	. 	. 	.DFF##-	.	"J "NN  	# 	# 	#"NNN	# 	-HEE, 	- 	- 	-OF++E##G,,,,,	-	0{HH, 	0 	0 	0 x00H##J/////	0	.YFF, 	. 	. 	._T**F##H-----	. | 	4/!v"K0 / / /$Q
Q77 ''...../ !BJN33L 	M 6tyy)9::6;;	   L	 	 229e2LLI !>> ?  

 ))$*>	JJ 	6(/1Ee1L    \$-.. ?	L*6777TXi077
CCDDD
 58bj!!68U5 5  0
E7D (,'9 ,a( ($ #'"4UA">">! $$)00"1$+"6!% )* 5 *: 6 1  	 	 	 	 $$.."1$+"6!% )* 5 /      }$abb!#5#5#5) )$ =(+  M$'''(1++CC44bqb)5 5  C   *<!=!D!D!D!M!MNNNN8"|1FHH% 8 8 8"7HHH8 00$$&& 1     /!:!A!Ac!A!J!JKKK?	L ?	L ?	L ?	L ?	L ?	L ?	L ?	L ?	L ?	L ?	L ?	L ?	L ?	L ?	L ?	L ?	L ?	Ls   
 '5 AA
A :BBB :CCC$ $:D! D!,D4 4>E54E59G&S3 Q21S32RS3RA S33S7:S7)TN)
rl   rm   rn   ro   rp   rq   r   r   r   r   r.   r   r   ri   ri     s         B FTw??E'	::O
 kJ \ C 	E
3B3EE L'
 '
 '
 '
R_L _L _L _L _Lr   ri   )ro   rP   r   rT   numpyrG    r   corer   r   
exceptionsr   libr	   timestepr
   r   r   r   r   SingleFrameReaderBaser   
WriterBaseri   r.   r   r   <module>r      sO  0N N^ 
			                2 2 2 2 2 2 2 2 $ $ $ $ $ $            ( iiiiii" " "C> C> C> C> C>* C> C> C>L|L |L |L |L |L |L |L |L |L |Lr   