B
    bm                @   s  d Z ddlmZmZmZ ddlmZmZ ddlm	Z	 ddl
Z
ddlmZ ddlZddlZddlZyddlmZ W n  ek
r   ddlmZ Y nX ddlZddlZdd	lmZmZ dd
lmZmZm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&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z< ddl=m>Z>m?Z? ddl@mAZB ddlCmDZD ddlEmFZFmGZGmHZH ddlImJZJ yRddlKZKyeKLeM d ZNW n eOk
r   dZNY nX eM ZPeQ d ZRW n: ek
r2   ddlSZSeST ZNdZPddlUZUeUV ZRY nX eWdZXG dd deYZZeFeG dd de$Z[d%ddZ\dd  Z]d!d" Z^d#d$ Z_dS )&zq
This module contains functionality relevant to loading a GROMACS topology file
and building a Structure from it
    )print_functiondivisionabsolute_import)OrderedDictdefaultdict)closingN)datetime)letters)ascii_letters)TINY
DEG_TO_RAD)GromacsErrorGromacsWarningParameterError)FileFormatType)ParameterSet_find_ureybrad_key)GromacsFile)	Structure)AtomBondAngleDihedralImproperNonbondedException
ExtraPointBondTypeCmapNoUreyBradley	AngleTypeDihedralTypeDihedralTypeListImproperTypeCmapTypeRBTorsionTypeThreeParticleExtraPointFrameAtomTypeUreyBradleyTwoParticleExtraPointFrameOutOfPlaneExtraPointFrameNonbondedExceptionTypeUnassignedAtomType)element_by_mass	AtomicNum)unit)genopen)add_metaclassstring_types	iteritems)rangeZusername   z\[ (\w+) \]\s*$c               @   s:   e Zd ZdZdddZdd	 Zd
d Zdd Zdd ZdS )	_Defaultsz= Global properties of force fields as implemented in GROMACS r4      no      ?c             C   s   t |dkrtdt |dkr(td|dkr8tdt|dk rLtdt|dk r`td	t || _t || _|| _t|| _t|| _d S )
N)r4   r6   z(nbfunc must be 1 (L-J) or 2 (Buckingham))r4   r6      zcomb_rule must be 1, 2, or 3)yesr7   zgen_pairs must be 'yes' or 'no'r   zfudgeLJ must be non-negativezfudgeQQ must be non-negative)int
ValueErrorfloatnbfunc	comb_rule	gen_pairsfudgeLJfudgeQQ)selfr>   r?   r@   rA   rB    rD   8lib/python3.7/site-packages/parmed/gromacs/gromacstop.py__init__f   s    


z_Defaults.__init__c             C   s   d| j | j| j| j| jf S )NzL<_Defaults: nbfunc=%d, comb-rule=%d, gen-pairs="%s", fudgeLJ=%g, fudgeQQ=%g>)r>   r?   r@   rA   rB   )rC   rD   rD   rE   __repr__x   s    z_Defaults.__repr__c             C   sf   |dk r|d7 }|dkr| j S |dkr,| jS |dkr:| jS |dkrH| jS |dkrV| jS td| d S )Nr      r4   r6   r9      zIndex %d out of range)r>   r?   r@   rA   rB   
IndexError)rC   idxrD   rD   rE   __getitem__}   s          z_Defaults.__getitem__c             C   s<   | j |j ko:| j|jko:| j|jko:| j|jko:| j|jkS )N)r>   r?   r@   rA   rB   )rC   otherrD   rD   rE   __eq__   s
    z_Defaults.__eq__c             C   s   |dk r|d7 }|dkr8t |dkr,tdt || _n|dkr`t |dkrTtdt || _nx|dkr|d	krxtd
|| _nX|dkrt|dk rtdt|| _n0|dkrt|dk rtd|| _ntd| d S )Nr   rH   )r4   r6   znbfunc must be 1 or 2r4   )r4   r6   r9   zcomb_rule must be 1, 2, or 3r6   )r:   r7   zgen_pairs must be "yes" or "no"r9   zfudgeLJ must be non-negativerI   zfudgeQQ must be non-negativezIndex %d out of range)	r;   r<   r>   r?   r@   r=   rA   rB   rJ   )rC   rK   valuerD   rD   rE   __setitem__   s.     z_Defaults.__setitem__N)r4   r6   r7   r8   r8   )	__name__
__module____qualname____doc__rF   rG   rL   rN   rP   rD   rD   rD   rE   r5   d   s    

