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

Read coordinates data from a `ParmEd <https://parmed.github.io/ParmEd/html>`_ :class:`parmed.structure.Structure`
with :class:`ParmEdReader` into a MDAnalysis Universe. Convert it back to a
:class:`parmed.structure.Structure` with :class:`ParmEdConverter`.

Example
-------

ParmEd has some neat functions. One such is `HMassRepartition`_.
This function changes the mass of the hydrogens in your system to your desired
value. It then adjusts the mass of the atom to which it is bonded by the same
amount, so that the total mass is unchanged. ::

    >>> import MDAnalysis as mda
    >>> from MDAnalysis.tests.datafiles import PRM
    >>> u = mda.Universe(PRM)
    >>> u.atoms.masses[:10]
    array([14.01 ,  1.008,  1.008,  1.008, 12.01 ,  1.008, 12.01 ,  1.008,
        1.008,  1.008])

We can convert our universe to a ParmEd structure to change our hydrogen
masses. ::

    >>> import parmed.tools as pmt
    >>> parm = u.atoms.convert_to('PARMED')
    >>> hmass = pmt.HMassRepartition(parm, 5)  # convert to 5 daltons
    >>> hmass.execute()

We can then convert it back to an MDAnalysis Universe for further analysis. ::

    >>> u2 = mda.Universe(parm)
    >>> u2.atoms.masses[:10]
    array([2.03399992, 5.        , 5.        , 5.        , 8.01799965,
       5.        , 0.034     , 5.        , 5.        , 5.        ])

.. _`HMassRepartition`: http://parmed.github.io/ParmEd/html/parmed.html#hmassrepartition



Classes
-------

.. autoclass:: ParmEdReader
   :members:

.. autoclass:: ParmEdConverter
   :members:


.. versionchanged:: 2.0.0
   The ParmEdReader and ParmEdConverter classes were moved from :mod:`~MDAnalysis.coordinates`
   to :mod:`~MDAnalysis.converters`

    N   )SYMB2Z   )base)SingleFrameReaderBase)Universe)NoDataErrorc                   <    e Zd ZdZdZdddZed             Zd ZdS )ParmEdReaderzCoordinate reader for ParmEd.PARMEDNAngstromtimelengthc                 X    	 ddl }t          | |j                  S # t          $ r Y dS w xY w)zGCan this reader read *thing*?

        .. versionadded:: 1.0.0
        r   NF)parmed
isinstance	StructureImportError)thingpmds     f/srv/www/vhosts/g4struct/public_html/venv/lib/python3.11/site-packages/MDAnalysis/converters/ParmEd.py_format_hintzParmEdReader._format_hinte   sK    	4    
 eS]333	  	 	 	55	s    
))c                     t          | j        j                  | _         | j        | j        fi | j        x| _        }| j        j        | j        j        |_        | j        j	        |_
        d|_        |S )Nr   )lenfilenameatomsn_atoms	_Timestep
_ts_kwargstscoordinates_posbox
dimensionsframe)selfr!   s     r   _read_first_framezParmEdReader._read_first_frames   sk    4=.//%t~dlFFdoFFF"=$0m/BG )	    )	__name__
__module____qualname____doc__formatunitsstaticmethodr   r(    r)   r   r   r   ]   sV        ''F Z00E4 4 \4    r)   r   bfactorscreenaltlocnb_idxsolvent_radiusnumber)
tempfactorgbscreenaltLocnbindexsolventradiusidc                 (    ||j         |                   S Nr   )i	atomgroupuniverses      r   get_indices_from_subsetrD      s    X^A&''r)   c                   &    e Zd ZdZdZdddZd ZdS )ParmEdConvertera  Convert MDAnalysis AtomGroup or Universe to ParmEd :class:`~parmed.structure.Structure`.

    Example
    -------

    .. code-block:: python

        import parmed as pmd
        import MDAnalysis as mda
        from MDAnalysis.tests.datafiles import GRO
        pgro = pmd.load_file(GRO)
        mgro = mda.Universe(pgro)
        parmed_subset = mgro.select_atoms('resname SOL').convert_to('PARMED')


    r   Nr   r   c           	        , 	 ddl }n# t          $ r d}t          |          w xY w	 |j        }n# t          $ r t	          d          d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|r;t          j        d	                    d
                    |                               	 |j        }n"# t          t          f$ r dg|j        z  }Y nw xY w	 |j        }	n"# t          t          f$ r dg|j        z  }	Y nw xY wg }