r5   c                   s   e Zd ZdZedd Zd@ fdd	ZdAdd	Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' ZdBd(d)Zd*d+ Zd,d- Zd.d/ ZdC fd1d2	Z fd3d4ZedDd5d6ZdEd8d9Zed:d; Z d<d= Z!d>d? Z"  Z#S )FGromacsTopologyFilea   Class providing a parser and writer for a GROMACS topology file

    Parameters
    ----------
    fname : str
        The name of the file to read
    defines : list of str=None
        If specified, this is the set of defines to use when parsing the
        topology file
    parametrized : bool, optional
        If True, parameters are assigned after parsing is done from the
        parametertypes sections. If False, only parameter types defined in the
        parameter sections themselves are loaded (i.e., on the same line as the
        parameter was defined). Default is True
    xyz : str or array, optional
        The source of atomic coordinates. It can be a string containing the name
        of a coordinate file from which to fill the coordinates (and optionally
        the unit cell information), or it can be an array with the coordinates.
        Default is None
    box : array, optional
        If provided, the unit cell information will be set from this variable.
        If provided, it must be a collection of 6 floats representing the unit
        cell dimensions a, b, c, alpha, beta, and gamma, respectively. Default
        is None.

    Notes
    -----
    If the ``xyz`` argument is a file name that contains the unit cell
    information, this unit cell information is set. However, the ``box``
    argument takes precedence and will override values given in the coordinate
    file unless it has its default value of ``None``.
    c          	   C   s   t t| }x|D ]}|dr4|d|d }| s>q|dr|drTq|dr`q|drlq|drxq|drqd	S t|}|sd	S | \}|d
kS W d	S Q R X dS )aT   Identifies the file as a GROMACS topology file

        Parameters
        ----------
        filename : str
            Name of the file to check if it is a gromacs topology file

        Returns
        -------
        is_fmt : bool
            If it is identified as a gromacs topology, return True. False
            otherwise
        ;N#z#ifz#definez#includez#undefz#endifF)atoms	atomtypesdefaultsmoleculetypesystem	bondtypes
angletypes	cmaptypesdihedraltypesbondsangles	dihedralscmaps	molecules
exclusionsnonbond_paramsZposition_restraints)r   r/   
startswithindexstrip
_sectionrematchgroups)filenameflineZrematchZsecrD   rD   rE   	id_format   s0    

 

 
 
 
 
 


zGromacsTopologyFile.id_formatNTc                s   ddl m} tt|   d | _tdd| _|d k	r| ||| |d k	rt	|t
r||dd}t|drt|jd krtd| |j| _|d krt|d	r|j| _n|| _|d k	r|| _|   n|d k	s|d k	rtd
d S )Nr   )	load_filer:   )r@   T)Z
skip_bondscoordinatesz!File %s does not have coordinatesboxz,Cannot provide coordinates/box and NOT a top)parmedrr   superrU   rF   parametersetr5   rZ   read
isinstancer1   hasattrrs   	TypeErrorrt   Zunchanger<   )rC   fnamedefinesparametrizeZxyzrt   rr   ro   )	__class__rD   rE   rF      s*    


zGromacsTopologyFile.__init__c       7         s^  ddl m} t  }| _t  }| _t }t }t }	t }
t }g }g }|dkr\tdd}t }tt||j	g|d}d}x|D ]}|
 }|sq|d dkr|dd 
 }q|d	kr.| \}}t|}||krtd
| t   |f||< || | _t }t }t }	t }
t }q|dkrL j| ||  q|dkr| || j\}} j| |dk	r$ j|  j|_q|dkr| || j\}} j| |dk	r$ j|  j|_q|dkrn| |||	 j\}}}} j| |dk	r& j| |dk	rD j|  j|_|dk	r$|tk	r$ j |  j |_q|dkr| !||
|  q|dkr| "| j} j#| q|dkr|| _$q|dkr*| }t%|dk rtd|d dkr
t&'dt( d| _)|d dkrd| _*t+| | _,q|dkrX| \}}t|}|||f q|dkr| -| j\} }! j.|   j.|!  j/  q|dkry| 0| j|\}"}#W n t1k
r   tdY nX  j|"  j|#  j|#_q|dkrD fdd | D }$x$|$dd D ]}%|$d 2|% q*W q|d!krh| 3|\}&}'|'|j4|&< q|d"kr| }|dd \}(})d#d$ |d%d& D \}*}+|*d'9 }*|+t5j67t5j89 }+|+|*d( f|j9|(|)f< |+|*d( f|j9|)|(f< |j4|( :|)|*d( |+ |j4|) :|(|*d( |+ q|d)krT| ;|\}%}"},|,|j|%|"f< |,|j|"|%f< q|d*kr| <|\}%}"}-},}.|,|j|%|"|-f< |,|j|-|"|%f< |.dk	r$|.|j |%|"|-f< |.|j |-|"|%f< q|d+kr| =|\}/}0},}1t>t?|/}2|0d,krD|1s|/|j@kr"tA|,g},|,|j@|/< |,|j@|2< n |/|j@kr|j@|/ j|,dd- nT|0d.krZ|,|jB|/< n>|0d/krz|,|jC|/< |,|jC|2< n|0d0kr$|,|jD|/< |,|jD|2< q|d1kr| E|\}(})}3}4}5},|,|jF|(|)|3|4|)|3|4|5f< |,|jF|5|4|3|)|4|3|)|(f< q|d2kr| G|\}%}"},|, |jH|%|"f< |jH|"|%f< qW |jI}6W dQ R X |s\x|D ]}||df qDW x|D ]\}}||krtd3| || \ }|d%k rtJ |rt&'d4| t( n&|d%krtJ d%rt&'d4| t( |dkrt&'d5| t( |dkr| || d 7 } n0|dkr0| || d | 7 } ntd6||f qbW |6| _K|rZ| L  dS )7z3 Reads the topology file into the current instance r   )gromacsNr4   )ZFLEXIBLE)Zincludesr}   [r[   z#Duplicate definition of molecule %srX   ra   Zpairsrb   rc   cmapr\   rZ   r6   zToo few fields in [ defaults ]1z.Unsupported nonbonded type; unknown functionalT)r   3	geometricre   Zsettles)Zvirtual_sites3Zdummies3z7Cannot determine vsite geometry without parameter typesrf   c                s   g | ]} j t|d   qS )r4   )rX   r;   ).0w)moleculerD   rE   
<listcomp>v  s    z,GromacsTopologyFile.read.<locals>.<listcomp>rY   rg   c             s   s   | ]}t |V  qd S )N)r=   )r   xrD   rD   rE   	<genexpr>  s    z+GromacsTopologyFile.read.<locals>.<genexpr>r9   rH   
   gÚ?r]   r^   r`   normal)overrideimproperimproper_periodic	rbtorsionr_   Z	pairtypesz8Structure contains %s molecules, but no template definedz!nrexcl %d not currently supportedz4Detected addition of 0 %s molecules in topology filezCan't add %d %s molecules)Mru   r   r   rw   dictre   r   r   r   GROMACS_TOPDIRrj   splitr;   r   r   appendnrexclZadd_atom_parse_atoms_parse_bondsrX   ra   
bond_typeslist_parse_pairsadjustsadjust_types_parse_anglesrb   urey_bradleysangle_typesr   urey_bradley_types_parse_dihedrals_parse_cmapsrd   titlelenwarningswarnr   unknown_functionalcombining_ruler5   rZ   _parse_settlesextendclaim_parse_vsites3KeyErrorZexclude_parse_atomtypes
atom_typesu	kilojouleconversion_factor_tokilocalorienbfix_typesZ	add_nbfix_parse_bondtypes_parse_angletypes_parse_dihedraltypestuplereverseddihedral_typesr!   improper_typesimproper_periodic_typesrb_torsion_types_parse_cmaptypes
cmap_types_parse_pairtypes
pair_typesZincluded_files_any_atoms_farther_thanZitpsr~   )7rC   r|   r}   r~   gmxparamsre   r   r   ub_typesr   	exc_typesZstructure_contentsZmolnamesZproper_multiterm_dihedralsro   Zcurrent_sectionrp   Zmolnamer   bond	bond_typenbenbetangubangtubtr   wordsnamenumZbndsZbndtsbZbtrX   aattypetypa1a2sigepstcutkeyZkndreplaceZrkeya3a4a5ZitplistrD   )r   rE   rx     sb   
 






































 







zGromacsTopologyFile.readc       	      C   s   |  }y|j|d  }W n tk
r2   d}Y nX t|dk r`|dk	rV|j}|j}qd}d}n2t|d }|dk	r|jdkr|j}ntt| }t|dkrt|d nd}|dkrt	|d |d |d	}nt
||d |d ||d
}||d t|d fS )z7 Parses an atom line. Returns an Atom, resname, resnum r4   N   r      r      rI   )r   typecharge)atomic_numberr   r   r   massr9   r6   )r   r   r   r   r   r   r=   r-   r,   r   r   r;   )	rC   rp   r   r   r   r   r   r   atomrD   rD   rE   r     s*    

z GromacsTopologyFile._parse_atomsc             C   s   |  }t|d d t|d d  }}t|d }|dkrPtdt d| _t|| || }||_d}	t|dkr|dkrdd	 |d
d D \}
}|
|f|kr||
|f |_	n6t
|tj tjd  d |
tj }	|	 ||
|f< |_	||	fS )z3 Parses a bond line. Returns a Bond, BondType/None r   r4   r6   z#bond funct != 1; unknown functionalTNrH   c             s   s   | ]}t |V  qd S )N)r=   )r   r   rD   rD   rE   r     s    z3GromacsTopologyFile._parse_bonds.<locals>.<genexpr>r9   )r   r;   r   r   r   r   r   functr   r   r   r   kilojoule_per_mole	nanometer)rC   rp   r   rX   r   ijr   r   r   reqkrD   rD   rE   r     s&    "z GromacsTopologyFile._parse_bondsc             C   s   |  }t|d d t|d d  }}t|d }|dkrPtdt d| _t|| || }||_d}	|dkrt|dkrt	|d d	 }
t	|d
 }|
|f|kr||
|f |_
n.t|
tj |tj | jj}	|	 ||
|f< |_
||	fS )z> Parses a pairs line. Returns NonbondedException, NEType/None r   r4   r6   z$pairs funct != 1; unknown functionalTNrH   r9   gÚ?rI   )r   r;   r   r   r   r   r   r   r   r=   r   r*   r   
nanometerskilojoules_per_molerZ   rB   )rC   rp   r   rX   r   r   r   r   r   r   r   r   rD   rD   rE   r     s&    "
z GromacsTopologyFile._parse_pairsc             C   s  |  }dd |dd D \}}}t|d }	|	dkrJtdt d| _d }
 }}t|| || || }|	|_|	dkrt|| || }|	d	krt	|d
ks|	dkr&t	|dkr&dd |dd
 D \}}||f|kr|||f |_
n6t|tj tjd  d |tj }
|
 |||f< |_
|	dkrt	|dkrdd |d
d D \}}|dkr||f|kr|||f |_
n6t|tj tjd  d |tj }| |||f< |_
nt|_
|||
|fS )z9 Parse an angles line, Returns Angle, UB/None, and types c             S   s   g | ]}t |d  qS )r4   )r;   )r   r   rD   rD   rE   r   !  s    z5GromacsTopologyFile._parse_angles.<locals>.<listcomp>Nr9   )r4   rH   z*angles funct != 1 or 5; unknown functionalTrH   r4   r   r   c             s   s   | ]}t |V  qd S )N)r=   )r   r   rD   rD   rE   r   -  s    z4GromacsTopologyFile._parse_angles.<locals>.<genexpr>rI   r6   c             s   s   | ]}t |V  qd S )N)r=   )r   r   rD   rD   rE   r   5  s    r   )r   r;   r   r   r   r   r   r   r'   r   r   r   r   r   radiandegreer   r   r   )rC   rp   r   r   rX   r   r   r   r   r   r   r   r   r   theteqZubreqZubkrD   rD   rE   r     s<    ,
z!GromacsTopologyFile._parse_anglesc             C   s:  |  }dd |dd D \}}}}	t|d }
|
dksN|
dkrt|dk r| ||j||||	||
dk\}}|j| |dk	r|j| |j|_n|
dkr| 	|||||	|j|\}}|j
| |dk	r|j| |j|_n:|
d	kr>| |||||	|j|\}}|j| |dk	r&|j| |j|_n|
dkr|j| |j| |j| |j|	 f}||kr|| }| || d}nPt| }| |}| |_ ||< |tt|< |j| |j| |j|_nDtd
t t|j| |j| |j| |j|	 }|j| d| _|dk	r6|
|_dS )z* Processes a dihedrals line, returns None c             S   s   g | ]}t |d  qS )r4   )r;   )r   r   rD   rD   rE   r   F  s    z8GromacsTopologyFile._parse_dihedrals.<locals>.<listcomp>NrI   )r4   rI   	   r   r6   r9   z3torsions funct != 1, 2, 3, 4, 9; unknown functionalT)r   r;   r   _process_normal_dihedralrX   rc   r   r   r   _process_improper	impropersr   _process_rbtorsionrb_torsionsr   _process_dihedral_seriesr   r   r   r   r   r   r   r   r   )rC   rp   r   ZPMDr   r   r   r   r   lr   dihdihtimptrbtr   rD   rD   rE   r   C  s\    








z$GromacsTopologyFile._parse_dihedralsc             C   s|   |  }dd |dd D \}}}}}t|d }	|	dkrNtdt d| _t|| || || || || }
|	|
_|
S )z! Parses cmap terms, returns cmap c             s   s   | ]}t |d  V  qdS )r4   N)r;   )r   r   rD   rD   rE   r   |  s    z3GromacsTopologyFile._parse_cmaps.<locals>.<genexpr>NrH   r4   z#cmap funct != 1; unknown functionalT)r   r;   r   r   r   r   r   r   )rC   rp   rX   r   r   r   r   r   mr   r   rD   rD   rE   r   y  s     $z GromacsTopologyFile._parse_cmapsc             C   s  t dd |D }|dkr&td| y&dd |D \}dd |D \}}W n tk
rh   tdY nX y&| \}}}	}
t|	t|
 }	}
W n tk
r   tdY nX tj}td	tj |d
  |	| }td	tj |d
  |
| }t	|||t	|||t	|||g||gfS )z? Parses settles line; returns list of Bonds, list of BondTypes c             S   s   g | ]}t |ts|qS rD   )ry   r   )r   r   rD   rD   rE   r     s    z6GromacsTopologyFile._parse_settles.<locals>.<listcomp>r9   z Cannot SETTLE a %d-atom moleculec             S   s   g | ]}|j d kr|qS )r   )r   )r   r   rD   rD   rE   r     s    c             S   s   g | ]}|j d kr|qS )r4   )r   )r   r   rD   rD   rE   r     s    z"Can only SETTLE water; wrong atomszBad [ settles ] lineg    Ar6   )
r   r   r<   r   r=   r   r   r   r   r   )rC   rp   rX   Znatomsoxyhyd1hyd2r   r   dohdhhZnmZbt_ohZbt_hhrD   rD   rE   r     s$    z"GromacsTopologyFile._parse_settlesc                s*  |  } t|d d  } fdd|dd D }t|d }|dkr~t|d t|d  }}	t||	 tkrtdntd	|d }
||
jkrtd
t }x||
jD ]r}|d |krt	|
t	|d f}|j
p|j| j|d< |d |krt	|jt	|jf}|j
p|j| j|d< qW x|
jD ]l}|
|jk	r@q,|d |ks,|d |kr`q,t	|jt	|jt	|jf}|j
p|j| j|d< P q,W xN|d jD ]@}|d |krt	|jt	|jf}|j
p|j| j|d< qW tj|
|d |d ||	f|}td|tj }t||
||fS )z3 Parse vsites3/dummy3 line; returns Bond, BondType r   r4   c                s   g | ]} t |d   qS )r4   )r;   )r   r   )	all_atomsrD   rE   r     s    z6GromacsTopologyFile._parse_vsites3.<locals>.<listcomp>rI   rH   r   z&No vsite frames with different weightsz&Only 3-point vsite type 1 is supportedz(Unexpected bond b/w vsite and its parentZdp1r6   Zdp2r   Zd12)r   r;   r=   absr   r   bond_partnersr   ra   _gettyper   r   r   atom1atom2rb   atom3r   r   r%   Zfrom_weightsr   r   	angstromsr   )rC   rp   r
  r   r   ZvsiterX   r   r   r   parentZkwsr   r   angleZbondlenZbt_vsrD   )r
  rE   r     sJ    

  z"GromacsTopologyFile._parse_vsites3c             C   sF  |  }|d }t|d dkr>|d tkr>d}d}d}d}nxt|d dkrx|d tkrxd}d}t|d	 }|d }n>d	}d}yt|d }d}W n  tk
r   |d }d}Y nX t|| }|dkr|dkrtt| }t||d  }	t|| tj	 }
t||d  tj
 }t|d||||	d
}|||
d d	  ||fS )z; Parses line from atomtypes section, returns str, AtomType r   r9   r4   r   rI   NrH   r   r6   )r   r   gÚ?)r   r   r	   r;   r<   r=   r-   r,   r   r   r   r&   Zset_lj_params)rC   rp   r   r   ZatnumZsigidxZmassidxr   r   Zchgr   r   r   rD   rD   rE   r     s:    

z$GromacsTopologyFile._parse_atomtypesc             C   sp   |  }t|d tj }t|d d tjtjd   }|d dkrXtdt d| _|d |d t	||fS )	z2 Parse bondtypes line. Returns str, str, BondType r9   rI   r6   r   z(bondtypes funct != 1; unknown functionalTr   r4   )
r   r=   r   r   r   r   r   r   r   r   )rC   rp   r   rr   rD   rD   rE   r     s     z$GromacsTopologyFile._parse_bondtypesc             C   s   |  }t|d tj }t|d d tjtjd   }|d dkrd|d dkrdtdt d| _	d	}|d dkrt|d
 }t|d d }|dkrt
}n(|tj9 }|tjtjd  9 }t||}|d |d |d t|||fS )zY
        Parses angletypes line. Returns str, str, str, AngleType, BondType/None
        rI   rH   r6   r9   r   5z.angletypes funct != 1 or 5; unknown functionalTNr   r   r   r4   )r   r=   r   degreesr   radiansr   r   r   r   r   r   r   r   )rC   rp   r   thetar   r   Zub0ZcubrD   rD   rE   r     s"     