t%          |||||	          D ]X\  }}}}}d|i}d|j        i}dD ]?}	 t)          ||          |t*                              ||          <   0# t          $ r Y <w xY w	 |j                                                                        }t4          |         |d<   nk# t6          t          f$ rW 	 |j                                                                        }t4          |         |d<   n# t6          t          f$ r Y nw xY wY nw xY w	 |j        |d<   n# t          $ r Y nw xY w	 |j        |d<   n# t          $ r Y nw xY w|
	                    |||j        |||f           Z|                                 ,|
D ]\  }}}}}} |j!        d)i |}||\  |_"        |_#        |_$        ||\  |_%        |_&        |_'        |(                    |d         d|d         |                    d                    |_)         ,j*        |||fi | 	 |j+        ,_,        n# t          $ r
 d,_,        Y nw xY wt[          |d          rHd t]          t_          |                    D             }ta          j1        td          ||j3                  }nd }	 |j4        }|D ]Z},fdtk          ||j6                  D             }	 |j        D ]4} |j7        ||j        |j8        d},j9        	                    |           5tu          |j        |j;                  r0,j<        	                    |j                   ,j<        |j        _/        # t          t          f$ r |j8        |j8        nd}t)          |j        dd          } |j7        |||d},j9        	                    |           tu          |j        |j;                  r0,j<        	                    |j                   ,j<        |j        _/        Y Xw xY wn# t          $ r Y nw xY w	 |j=        >                    |d          }|D ]},fdtk          ||j6                  D             }	 |j        D ]}t)          |dd           } t)          |d!d           }! |j?        ||j        |!| d"}",j=        	                    |"           tu          |"j        |j@                  r0,jA        	                    |"j                   ,jA        |"j        _/        # t          t          f$ r t)          |j        dd          }t)          |j        dd           } t)          |j        d!d           }! |j?        ||| |!d#}",j=        	                    |"           tu          |"j        |j@                  r0,jA        	                    |"j                   ,jA        |"j        _/        Y w xY wn# t          $ r Y nw xY wd$|jB        ,jC        ,jD        |j;        fd%|jE        ,jF        ,jG        |jH        fd&|jI        ,jJ        ,jK        |jL        fd'|jM        ,jN        ,jO        |jP        ffD ]W\  }#}$}%}&}'	 t)          ||#          }|>                    |d          }(|(D ]}),fd(tk          ||)j6                  D             }	 |)j        D ]_}* |$|d|*j        i}|%	                    |           tu          |j        |'          r&|&	                    |j                   |&|j        _/        `# t          t          f$ rr t)          |)j        dd          }+ |$|d|+i}|%	                    |           tu          |j        |'          r&|&	                    |j                   |&|j        _/        Y w xY wH# t          $ r Y Uw xY w,S )*zWrite selection at current trajectory frame to :class:`~parmed.structure.Structure`.

        Parameters
        -----------
        obj : AtomGroup or Universe or :class:`Timestep`
        r   NzgParmEd is required for ParmEdConverter but is not installed. Try installing it with 