z%GromacsTopologyFile._parse_angletypesc          
   C   s  |  }d}d}|d dkr:d }}|dd \}}d}	n|dd \}}}}d}	d}
||	 dk}||	 d	k}
||	 d
krd}n0||	 dkrd}n||	 dkrtdt d| _|dkr$t||	d  tj }t||	d  tj }t	||	d  }t
|||d| jj d| jj d}|
rd}n|dkrt||	d  tj }t||	d  tj tjd  d }t||||g\}}}}t||}np|dkr|dd \}}}}dd ||	d |	d  D \}}}}}}t||||||d| jj d| jj d}||||f|||fS )zA Parse dihedraltypes, returns (str,str,str,str), str, Type, bool Fr   r6   )	r   2r   4r  89Z10Z11XNrI   )r   r  r   r  r  r  r   r   r   )r   r  r  z!dihedraltypes funct not supportedTr4   r9   )sceescnbr   c             s   s   | ]}t |tj V  qd S )N)r=   r   r   )r   r   rD   rD   rE   r   H  s   z;GromacsTopologyFile._parse_dihedraltypes.<locals>.<genexpr>r   )r   r   r   r   r   r=   r   r  r   r;   r    rZ   rB   rA   r  sortedr"   r$   )rC   rp   r   r   Zdtyper   r   r   r   Zsir   phasephi_kperZptyper  r   c0c1c2c3c4c5rD   rD   rE   r     sR    


$
$
z(GromacsTopologyFile._parse_dihedraltypesc             C   s   |  }|d d \}}}}}t|d t|d  }}	dd |dd  D tj }
t|
||	 krltd||	kr|td|||||t||
fS )	NrH   r   r   c             S   s   g | ]}t |qS rD   )r=   )r   r   rD   rD   rE   r   T  s    z8GromacsTopologyFile._parse_cmaptypes.<locals>.<listcomp>r   z,CMAP grid dimensions do not match resolutionzOnly square CMAPs are supported)r   r;   r   r   r   r   r#   )rC   rp   r   r   r   r   r   r   Zres1res2gridrD   rD   rE   r   O  s    z$GromacsTopologyFile._parse_cmaptypesc             C   s`   |  }|d d \}}dd |dd D \}}|tjd 9 }|tj9 }||t||| jjfS )Nr6   c             s   s   | ]}t |V  qd S )N)r=   )r   r   rD   rD   rE   r   _  s    z7GromacsTopologyFile._parse_pairtypes.<locals>.<genexpr>r9   rH   gÚ?)r   r   r   r   r*   rZ   rB   )rC   rp   r   r   r   Zcs6Zcs12rD   rD   rE   r   [  s    
z$GromacsTopologyFile._parse_pairtypesc	             C   s   t || || || || |d}	d }
t|dkrdd |dd D \}}}|||f|krn||||f |	_nBt|tj ||tj d| jj d| jj	 d}
|
 ||||f< |	_|	|
fS )N)r   r   c             s   s   | ]}t |V  qd S )N)r=   )r   r   rD   rD   rE   r   m  s    z?GromacsTopologyFile._process_normal_dihedral.<locals>.<genexpr>rH   r4   )r  r  )
r   r   r   r    r   r   r  rZ   rB   rA   )rC   r   rX   r   r   r   r   r   impr   r  r!  r"  r#  rD   rD   rE   r   h  s    "


z,GromacsTopologyFile._process_normal_dihedralc             C   s   dd |dd D \}}}t |tj ||tj d| jj d| jj d}|d k	rb|| d }n>t |tj ||tj d| jj d| jj d}t }|| |S )Nc             s   s   | ]}t |V  qd S )N)r=   )r   r   rD   rD   rE   r   y  s    z?GromacsTopologyFile._process_dihedral_series.<locals>.<genexpr>rH   r   r4   )r  r  )	r    r   r   r  rZ   rB   rA   r   r!   )rC   r   Zdihtyper!  r"  r#  dtZdtlrD   rD   rE   r   x  s    







z,GromacsTopologyFile._process_dihedral_seriesc             C   s   t || || || || }d}	t|dkrdd |dd D \}
}|
|f|krd||
|f |_n6t|tj tjd  d |
tj }	|	 |_||
|f< ||	fS )z7 Processes an improper, returns Improper, ImproperType Nr   c             s   s   | ]}t |V  qd S )N)r=   )r   r   rD   rD   rE   r     s    z8GromacsTopologyFile._process_improper.<locals>.<genexpr>rH   r6   )r   r   r   r"   r   r   r   r   )rC   r   r   r   r   r   rX   r   r,  r  ZpsieqrD   rD   rE   r     s    z%GromacsTopologyFile._process_improperc          
   C   s   t || || || || }d }	t|dkrdd |dd D \}
}}}}}|
|||||f|kr|||
|||||f |_n`tj}t|
| || || || || || d| jj d| jj d}	|	 ||
|||||f< |_||	fS )N   c             s   s   | ]}t |V  qd S )N)r=   )r   r   rD   rD   rE   r     s    z9GromacsTopologyFile._process_rbtorsion.<locals>.<genexpr>rH   r4   )r  r  )	r   r   r   r   r   r$   rZ   rB   rA   )rC   r   r   r   r   r   rX   r   rbr  r$  r%  r&  r'  r(  r)  ZkjpmrD   rD   rE   r     s    "
z&GromacsTopologyFile._process_rbtorsionc          
   C   sj	  | j dkrtdt| j }dd }x| jD ]}|j|j |_q.W t }x\| jD ]P}|j	|j
krz||j
|j	f n||j	|j
f |jdk	rqTt|j	t|j
f}||jkr|j| |_d|j_qT| jjdkr| jdkstd| jd	kr&t|j	j|j
j }t|j	j|j
j }n6| jd
kr\t|j	j|j
j }d|j	j|j
j  }|| jj9 }t|d || jj| jd}	| j|	 |	|_d|j_qTtdqTW ||j| j t }
x| jD ]}x|j	jD ]}xx|j
jD ]l}tt||j	|j
|gdk rq||jks||j kr$q||kr>|
||f n|
||f qW qW |jdk	rhqt|j	t|j
f}||j!kr|j!| |_d|j_ntdqW t|
| dkr$tddd| jd}| j| d}x2|
| D ]&\}}| jt"||| |d7 }qW t#$d| t% t||
 dkrNt#$dt||
  t% ||j!| j! xf| j&D ]\}|jdk	rxqdt|j	t|j
t|j'f}||j(kr|j(| |_d|j_ntdqdW ||j(| j( x^| j)D ]T}|jdk	rqt*|}||j+kr$|j+| |_|jt,k	r,d|j_ntdqW x6t-t.t| j)D ] }| j)| jt,krF| j)|= qFW ||j+| j+ x| j/D ]}|jdk	rqt|j	t|j
t|j't|j0f}|j1sdt|j
t|j'df}t|j	t|j
t|j'df}dt|j
t|j't|j0f}||j2kr:|j2| |_d|j_nn||j2kr\|j2| |_d|j_nL||j2kr~|j2| |_d|j_n*||j2kr|j2| |_d|j_ntdn||j3kr|j3| |_d|j_nx|d |d |d dfd|d |d |d f|d |d ddfdd|d |d fgD ](}||j3kr"|j3| |_d|j_P q"W tdqW ||j2| j2 ||j3| j2 x*| j4D ]}|jdk	rqt|j	t|j
t|j't|j0f}dt|j
t|j'df}t|j	t|j
t|j'df}dt|j
t|j't|j0f}||j5kr2|j5| |_d|j_nn||j5krT|j5| |_d|j_nL||j5krv|j5| |_d|j_n*||j5kr|j5| |_d|j_ntdqW ||j5| j5 | 6  x| j7D ]}|jdk	rؐqt8t9t|j	t|j
t|j't|j0g}||j:kr(|j:| |_d|j_qxnt|j
t|j't|j0fD ]F}t8t9t|j	|ddg}||j:krtqF|j:| |_d|j_P qFW tdqW ||j:| j: x| j;D ]}|jdk	rȐqt|j	t|j
t|j't|j0t|j<f}|d |d |d |d |d |d |d |d f}||j=k	rJ|j=| |_d|j_ntdqW ||j=| j= dS ) zj
        Assign parameters to the current structure. This should be called
        *after* `read`
        Nzparametrize called before readc             S   sb   t dd |D }xBt| D ]6\}}|js,qt||kr:q|t| || qW |  d S )Nc             s   s   | ]}t |V  qd S )N)id)r   r   rD   rD   rE   r     s    zPGromacsTopologyFile.parametrize.<locals>.update_typelist_from.<locals>.<genexpr>)setr2   usedr0  addr   r   )ZptypestypesZadded_typesr   r   rD   rD   rE   update_typelist_from  s      z=GromacsTopologyFile.parametrize.<locals>.update_typelist_fromTr:   )r   lorentzzUnrecognized combining ruler   r6  g      ?gÚ?)r   z$Not all pair parameters can be foundrI   zNot all bond parameters foundr   g        r4   zp%i 1-4 pairs were missing from the [ pairs ] section and were set to zero; make sure you know what you're doing!ziThe [ pairs ] section contains %i exceptions that aren't 1-4 pairs; make sure you know what you're doing!zNot all angle parameters foundz%Not all urey-bradley parameters foundr  z Not all torsion parameters foundr6   r9   z)Not all improper torsion parameters foundz$Not all R-B torsion parameters foundz!Not all improper parameters foundzNot all cmap parameters found)>rw   RuntimeErrorcopyrX   r   r   	atom_typer1  r   r  r  r3  r  r   r2  rZ   r@   r   AssertionErrormathsqrtepsilonsigmarA   r*   rB   r   r   r   ra   r  r   angle_partnersr   r   r   r   r   rb   r  r   r   r   r   r   r   r3   rc   atom4r   r   r   r   r   update_dihedral_exclusionsr   r   r   r   rd   atom5r   )rC   r   r5  r   Zgmx_pairZpairr   r   r   ZpairtypeZtrue_14r   ZbpiZbpjZzero_pairtypeZnum_zero_14r   r   r  r   r   r   ZwckeyZwckey1Zwckey2Zanchorr   rD   rD   rE   r~     sp   


 




 

 
 
 





 



   4
zGromacsTopologyFile.parametrizeFc                s$   t t| ||}t| j|_|S )a  
        Makes a copy of the current structure as an instance of a specified
        subclass

        Parameters
        ----------
        cls : Structure subclass
            The returned object is a copy of this structure as a `cls` instance
        split_dihedrals : ``bool``
            If True, then the Dihedral entries will be split up so that each one
            is paired with a single DihedralType (rather than a
            DihedralTypeList)

        Returns
        -------
        *cls* instance
            The instance of the Structure subclass `cls` with a copy of the
            current Structure's topology information
        )rv   rU   r8  rZ   )rC   clsZsplit_dihedralsr   )r   rD   rE   r8    s    zGromacsTopologyFile.copyc                s0   t t| |}t|tr|S t| j|_|S )z- See Structure.__getitem__ for documentation )rv   rU   rL   ry   r   r8  rZ   )rC   Z	selectionstruct)r   rD   rE   rL     s
    
zGromacsTopologyFile.__getitem__c       
      C   s  ddl m } |  }|r&||}|  |j|_|j|_|j|_|j|_|j|_|j|_|j|_|j	|_	|j
|_
|j|_|j|_|j|_|j|_|j|_|j|_|j|_|j|_|j|_|j|_|j|_|j|_|js|js|js|js|js|js|jrtdt|dr(t |j!t"r(|j!|_!nt# }t# }|jrzx2|jD ](}|j$dkrXqD|%d|j$j&  qDW d|j!_'nx|jD ]}|j$dks|j(rqt |j$t)rxj|j$D ].}	|	j*r|%|	j* |	j+r|%|	j+ qW n0|j$j*r |%|j$j* |j$j+r|%|j$j+ qW t,t#dd	 |D dkrBt-d
t.|}t.|}t,t#dd	 |D dkrd|d  |j!_/nd|j!_/t,t#dd	 |D dkrd|d  |j!_0nd|j!_0|jdkrd|j!_1t2j3|dd|_4|S )a   Instantiates a GromacsTopologyFile instance from a Structure

        Parameters
        ----------
        struct : :class:`parmed.Structure`
            The input structure to generate from
        copy : bool, optional
            If True, assign from a *copy* of ``struct`` (this is a lot slower).
            Default is False

        Returns
        -------
        gmxtop : :class:`GromacsTopologyFile`
            The topology file defined by the given struct
        r   )r8  z.GromacsTopologyFile does not support Amoeba FFrZ   Nr4   r7   c             s   s   | ]}d | V  qdS )z%.5fNrD   )r   r   rD   rD   rE   r     s    z5GromacsTopologyFile.from_structure.<locals>.<genexpr>zAStructure has mixed 1-4 scaling which is not supported by Gromacsc             s   s   | ]}d | V  qdS )z%.5fNrD   )r   r   rD   rD   rE   r     s    g      ?c             s   s   | ]}d | V  qdS )z%.5fNrD   )r   r   rD   rD   rE   r     s    r   r9   T)allow_unequal_duplicates)5r8  Zjoin_dihedralsrX   residuesra   rb   rc   r   rd   r   r   r   r   r   r   r   r   r   r   r   r   rt   r   Ztrigonal_anglesZout_of_plane_bendsZpi_torsionsZstretch_bendsZtorsion_torsionsZchiral_framesZmultipole_framesr{   rz   ry   rZ   r5   r1  r   r3  Zchgscaler@   
ignore_endr!   r  r  r   r   r   rB   rA   r?   r   from_structurerw   )
rC  rD  r8  Z_copyZgmxtopZscee_valuesZscnb_valuesadjustZdihedralr-  rD   rD   rE   rH    s     
 


z"GromacsTopologyFile.from_structureinlinec       B         s(  ddl m} ddlm} d}d}	tj| dd}
t|trPd| }	t|d	}d}nt	|d
sbt
dd}d}|dkrx|}nHt|tr||	 kr|}qd}t|d	}|}nt	|d
r|}ntd|rd}d}d}|dkr|}nRt|tr||	 kr|}nd}t|d	}|}n t	|d
r(|}|j}ntd|dk	rt|tr^| dkrtdnVg }xP|D ]Htttfddttd D rtd| qhW z@t }|d|	ttt|dtjtj d d |tjtj d d |j!d"tj #d$df
  |sh|d |d |d| j%j&| j%j'| j%j(| j%j)| j%j*f  |dk	r|d|  |s|d tdd t+|
j,D rd}nd}t-d d t+|
j,D rd}nd}|d! |r|d" |r|d# |d$ t.j/0t.j1}xxt+|
j,D ]j\}}|d%|  |rR|d&|j2  |rh|d'|j3  |d(|j4|j5|j6d) |j7| f  q&W |d* |sT| 8 rTt9| j:j;}| j:j,< }|d+ t.j=0t.j>}xt|? D ]h\}}|d |kr|d |kr|d }|d }||9 }|d,9 }|d-@|d |d |d. | qW |	s<|dk	r<|
jAr$|d/ |d0 t }t.j=t.jBd1  0t.j>t.jCd1  d1  xlt+|
jAD ]^\}||krΐq|D| |DtEtF| |d2|d |d jGd) jH  f  qW |d* |
jIr| j%j(d3kr|d4 |d5 t.j=0t.j>}t.jB0t.jC}t }xlt+|
jID ]^\}||krq||D| |DtEtF| |d6|d |d j6| j7| f  q|W |d* |
jJr&|d7 |d8 t }t.j=t.jKd1  0t.j>t.jKd1  d1  t.j=t.jBd1  0t.j>t.jCd1  d1 } xt+|
jJD ]\}||krxqb|D| |DtEtF| d9|d |d |d1 jLjH  f }!||
jMkr|
jM| }"||!d:  |d;d,|"jG |"jH|  f  n||!d  |d* qbW |d* |
jNr|d< |d= t }t.j/0t.j1 d>}#xt+|
jND ]\}||kr|qf|D| |DtEtF| xJD ]B}$||#|d |d |d1 |d? d@|$jO|$jP  tQ|$jRf  qW qfW |d* |
jSr|d< |d= t }t.j10t.j/ d>}#x~t+|
jSD ]p\}||krJq4|D| |DtEtF| ||#|d |d |d1 |d? dAjOjP  tQjRf  q4W |d* |
jT	r<|d< |dB dC}#t.j/0t.j1d1  xLt+|
jTD ]>\}||#|d |d |d1 |d? d1jUjV  f  qW |d* |
sL|
jW
rL|dD t }t.j/0t.j1 xt+|
jWD ]\}||k	r	qt|D| |DtEtF| |dE|d |d |d1 |d? |dF jXjXf  jXjX }%xTtd|%d)D ]D}&|dG tY|&d) |%}'|d" fdHdt|&|'D  	qW |dI 	qtW |dk	
rd|d|  |dkr|  }(d})g }*t }+x|(D ]\},}-t|,jZdk
r|,jZd j}.|.|+k
r|.}/d1}0x6|.|+k
rdJ|/|0f }.|0d7 }0
qW ndK|) }.|)d7 })|*|. |+D|. t[\|,||.|
|dk 
qW |s|dL | j]rN|| j] n
|dM |dI |dN t^dOd |(D }1d}&x|&|1k rx2t_|(D ]\}2\},}3|&|3krP qW t`dP|& |&}4x"|4|1k r|4|3kr|4d7 }4qW |dQ|*|2 |4|& f  |4}&qW nt|tr| dkrt[\| |dR|
|dk |s|dL | j]rh|| j] n
|dM |dI |dN |dQdS  n\|  }(t^dTd |(D }5t9 }6x*|(D ]"\}7}-x|-D ]}&|7|6|&< qW qW g }8xp|D ]f}9tatQ}:g };xr|9D ]j}<y|6|< }=W n tbk
r6   tcdUY nX |:td|6|<   d7  < |:td|6|<  dkr|;|= qW |:td|;d  dkr|;d |:td|;d   }>ntee|;d }>xxt_|;D ]l\}&}=|&dkrԐqtd|=|:kr|:td|= dkst`|:td|= dkr |>|=|:td|=  7 }>n|>|=7 }>qW |8|>|9d t|9f |5t|9d 8 }5qW |8jfdVdW dX g }?tat}:d}@d}Axt|5D ]}&|&|A }4|@t|8k r|8|@ d |4kr|?|8|@ d t|&gg |A|8|@ d1 d 7 }A|@d7 }@nft|:td|6|4  dkr@|:td|6|4  D|& |?|6|4 |:td|6|4  g n|:td|6|4  D|& qW d})g }*t }+x|?D ]\},}-t|,jZdkr|,jZd j}.|.|+kr|.}/d1}0x6|.|+krdJ|/|0f }.|0d7 }0qW ndK|) }.|)d7 })|*|. |+D|. t[\|,||.|
|dk qpW |s|dL | j]r4|| j] n
|dM |dI |dN t^dYd |?D }1d}&x|&|1k rx2t_|?D ]\}2\},}3|&|3kr~P q~W t`dP|& |&}4x"|4|1k r|4|3kr|4d7 }4qW |dQ|*|2 |4|& f  |4}&qjW W d|r|g  |r|g  |r"|g  X dS )ZaY
   Write a Gromacs Topology File from a Structure

        Parameters
        ----------
        dest : str or file-like
            The name of a file or a file object to write the Gromacs topology to
        combine : 'all', None, or list of iterables, optional
            If None, no molecules are combined into a single moleculetype. If
            'all', all molecules are combined into a single moleculetype.
            Otherwise, the list of molecule indices (start from 0) will control
            which atoms are combined into single moleculetype's. Default is None
        parameters : 'inline' or str or file-like object, optional
            This specifies where parameters should be printed. If 'inline'
            (default), the parameters are written on the same lines as the
            valence terms are defined on. Any other string is interpreted as a
            filename for an ITP that will be written to and then included at the
            top of `dest`. If it is a file-like object, parameters will be
            written there.  If parameters is the same as ``dest``, then the
            parameter types will be written to the same topologyfile.
        molfile : None or str of file-like object, optional
            If specified as other than None, the molecules will be written to a
            separate file that is included in the main topology file. The
            name of this file will be the provided srting. If None or
            the same as the ``dest'', the molecules will be written into the
            body of the topology file. If it is a file-like object,
            the molecules will be written there. Using this option can make
            it easier to combine multiple molecules into the same topology.
            This will change where the following topology sections are
            written: moleculetype, atoms, bonds, pairs, angles, dihedrals,
            cmap, settles, virtual_sites2, virtual_sites3 and exclusions.
        itp : bool, optional
            If True the following topology sections are not written:
            defaults, atomtypes, nonbond_params, bondtypes, pairtypes,
            angletypes, dihedraltypes, cmaptypes, system and molecules
            Thus only the individual molecules will be written in a stand-alone
            fashion, i.e. an itp-file.
            If True the molfile parameter will be set to None

        Raises
        ------
        ValueError if the same molecule number appears in multiple combine lists
        TypeError if the dest input cannot be parsed
        ValueError if the combine, parameters, or molfile input cannot be parsed
        r   N)__version__F T)rE  z%s r   writez,dest must be a file name or file-like objectrJ  z?parameters must be "inline", a file name, or a file-like objectz9molfile must be "top", a file name, or a file-like objectallz/combine must be None, list of indices, or "all"c             3   s&   | ]} |d    |  d kV  qdS )r4   NrD   )r   r   )indicesrD   rE   r     s   z,GromacsTopologyFile.write.<locals>.<genexpr>r4   z#Can only combine adjacent moleculesz;