pip install parmedzNo atoms found in obj argument)Xnames)UNKresnameszSupplied AtomGroup was missing the following attributes: {miss}. These will be written with default values. Alternatively these can be supplied as keyword arguments.z, )missnamesegid)masschargetyper:   r8   	occupancyr9   r<   r;   rminepsilonrmin14	epsilon14r=   atomic_numberchaininscoderO   )rW   rC   c                     i | ]\  }}||	S r1   r1   ).0indexatoms      r   
<dictcomp>z+ParmEdConverter.convert.<locals>.<dictcomp>#  s+        +te  r)   )rB   rC   c                     | S r?   r1   )xs    r   <lambda>z)ParmEdConverter.convert.<locals>.<lambda>,  s     r)   c                 *    g | ]}j         |         S r1   r@   r[   rA   structs     r   
<listcomp>z+ParmEdConverter.convert.<locals>.<listcomp>5  ,       ()FLO  r)   )rQ   orderr   rQ   T)strictc                 *    g | ]}j         |         S r1   r@   rc   s     r   re   z+ParmEdConverter.convert.<locals>.<listcomp>R  rf   r)   improperF
ignore_end)rQ   rk   rj   )rQ   rj   rk   ureybradleysangles	improperscmapsc                 *    g | ]}j         |         S r1   r@   rc   s     r   re   z+ParmEdConverter.convert.<locals>.<listcomp>  s/        Q  r)   r1   )Qr   r   r   AttributeError	TypeErrorrI   r	   	itertoolscycleappendrK   warningswarnr.   join	positionsr   
velocitiesziprN   getattrMDA2PMDgetelementlower
capitalizer   KeyErrorrQ   chainIDicoderesidr   AtomxxxyxzvxvyvzAtomType	atom_typeadd_atomr%   r$   hasattr	enumeratelist	functoolspartialrD   rC   intra_bondsmapindicesBondrg   bondsr   BondType
bond_types	dihedralsatomgroup_intersectionDihedralDihedralTypedihedral_typesUreyBradleyurey_bradleysurey_bradley_typesAnglerm   angle_types	AngleTypeImproperrn   improper_typesImproperTypeCmapro   
cmap_typesCmapType)-r'   objr   errmsgag_or_tsmissing_topologyrI   rK   ry   rz   atom_kwargsr]   rM   resnamexyzvelakwargs	chain_segattrnameeltpakwargr   kwrB   get_atom_indicesparamspr   bondrg   btypeimpigndihparampmdtypetrackedlisttypelistclstypevaluesv
parmed_objvtyperd   s-                                               @r   convertzParmEdConverter.convert   s   	&      	& 	& 	&% 
 f%%%	&	HyHH 	H 	H 	H<==4G	H 	-NEE, 	- 	- 	-OF++E##G,,,,,	-	0(HH, 	0 	0 	0 x00H##J/////	0  	M 6tyy)9::6;;	  	2 *II, 	2 	2 	2!11III	2	3!,JJ, 	3 	3 	3("22JJJ	3 -0eXy*.
 .
 .	 .	)D$c tnG $*-I   ?Fh@ @GGKK(;;<< &   D\''))4466+1":((n-   **5577B/5bzGO,, .1   D	%)\	'""!   '+z	)$$!   '4:y#sC    4? 	8 	80FGUBS38%%f%%D,/)$',/)$' \\vv%kk/::	 *  DN FOD'577B7777	!,FJJ 	 	 	FJJJ	 8Z(( 
	+ /8h/H/H  I  )0'#!*       +{	;)F  ; ;   -01A19-M-M  ; v 2 2'sxSXSYOOO++D1111!#(CL99 ;)00;;;)/):	!>2 ; ; ;'(w':AGGE#AFFD99E#38UeDDDDL''---!$)S\:: ;)00;;;)/):	;;  	 	 	D	2 	>'>> ?  F  > >   -01A19-M-M  > v 	B 	B%c:u==%c<??*cl"cC   (//444%ch0@AA B"188BBB,2,ACHM	B ">2 
> 
> 
>#AFFD99E!!&*e<<C!!&,>>C&#,USS  C $++C000!#(C,<== >-44SX>>>(.(=
>>  	 	 	D	@ $) 	"  %  chf.?N-?
 2	3 2	3:E7K703 51166x6MM   3 3A   !$%5qy!A!A  E
3*+& 7 7J ' EZ_ E EA'..q111)!&':: 7 ( 7 7 7.67 &~6 3 3 3 ' = =#GU777#**1---%afg66 3$OOAF333*2AFK33 "   0 sI   $0 AA :BBB" ":CC D( (EEE E21E2%,G
GG#;HJ1;I-,J-J>J JJJ
J
J#"J#'
J22
J?>J?N N.-N.U3 ;BSB)U/.U/3
V ?V \: B$Y,,C\65\6:
]]>'c<A'a44A?c76c7<
d
	d
)r*   r+   r,   r-   libr/   r   r1   r)   r   rF   rF      sF         " CZ00Ez z z z zr)   rF   )NN)r-   r   rs   rv   guesser.tablesr   numpynp r   coordinates.baser   core.universer   
exceptionsr	   r   r}   rD   ConverterBaserF   r1   r)   r   <module>r      s:  07 7p          # # # # # #           4 4 4 4 4 4 $ $ $ $ $ $ $ $ $ $ $ $" " " " "( " " "L %
 ( ( ( (O O O O Od( O O O O Or)   