;   File %s was generated
;   By user: %s (%d)
;   On host: %s
;   At date: %s
;
;   This is a standalone topology file
;
;   Created by:
;   ParmEd:       %s, VERSION %s
;   Executable:   %s
;   Library dir:  %s
;   Command line:
;     %s
;
z%a. %B  %w %X %Y Zunicode_escapezutf-8z
[ defaults ]
z@; nbfunc        comb-rule       gen-pairs       fudgeLJ fudgeQQ
z#%-15d %-15d %-15s %-12.8g %-12.8g

z#include "%s"

z[ atomtypes ]
c             s   s   | ]\}}|j d k	V  qd S )N)Z
_bond_type)r   r   r   rD   rD   rE   r     s   c             s   s   | ]\}}|j d kV  qdS )r   N)r   )r   r   r   rD   rD   rE   r     s   z
; name    z
bond_type z
at.num    z)mass    charge ptype  sigma      epsilon
z%-7s z%-8s z%8d z %10.6f  %10.8f  A %14.8g %14.8g
r   
z[ nonbond_params ]
g?z{0} {1} 1 {2} {3}
gÚ?z[ bondtypes ]
z$; i    j  func       b0          kb
r6   z%-5s %-5s    1   %.5f   %f
r7   z[ pairtypes ]
zF; i j   func    sigma1-4    epsilon1-4 ; ; THESE ARE 1-4 INTERACTIONS
z%-5s %-5s  1  %.9f %.9f
z[ angletypes ]
z<;  i    j    k  func       th0       cth    rub         kub
z'%-5s %-5s %-5s    %%d   %12.7f   %12.7frH   z  %12.7f  %12.7f
z[ dihedraltypes ]
z.;i  j   k  l  func      phase      kd      pn
z+%-6s %-6s %-6s %-6s  %d   %.2f   %.6f   %d
r9   r   rI   z/; i  j       k       l       func     q0    cq
z(%-6s %-6s %-6s %-6s    %d   %.6f   %.6f
z[ cmaptypes ]

z&%-6s %-6s %-6s %-6s %-6s   1   %4d %4dr   z\
c             3   s    | ]}t j|   V  qd S )N)strr+  )r   r   )convparamrD   rE   r   G  s   z

z%s%dzsystem%dz[ system ]
; Name
zGeneric titlez%[ molecules ]
; Compound       #mols
c             s   s   | ]}t |d  V  qdS )r4   N)r   )r   r  rD   rD   rE   r   l  s    z"Could not find molecule %d in listz
%-15s %6d
r\   )r\   r4   c             s   s   | ]}t |d  V  qdS )r4   N)r   )r   r  rD   rD   rE   r     s    zMolecule ID out of rangec             S   s   | d S )Nr4   rD   )r   rD   rD   rE   <lambda>      z+GromacsTopologyFile.write.<locals>.<lambda>)r   c             s   s   | ]}t |d  V  qdS )r4   N)r   )r   r  rD   rD   rE   r     s    )hZparmed.gromacsr   ru   rK  r   rH  ry   r1   r/   rz   r{   rj   r<   r   lowerr   r1  anyr3   r   r   r   nowrM  	_username_userid_unameZstrftimeospathr   sysargvr   joinencodedecoderZ   r>   r?   r@   rA   rB   r2   r   rN  r   kilocaloriesr   
kilojoulesr   r   r   r   r>  r=  Z	has_NBFIXr   rw   r   keysr   r   itemsformatr   angstromr   r3  r   r   r   r   r   r   r   r   r   r   r!  r"  r;   r#  r   r   psi_eqpsi_kr   Z
resolutionminrF  rU   _write_moleculer   sum	enumerater:  r   r   rJ   r0  r8  sortclose)BrC   destZcombineZ
parametersZmolfileZitpr   rK  Z
own_handler|   r   Zown_parfile_handleZinclude_parfileZparfileZown_molfile_handleZinclude_molfileZ_molfileZcombine_listsrY  Zprint_bond_typesZprint_atnumeconvr   r9  ZtypemapZtypes_in_systemZeps_conversionvalr   r   Z	used_keyslconvZbconvpartr   Zfmtr-  r*  r   endre   ZsysnumnamesZnamesetr   r   r   ZorigZsfxZ
total_molsr   ZlstZiiZnmolsZmoleculedictr  Zcombined_moleculesZclZcountsZmols_in_molZmolidZmolZcombmolZnew_moleculesZcmcr3  rD   )rS  rO  rT  rE   rM    s   -



















 


 
$



 




 





 

$



 






 




















 $









zGromacsTopologyFile.writec       -      C   s  | d | d|| jf  | d | d d}x| jD ]}| d|jd |j|jtdd	 |D f  xR|D ]J}||j7 }| d
|jd |j|jd |j|j|jd |j|j|f	  qvW q>W | d dd | j	D }d}	t
| j	t
| dkrDy.dd	 | j	D \}
dd	 | j	D \}}d}	W n tk
rB   Y nX | jrztjtjd  tjtjd  d }|	r| d | d | dd  x| jD ]}t|jtst|jtrƐq| d|jjd |jjd |jf  |jd kr| d qt|jt|jf}|s>||jks>|j|j| kr`| d|jjd |jj| f  | d qW | d | jrz| d | dd  tjtj}tjtj}x| jD ]}t|jt|jf}| d|jjd |jjd |jf  | j j!dkr\|s.||j"ks.|j|j"| kr\|jd k	r\| d|jj#| |jj$| f  | d qW | d n
| j%r| d | dd  | &  tjtj}tjtj}x| j%D ]}|j's|j(rސq|j|j) }}||j*ks||j+krq| d|jd |jd df  | j j!dkrj| dd|j,|j,  | t-.|j/|j/ | f  | d qW | d | j0r>tjtj1d  tjtj1d  d }tjtjd  tjtjd  d }| d  | d!d"  x@| j0D ]4}| d#|jjd |jjd |j2jd |jf  |jd krJ| d qt|jt|jt|j2f}|j34||jk}|jd$krx4| j5D ]&}|j|kr|j2|kr|j}P qW t6}|o|j74||k}|s|s$| d%|jj8|jj| f  |jd$kr$| d&|jd |j| f  | d qW | d | j%r$| d' | d(d)  | d tjtj}x| j%D ]}| d*|jjd |jjd |j2jd |j)jd |jf  |jd kr| d q|j(r|j9}n|j:}t|jt|jt|j2t|j)f}|s6||ks6t;|j|| r
t|jt<r| d+|jd j=|jd j>| t?|jd j@f  x|jdd  D ]T}| d,|jjd |jjd |j2jd |j)jd |j|j=|j>| t?|j@f  qW n(| d-|jj=|jj>| t?|jj@f  | d qW | d | jA	rn| d' | d(d)  | d tjtj}d.}x | jAD ]}| d*|jjd |jjd |j2jd |j)jd |jf  |jd kr| d qjt|jt|jt|j2t|j)f}|	s
||jBk	s
|jB| |jkrj| ||jjC| |jjD| |jjE| |jjF| |jjG| |jjH| f  | d qjW | d | jI
r8| d' | d/d0  | d tjtjd }x| jID ]x}| d*|jjd |jjd |j2jd |j)jd |jf  |jd k
r
| d 	q| d1|jjJ|jjK| f  	qW | d | jL
r| d2 | d3d4  xT| jLD ]J}| d5|jjd |jjd |j2jd |j)jd |jMjd |jf  
q`W |	r| d6 | d7 | d8 x8|
jD ].}||k
r|jd k
rd9n
|jjd } P 
qW x|jD ].}||kr|jd kr2d:n
|jjd }!P qW xb|
j0D ]P}"||"krN||"krN|"jj8tN }#t-.d|  |  d|  |  t-O|#  }!P qNW tPd;| d<| |!f  |rxtQd=d	 |D }$x|$D ]}%|%tRkrp| d> | d? x`|D ]X}&t|&jS|%sq|&jST \}}| d@|&jd |jd |jd d|&U d f  qW | d q|%tVtWfkr| dA | dB x|D ]}&t|&jStVr |&jST \}}}'|&jSU \}(})}*| dC|&jd |jd |jd |'jd d|)|*f  nbt|&jStWr|&jST \}}}'|&jSU \})}*}+| dD|&jd |jd |jd |'jd |)|*|+f  qW | d qW |s|	r| dE xtX| j	D ]r\},}| dF|,d   x$|j*D ]}"| dG|"jd   qW x$|j+D ]}"| dG|"jd   qW | d qW | d d S )HNz+
[ moleculetype ]
; Name            nrexcl
z%s          %d

z
[ atoms ]
z`;   nr       type  resnr residue  atom   cgnr    charge       mass  typeB    chargeB      massB
r   z; residue %4d %s rtp %s q %.1f
r4   c             s   s   | ]}|j V  qd S )N)r   )r   r   rD   rD   rE   r     s    z6GromacsTopologyFile._write_molecule.<locals>.<genexpr>z5%5d %10s %6d %6s %6s %6d %10.8f %10.6f   ; qtot %.6f
rQ  c             S   s   g | ]}t |tr|qS rD   )ry   r   )r   r   rD   rD   rE   r     s    z7GromacsTopologyFile._write_molecule.<locals>.<listcomp>Fr9   c             s   s   | ]}|j d kr|V  qdS )r   N)r   )r   r   rD   rD   rE   r     s    c             s   s   | ]}|j d kr|V  qdS )r4   N)r   )r   r   rD   rD   rE   r     s    Tr6   z#ifdef FLEXIBLE

z
[ bonds ]
z!;%6s %6s %5s %10s %10s %10s %10s
)aiajr   r$  r%  r&  r'  z%7d %6d %5dz
   %.5f %fr   z
[ pairs ]
r7   z
 %.9f %.9fz  %.9f  %.9fg      ?z[ angles ]
z%;%6s %6s %6s %5s %10s %10s %10s %10s
)ry  rz  akr   r$  r%  r&  r'  z%7d %6d %6d %5drH   z
   %.7f %fz %.7f %fz[ dihedrals ]
z2;%6s %6s %6s %6s %5s %10s %10s %10s %10s %10s %10s)ry  rz  r{  alr   r$  r%  r&  r'  r(  r)  z%7d %6d %6d %6d %5dz  %.6f  %.6f  %dz$
%7d %6d %6d %6d %5d  %.5f  %.7f  %dz  %.7f  %.7f  %dz0  %12.7f  %12.7f  %12.7f  %12.7f  %12.7f  %12.7fz(;%6s %6s %6s %6s %5s %10s %10s %10s %10s)	ry  rz  r{  r|  r   r$  r%  r&  r'  z  %12.7f  %12.7f
z	[ cmap ]
z;%6s %6s %6s %6s %6s %5s
)ry  rz  r{  r|  Zamr   z%7d %6d %6d %6d %6d %5d
z
#else

z[ settles ]
z; i     funct   doh     dhh
g?gx]`?z Cannot determine SETTLE geometryz1     1   %.8f   %.8f

#endif

c             s   s   | ]}t |jV  qd S )N)r   
frame_type)r   r   rD   rD   rE   r     s    z[ virtual_sites2 ]
z; Site  from    funct  a
z%-5d %-4d %-4d %-4d   %.6f
z[ virtual_sites3 ]
z%; Site  from                   funct
z&%-5d %-4d %-4d %-4d %-4d   %.6f  %.6f
z,%-5d %-4d %-4d %-4d %-4d   %.6f  %.6f  %.6f
z[ exclusions ]
z%dz  %d)YrM  r   rF  rK   r   rn  r   r   r   rX   r   r<   ra   r   Zkilocalorie_per_moleri  r   r   r   ry   r  r   r  r   r  r   r   r   r   rd  re  r  rZ   r@   r   r>  r=  rc   rA  rG  r   r@  r  r?  Zsigma_14r;  r<  Z
epsilon_14rb   r   r  r   getr   r   r   r   r   r   _diff_dihedsr!   r!  r"  r;   r#  r   r   r$  r%  r&  r'  r(  r)  r   rj  rk  rd   rB  r   Zcosr   r1  r(   r}  Z	get_atomsZget_weightsr%   r)   ro  )-rD  rr  r   r   ZwriteparamsZrunchgZresiduer   ZEPsZsettler  r  r  rS  r   r   rs  ru  rI  Zdihedr   r   Zconv2r  Zparam_equalr   ZubtypeZtypedictr-  Zparamfmtr   r   r  r	  r   r   ZftypesZftypeZEPr   ZjunkZw1Zw2Zw3r   rD   rD   rE   rm    s   




"


&
"

&"
  





 
$













&




(



 



 
z#GromacsTopologyFile._write_moleculec             C   s"   t | }| j|d< | j|d< |S )Nrw   rZ   )r   __getstate__rw   rZ   )rC   drD   rD   rE   r    s    


z GromacsTopologyFile.__getstate__c             C   s$   t | | |d | _|d | _d S )Nrw   rZ   )r   __setstate__rw   rZ   )rC   r  rD   rD   rE   r    s    
z GromacsTopologyFile.__setstate__)NNTNN)NT)N)F)F)NrJ  NF)$rQ   rR   rS   rT   staticmethodrq   rF   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r~   r8  rL   classmethodrH  rM  rm  r  r  __classcell__rD   rD   )r   rE   rU      sN   !( 
 C%6+01
 \h
   g  rU   r9   c                s   ddl }t| j d krdS |t|  d  xN| jD ]D}x| jD ]} d |_qJW t|d t fdd| jD r>dS q>W dS )a  
    This function checks to see if there are any atom pairs farther away in the
    bond graph than the desired limit

    Parameters
    ----------
    structure : :class:`Structure`
        The structure to search through
    limit : int, optional
        The most number of bonds away to check for. Default is 3

    Returns
    -------
    within : bool
        True if any atoms are *more* than ``limit`` bonds away from any other
        atom
    r   Nr4   Fc             3   s   | ]}|j  kV  qd S )N)marked)r   r   )limitrD   rE   r   5  s    z*_any_atoms_farther_than.<locals>.<genexpr>T)	r_  r   rX   setrecursionlimitmaxgetrecursionlimitr  _mark_graphrX  )Z	structurer  r_  r   rD   )r  rE   r     s      
r   c             C   s4   || _ x(| jD ]}|j |krqt||d  qW dS )aS   Marks all atoms in the graph listing the minimum number of bonds each
    atom is away from the current atom

    Parameters
    ----------
    atom : :class:`Atom`
        The current atom to evaluate in the bond graph
    num : int
        The current depth in our search
    limit : int
        The maximum depth we want to search
    r4   N)r  r  r  )r   r   r   rD   rD   rE   r  9  s
    
 r  c             C   sP   t | t |kr| |krdS t|trLt| trLt|dkrL|d | krLdS dS )a   Determine if 2 dihedrals are *really* different. dt1 can either be a
    DihedralType or a DihedralTypeList or dt1 can be a DihedralType and dt2 can
    be a DihedralTypeList.  This returns True if dt1 == dt2 *or* dt1 is equal to
    the only element of dt2
    Fr4   r   T)r   ry   r!   r    r   )Zdt1Zdt2rD   rD   rE   r  K  s     r  c             C   s   | j d tfkr| j jS | jS )N)r9  r+   r   r   )r   rD   rD   rE   r  W  s    r  )r9   )`rT   Z
__future__r   r   r   collectionsr   r   
contextlibr   r8  r   r;  r]  restringr	   ImportErrorr
   r_  r   Zparmed.constantsr   r   Zparmed.exceptionsr   r   r   Zparmed.formats.registryr   Zparmed.parametersr   r   Zparmed.gromacs._gromacsfiler   Zparmed.structurer   Zparmed.topologyobjectsr   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   Zparmed.periodic_tabler,   r-   ru   r.   r   Zparmed.utils.ior/   Zparmed.utils.sixr0   r1   r2   Zparmed.utils.six.movesr3   pwdgetpwuidgetuidrZ  r   r[  unamer\  ZgetpassZgetuserplatformZnodecompilerk   objectr5   rU   r   r  r  r  rD   rD   rD   rE   <module>   s~   d
.
C               
