B
    b                 @   s\  d Z ddlmZmZmZ ddlZddl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 dd	lmZmZ dd
lmZmZ ddlmZ ddlmZ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%m&Z& ddl'm(Z( ddl)m*Z*m+Z+m,Z, ddl-m.Z. ddl/m0Z0m1Z1 e2dZ3G dd de4Z5dd Z6G dd de4Z7G dd dee7Z8dd Z9dS )z
This module contains classes for parsing and processing CHARMM parameter,
topology, and stream files.

Author: Jason M. Swails
Contributors:
Date: Mar. 26, 2017
    )absolute_importdivisionprint_functionN)copy)OrderedDict)combinations   )TINY)CharmmErrorParameterWarning)PatchTemplateResidueTemplate)ParameterSet)	AtomicNumelement_by_mass)	AngleTypeAtomAtomTypeBondTypeCmapTypeDihedralTypeDihedralTypeListImproperTypeNoUreyBradley	DrudeAtomDrudeAnisotropy)genopen)integer_types	iteritemsstring_types)zip   )
CharmmFileCharmmStreamFilezpenalty\s*=\s*([\d\.]+)c               @   s    e Zd ZdZdd Zdd ZdS )_EmptyStringIteratorz Always yields an empty string c             c   s   x
dV  qW d S )N  )selfr&   r&   7lib/python3.7/site-packages/parmed/charmm/parameters.py__iter__#   s    z_EmptyStringIterator.__iter__c             C   s   dS )Nr%   r&   )r'   idxr&   r&   r(   __getitem__&   s    z _EmptyStringIterator.__getitem__N)__name__
__module____qualname____doc__r)   r+   r&   r&   r&   r(   r$   !   s   r$   c             C   sj   t | tr| S |  | kr>| ddddddd d S d|   ddddddd d S )	N*ZSTR+P-M   z%sLTU)
isinstancer   upperreplace)namer&   r&   r(   	_typeconv)   s    
$r:   c               @   s    e Zd ZdZdd Zdd ZdS )CharmmImproperMatchingMixinz+ Implements CHARMM-style improper matching c             C   s4   |  | j||||}|dkr0|  | j||||}|S )z3 Matches an improper type based on atom type names N)_match_improper_with_typemapimproper_typesimproper_periodic_types)r'   a1a2a3a4typr&   r&   r(   match_improper_type6   s    z/CharmmImproperMatchingMixin.match_improper_typec       
      C   s"  ||||f|kr |||||f S ||||f|kr@|||||f S t t||||g}| j|d |krt|| j|  S xTt||||fdD ]>\}}}	t t|||	dg}| j|d |kr|| j|  S qW xRt||||fdD ]<\}}t t||ddg}| j|d |kr|| j|  S qW d S )N   Xr   )tuplesorted_improper_key_mapgetr   )
r'   Ztypemapr?   r@   rA   rB   keyZexact1Zexact2Zexact3r&   r&   r(   r<   =   s       z8CharmmImproperMatchingMixin._match_improper_with_typemapN)r,   r-   r.   r/   rD   r<   r&   r&   r&   r(   r;   3   s   r;   c                   s   e Zd ZdZ fddZedddZ fdd	Zed ddZ	edd Z
ed!ddZd"ddZdd Zdd Zd#ddZdd Zdd Zdd Z  ZS )$CharmmParameterSetaQ  
    Stores a parameter set defined by CHARMM files. It stores the equivalent of
    the information found in the MASS section of the CHARMM topology file
    (TOP/RTF) and all of the information in the parameter files (PAR)

    Parameters
    ----------
    *filenames : variable length arguments of str
        The list of topology, parameter, and stream files to load into the
        parameter set. The following file type suffixes are recognized:
            .rtf, .top -- Residue topology file
            .par, .prm -- Parameter file
            .str -- Stream file
            .inp -- If "par" is in the file name, it is a parameter file. If
                    "top" is in the file name, it is a topology file.
                    Otherwise, ValueError is raised.

    See Also
    --------
    :class:`parmed.parameters.ParameterSet`
    c                s   t t|  }| j|_|S )N)superrL   __copy___declared_nbrules)r'   other)	__class__r&   r(   rN   l   s    zCharmmParameterSet.__copy__r%   Nc             C   s^   y|| S  t k
rX   d||f }|dk	r8|d| 7 }|dk	rL|d| 7 }t|Y nX dS )za
        Converts a data type to a desired type, raising CharmmError if it
        fails
        zCould not convert %s to %s
Nzinput line %d
zinput line: %s
)
ValueErrorr
   )datatypemsg
line_indexliner&   r&   r(   _convertq   s    zCharmmParameterSet._convertc       
         s:  t t|   g | _d| _g g g   }}}x|D ]}|dsH|drT|| q0|dsh|drt|| q0|dr|| q0|drtj	|d }d	|kr|| qd
|kr|| qt
d| q0t
d| q0W x|D ]}| | qW x|D ]}| | qW x|D ]}	| |	 q"W d S )NFz.rtfz.topz.parz.prmz.strz.inpr!   partopzUnrecognized file type: %s)rM   rL   __init__parametersetsrO   endswithappendospathsplitrR   read_topology_fileread_parameter_fileread_stream_file)
r'   argsZtopsZparsZstrsargfnamerZ   rY   Zstrf)rQ   r&   r(   r[      s2    





zCharmmParameterSet.__init__Fc       
         s$  |  }|rdd  ndd  t   fdd}x0t|jD ]"\}}t|j|_||||j q<W x0t|jD ]"\}}t|j|_||||j qnW x0t|jD ]"\}}t|j|_||||j qW x$t|jD ]\}}	|||	|j qW x$t|jD ]\}}	|||	|j qW x&t|j	D ]\}}	|||	|j	 qW x&t|j
D ]\}}	|||	|j
 qFW x&t|jD ]\}}	|||	|j qnW x&t|jD ]\}}	|||	|j qW xDt|jD ]6\}}	t|dkstdt| |||	|j qW x&t|jD ]\}}	|||	|j qW |S )a  
        Instantiates a CharmmParameterSet from another ParameterSet (or
        subclass). The main thing this feature is responsible for is converting
        lower-case atom type names into all upper-case and decorating the name
        to ensure each atom type name is unique.

        Parameters
        ----------
        params : :class:`parmed.parameters.ParameterSet`
            ParameterSet containing the list of parameters to be converted to a
            CHARMM-compatible set
        copy : bool, optional
            If True, the returned parameter set is a deep copy of ``params``. If
            False, the returned parameter set is a shallow copy, and the
            original set may be modified if any lower-case atom type names are
            present. Default is False.

        Returns
        -------
        new_params : CharmmParameterSet
            The parameter set whose atom type names are converted to all
            upper-case
        c             S   s   t | S )N)_copy)xr&   r&   r(   <lambda>       z6CharmmParameterSet.from_parameterset.<locals>.<lambda>c             S   s   | S )Nr&   )ri   r&   r&   r(   rj      rk   c                s   t | trt| } nt | tr0tdd | D } |tkrBt|| < n:t|kr`t| || < n |}|t|< ||| < d S )Nc             s   s   | ]}t |V  qd S )N)r:   ).0kr&   r&   r(   	<genexpr>   s    zOCharmmParameterSet.from_parameterset.<locals>.copy_paramtype.<locals>.<genexpr>)r6   r   r:   rG   r   id)rK   rC   dictZnewtype)do_copy
id_typemapr&   r(   copy_paramtype   s    



z<CharmmParameterSet.from_parameterset.<locals>.copy_paramtype   z%d-key cmap type detected!)rp   r   atom_types_tupler:   r9   
atom_typesatom_types_int
bond_typesangle_typesurey_bradley_typesdihedral_typesr>   r=   
cmap_typeslenAssertionErrornbfix_types)
clsZparamsr   Z
new_paramsrs   rK   Z	atom_typetypenamer*   rC   r&   )rq   rr   r(   from_parameterset   sB    
z$CharmmParameterSet.from_parametersetc             C   s   |  tj|ddS )a'   Extracts known parameters from a Structure instance

        Parameters
        ----------
        struct : :class:`parmed.structure.Structure`
            The parametrized ``Structure`` instance from which to extract
            parameters into a ParameterSet

        Returns
        -------
        params : :class:`ParameterSet`
            The parameter set with all parameters defined in the Structure

        Notes
        -----
        The parameters here are copies of the ones in the Structure, so
        modifying the generated ParameterSet will have no effect on ``struct``.
        Furthermore, the *first* occurrence of each parameter will be used. If
        future ones differ, they will be silently ignored, since this is
        expected behavior in some instances (like with Gromacs topologies in the
        ff99sb-ildn force field).

        Dihedrals are a little trickier. They can be multi-term, which can be
        represented either as a *single* entry in dihedrals with a type of
        DihedralTypeList or multiple entries in dihedrals with a DihedralType
        parameter type. In this case, the parameter is constructed from either
        the first DihedralTypeList found or the first DihedralType of each
        periodicity found if no matching DihedralTypeList is found.
        F)Zallow_unequal_duplicates)r   r   from_structure)r   Zstructr&   r&   r(   r      s    z!CharmmParameterSet.from_structurec             C   sd   |  }|dk	r| | |dk	r*|| t|tr@|| n |dk	r`x|D ]}|| qNW |S )aw  
        Instantiates a CharmmParameterSet from a Topology file and a Parameter
        file (or just a Parameter file if it has all information)

        Parameters
        ----------
        tfile : str
            The name of the Topology (RTF/TOP) file to parse
        pfile : str
            The name of the Parameter (PAR/PRM) file to parse
        sfiles : list(str)
            Iterable of stream (STR) file names

        Returns
        -------
        New CharmmParameterSet populated with parameters found in the provided
        files

        Notes
        -----
        The RTF file is read first (if provided), followed by the PAR file,
        followed by the list of stream files (in the order they are provided).
        Parameters in each stream file will overwrite those that came before (or
        simply append to the existing set if they are different)
        N)rb   rc   r6   r   rd   )r   tfilepfileZsfilesinstsfiler&   r&   r(   load_set  s    



zCharmmParameterSet.load_setc       I      C   s  t j}t|trd}t|}n d}|}t|ts>|dkr>t }d}d}d}g }	d}
t }d}d}xt|D ]\}}| }y
|j	}W n t
k
r   || }Y nX |sql|dkr| dr| dd }ql| drd	}ql| d
rd}ql| ds| dr"d}ql| dsB| drHd}ql| dsh| drnd}ql| drd}ql| drd }}d}| dd }d}xt|D ]\}}| dkrydt||d   }W n" ttfk
r   tdY nX | jrdt| jdkrtt| j\}}t|d j| }|tkrtdn0xft| jD ] \}}x|D ]}||_q~W qpW n6| dr| jr| jdkrtdd| _d}qW ql| drd}ql| dr d}ql| drd}ql|dd  d kr2d}ql|dkr>qlt|}t|dkrdt|d }nd}| d	kr| d!sql| }|d  d krqly<||d td"||d#}|d$  }||d td%||d#}W n tk
r   td&Y nX y:|d'  } t| d$kr0| d | d   } t|  }!W n& tt fk
r`   tt!| }!Y nX t"||||!d(}"|"| j#|"j$< |"| j%|"j&< |"| j'|"j$|"j&f< ql| dkr| }|d  d krqlyH|d  }#|d  }$||d$ td)||d#}%||d td*||d#}&W n tk
r.   td+Y nX t(|#|$t)|#|$f}t*|%|&}'|| j+kr| j+| |'krt,-d,|| j+| |'f t. |'| j+|#|$f< |'| j+|$|#f< n|'| j+|#|$f< |'| j+|$|#f< ||'_/ql| dkrx| }|d  d krqlyT|d  }#|d  }$|d$  }(||d td-||d#}%||d' td.||d#})W n tk
rd   td/Y nX t0|%|)}*|#|$|(f}|| j1kr| j1| |*krt,-d0|| j1| |*f t. |*| j1|#|$|(f< |*| j1|(|$|#f< n |*| j1|#|$|(f< |*| j1|(|$|#f< y@||d1 td2||d#}+||d3 td4||d#},t*|+|,}-||-_/W n tk
rN   t2}-Y nX |-| j3|#|$|(f< |-| j3|(|$|#f< ||*_/ql| dk	r| }|d jd krqlyv|d  }#|d  }$|d$  }(|d  }.||d' td5||d#}%||d1 td6||d#}/||d3 td7||d#}0W n tk
r4   td8Y nX |#|$|(|.f}t4|%|/|0}1||1_/|| jkrd}2x\t| j| D ]J\}}3|3j5|1j5krt|3|1krt,-d9|3|1f t. |1| j| |< d}2P qtW |2	s| j| 6|1 qlt7 }|6|1 || j|#|$|(|.f< || j|.|(|$|#f< ql| dk
r^| }|d  d k	r:qly`|d  }#|d  }$|d$  }(|d  }.||d' td:||d#}%||d1 td;||d#})W n tk
	r   td8Y nX y||d3 td;||d#}4W n tk
	r   d}5Y nX t|)}5|4})|#|$|(|.f}|| j8t9t:|< |5dk
r:t;|%|)}6|6| j<|< nt4|%|5|)}6|6| j=|< d|6_>||6_/ql| dkr| }|d  d k
rqlyd<d= |D }7|	?|7 W ql tk
r   |dk	
rt@|
|	}8|8| jA|< |8| jA|< yz|d  }#|d  }$|d$  }(|d  }.|d'  }9|d1  }:|d3  };|d>  }<||d? td@||d#}=W n tk
rv   tdAY nX |#|$|(|.|9|:|;|<g}>|<|;|:|9|.|(|$|#g}?t9t(|>|?}t9t)|>|?}|=}
g }	Y qlX ql| dkr| }|d jd krqly>|d  }"||d$ tdB||d#}@||d tdC||d#}AW n0 ttfk
rb   |rP xt|D ]\}}| dkr ydt||d   }W n" ttfk
r   tdDY nX | jrtt| j\}}t|d j| }|tkrtdn0xft| jD ] \}}x|D ]}||_qW qW n6| dr\| jrL| jdkrLtdd| _d}q\W wlY n.X | jr| jdkr|stdd}d| _y0||d1 tdE||d#}B||d3 tdF||d#}CW n tk
r   d }B}CY nX |@|A|B|Cg||"< ql| dkrl| }|d  d krqly|d  }D|d  }Et||d$ tdG||d#}F||d tdH||d#}Ay4t||d' tdI||d#}G||d1 tdJ||d#}CW n tk
r   d }G}CY nX y4| j#|D B|E|A|F|C|G | j#|E B|D|A|F|C|G W n t k
r   Y nX W n tk
r$   tdKY nX |F|Af| jCt(|D|Et)|D|Ef< qlW |dk	rpt@|
|	}H|H| jA|< |H| jA|< y(x"|D ]}| j#| jD||   qxW W n& t k
r   t,-dL| t. Y nX |dk	r| jE6| |r|F  dS )MaN  
        Reads all of the parameters from a parameter file. Versions 36 and
        later of the CHARMM force field files have an ATOMS section defining
        all of the atom types.  Older versions need to load this information
        from the RTF/TOP files.

        Parameters
        ----------
        pfile : str or list of lines
            Name of the CHARMM parameter file to read or list of lines to parse
            as a file
        comments : list of str, optional
            List of comments on each of the pfile lines (if pfile is a list of
            lines)

        Notes
        -----
        The atom types must all be loaded by the end of this routine.  Either
        supply a PAR file with atom definitions in them or read in a RTF/TOP
        file first. Failure to do so will result in a raised RuntimeError.
        TFNr   z*>>r!   N   ATOMZATOMSBONDZBONDSZANGLEZTHETAZANGLESDIHEZPHIZ	DIHEDRALSZIMPROPERZIMPHICMAPZ	NONBONDEDZE14FACzDCould not parse 1-4 electrostatic scaling factor from NONBONDED cardzInconsistent 1-4 scalingsZGEOM	geometricz=Cannot combine parameter files with different combining rulesZNBFIXZHBONDTHOLErE   ENDMASSz	atom type)rV   rW   r   z	atom masszCould not parse MASS section.   )r9   numbermassatomic_numberzbond force constantzbond equilibrium distzCould not parse bonds.zReplacing bond %r, %r with %rzangle force constantzangle equilibrium valuezCould not parse angles.zReplacing angle %r, %r with %r   zUrey-Bradley force constantr5   zUrey-Bradley equil. valuezdihedral force constantzdihedral periodicityzdihedral phasezCould not parse dihedrals.zReplacing dihedral %r with %rzimproper force constantzimproper equil. valuec             S   s   g | ]}t |qS r&   )float)rl   wr&   r&   r(   
<listcomp>j  s    z:CharmmParameterSet.read_parameter_file.<locals>.<listcomp>   rt   zCMAP resolutionzCould not parse CMAP data.zvdW epsilon termzvdW Rmin/2 termz.Could not parse electrostatic scaling constantz1-4 vdW epsilon termz1-4 vdW Rmin/2 termz
NBFIX Eminz
NBFIX RminzNBFIX Emin 1-4zNBFIX Rmin 1-4zCould not parse NBFIX terms.z)Atom type %s not present in AtomType list)GrL   rX   r6   strr"   r$   rp   	enumeratestripcommentAttributeError
startswithr7   ra   r   rR   
IndexErrorr
   rO   r}   r{   nextr   abssceer	   combining_rule
_penaltyrefindallintlowerr   KeyErrorr   r   atom_types_strr9   rw   r   ru   minmaxr   rx   warningswarnr   penaltyr   ry   r   rz   r   perr^   r   rI   rG   rH   r   r=   r>   Zimproperextendr   r|   Z	add_nbfixr   Zset_lj_paramsr\   close)Ir'   r   commentsconv
own_handlefsectionZcurrent_cmapZcurrent_cmap2Zcurrent_cmap_dataZcurrent_cmap_resZnonbonded_typesZparametersetZdeclared_geometricirW   r   Zread_first_nonbondedwordsr   Zword_Zdt0ZdiffrK   ZdtlZdtZpensr   r*   r9   r   elemr   atypeZtype1Ztype2rm   reqZ	bond_typeZtype3theteqZ
angle_typeZubkZubeqZubtypeZtype4nphaseZdihedralZreplacedZdtypeZtmpr   ZimpropZholderZtyZtype5Ztype6Ztype7Ztype8resZk1Zk2epsilonrminZeps14Zrmin14Zat1Zat2ZeminZemin14rC   r&   r&   r(   rc   <  s   


   




 
 
















 




"





z&CharmmParameterSet.read_parameter_filec       2   	      s
  t j}t|tr"d}tt|}nd}|}d }}t }t }t }	t }
t|}d}d}	y	x|	r| }|dd 	 dkr|
 y<|d td||d	}d
 	 }|d td||d	}W n  tk
r   td| Y nX y:d 	 }t|d
kr|d |d   }t| }W n& ttfk
rL   tt| }Y nX t||||d}|| j|j< || j|j< || j|j|jf< nH|dd 	 dkrn.|dd 	 dkr^|
 tdk rtdt  nttdd }xbt||D ]T\}}|	 dkrd}|	 dr2|}n"|	 dkrF|}ntd|  qW nv|dd 	 dk	r|dd 	 }|
 d 	 }|| jkrtd|t  ||	|< ||
|< ytd
 }W n( tt!fk
r   td|  Y nX |dkrt"| n"|dkr(t#| nds6t$dd}t|}g }g }x*|	rv|% }|dd 	 dkr|r j&'| g }n|dd 	 dkrn|
 d 	 }d
 	 }td }dkrHt(dd  }d }d!}d"krt(d"d  }d#kr2(d#d  }t)||||||d$} nt*|||d%} |'|   +|  n|dd& 	 d'kr|
 d
 	 }d 	 }!|!dkr j,'| n6|!d(kr܈ j-'d
d  ntd)| |!f  nt| 	 r|
 d 	 d*krtd+d, |
 dd D }xt||D ]\}"}#|dkrd}$|
 d 	 d-krtd
}$ j.'|"|#|$f qD|"d.r |#  _/qD|#d.r |"  _/qD|"d/r؈ |#  _0qD|#d/r |"  _0qD 1|"|# qDW nb|dd 	 d0kr"nH|dd 	 d1kr<n.|dd& 	 d2krVn|dd3 	 d4kr,|
 d dd 	 }%|s|%d5krtd6d   d}P d
d& \}"}#}&}'fd7d8t2d&td
D }(|(d9 })|(d: }*|(d; }+d<d=d5},|,|% |"|#|&|'|)|*|+f}- j3'|- n>|dd
 	 d>kr|
 dd |'d?d, dd D d@d, dd D f n|dd 	 dAkrP n|dd 	 dBkr0t|
 dd }x\t||D ]N\}}|	 dkrd}|	 dr||	|< n|	 dr||
|< qW n:|dd 	 dCkrtdDdE |
 dd D }xdt||||D ]R\}"}#}&}' j4'|"|#|&|'f |#d d.ks|&d d.ks|'d.krt |"  _/qtW n|ddF 	 dGk	rR|
  fdHd,dd D }.fdId8t2dtd
D }(t|(dJ }/t|(dK }0t5|.|/|0dL|.d _6n|dd 	 dMk	rjP t|}qNW |	r j&'| t7 | |	rqbqb|dk	r ||< qb|dk	rƈ ||< qbdsbt$dqbt|}|d7 }qbW W n t8k

r    Y nX | j9:| xt;|D ]\} |	| }1|1dk	
rhy| j9|1  _<W n$ tk

rf   tdN|1  Y nX |
| }1|1dk	
ry| j9|1  _=W n$ tk

r   tdN|1  Y nX 
qW | j:| |
r|>  dS )Oa  
        Reads _only_ the atom type definitions from a topology file. This is
        unnecessary for versions 36 and later of the CHARMM force field.

        Parameters
        ----------
        tfile : str
            Name of the CHARMM topology file to read
        TFNr   r   r   r!   z	atom type)rV   rW   r   rE   z	atom massz"Could not parse MASS section of %s)r9   r   r   r   ZDECLZDEFAr   z#DEFA line has %d tokens; expected 5ZNONEZFIRSZLASTzDEFA patch %s unknown)RESIPRESzReplacing residue {}zNo charge for %sr   r   zrestype != RESI or PRESZGROUPr   ZALPHAg?ZDRUDr   ZTYPE)r9   rT   chargealphathole
drude_type)r9   rT   r   r5   ZDELETEIMPRz7WARNING: Ignoring "%s" because entity type %s not used.)r   DOUBLEc             S   s   g | ]}|  qS r&   )r7   )rl   r   r&   r&   r(   r   s  s    z9CharmmParameterSet.read_topology_file.<locals>.<listcomp>r   r3   r1   r   ZDONORZACCEPTrt   ZLONEPAIR)ZBISEZRELAzDLONEPAIR type %s not supported; only BISEctor and RELAtive supportedc                s.   i | ]&}t  |d    | dd  qS )r!   r   r   )r   r7   )rl   index)r   r&   r(   
<dictcomp>  s   z9CharmmParameterSet.read_topology_file.<locals>.<dictcomp>ZDISTZANGLr   ZbisectorZrelativeZICc             S   s   g | ]}|  qS r&   )r7   )rl   r   r&   r&   r(   r     s    c             S   s   g | ]}t |qS r&   )r   )rl   r   r&   r&   r(   r     s    r   ZPATCH)r   ZIMPHc             s   s   | ]}|  V  qd S )N)r7   )rl   r   r&   r&   r(   rn     s    z8CharmmParameterSet.read_topology_file.<locals>.<genexpr>
   Z
ANISOTROPYc                s   g | ]} | qS r&   r&   )rl   r9   )r   r&   r(   r     s    c                s&   i | ]}t  |d    |  qS )r!   )r   r7   )rl   r   )r   r&   r(   r     s   ZA11ZA22)a11a22)r   r   r   zPatch %s not found)?rL   rX   r6   r   iterr"   r   r   r   r7   ra   r   r   r   r
   r}   r   r   r   r   r   r   r9   rw   r   ru   r   r   r    r   residuesformatr   rR   r   r   r~   lstripgroupsr^   r   r   r   Zadd_atomZdelete_atomsZdelete_impropersZ	add_bondsheadtailZadd_bondrangeZ	lonepairsZ_imprr   Z
anisotropy_fit_IC_tableStopIterationpatchesupdater   Zfirst_patchZ
last_patchr   )2r'   r   r   r   r   ZhpatchZtpatchr   r   ZhpatchesZtpatchesrW   rV   Zskip_adding_residuer*   r9   r   r   r   r   ittokvalZrestypeZresnamer   groupictablerT   r   r   r   atomZentity_typer?   r@   orderZlptype_keywordrA   rB   keywordsrZthetaZphiZlptypesZlonepairZatomsr   r   Z
patch_namer&   )r   r   r(   rb     s   













$






 
&
 






 z%CharmmParameterSet.read_topology_filec             C   s   t |tr|}nt|}| \}}}xd|dk	r|dk	r|  }|d dkr`| t| n|d drz| || | \}}}q(W dS )a   
        Reads RTF and PAR sections from a stream file and dispatches the
        sections to read_topology_file or read_parameter_file

        Parameters
        ----------
        sfile : str or CharmmStreamFile
            Stream file to parse
        Nr!   ZrtfZpara)	r6   r#   Znext_sectionr   ra   rb   r   r   rc   )r'   r   r   titler   r   r   r&   r&   r(   rd     s    

z#CharmmParameterSet.read_stream_filec             C   s
  |dkr|dkrt d|dk	rnt|tr:t|d}d}n|}d}|d |d | |d |rn|  |dk	rt|trt|d}d}n|}d}|d |d	 | | |r|  |dk	rt|trt|d}d}n|}d}| | |r|  dS )
a   Write a CHARMM parameter set to a file

        Parameters
        ----------
        top : str or file-like object, optional
            If provided, the atom types will be written to this file in RTF
            format.
        par : str or file-like object, optional
            If provided, the parameters will be written to this file in PAR
            format. Either this or the ``str`` argument *must* be provided
        str : str or file-like object, optional
            If provided, the atom types and parameters will be written to this
            file as separate RTF and PAR cards that can be read as a CHARMM
            stream file. Either this or the ``par`` argument *must* be provided

        Raises
        ------
        ValueError if both par and str are None
        Nz Must specify either par *or* strr   TFz4*>>>> CHARMM Topology file generated by ParmEd <<<<
z*
z5*>>>> CHARMM Parameter file generated by ParmEd <<<<
z*

)	rR   r6   r   r   write_write_top_tor   _write_par_to_write_str_to)r'   rZ   rY   r   r   Z	ownhandler&   r&   r(   r     sB    



 




 



 zCharmmParameterSet.writec             C   s.   | d | |d | d | | dS )z: Private method to write stream items to open file object z/read rtf card
* Topology generated by ParmEd
*
Tz3
read para card
* Parameters generated by ParmEd
*
N)r   r   r   )r'   r   r&   r&   r(   r   =  s    

z CharmmParameterSet._write_str_toc             C   sf   |r| d | d x:tt| jD ](\}\}}| d|d |j|jf  q(W |rb| d dS )z< Private method to write topology items to open file object z36   1

zMASS %5d %-6s %9.5f
r!   z
END
N)r   r   r   rv   r9   r   )r'   r   Zwrite_versionr   r   r   r&   r&   r(   r   D  s    

 z CharmmParameterSet._write_top_toc             C   s  t  t   }}xHt| jD ]:\}}x0|D ](}|jr>||j |jr(||j q(W qW t|dkspt|dkrxtd|sdn| }|sdn| }|	d | 
|d |	d t  }x^t| jD ]P\}}||krq|| |tt| |	d|d |d |j|jf  qW |	d	 t  }xjt| jD ]\\}}||krPq:|| |tt| |	d
|d |d |d |j|jf  q:W |	d t  }xt| jD ]z\}}||kr̐q|| |tt| xD|D ]<}	|	d|d |d |d |d |	jt|	j|	jf  qW qW |	d t  }xZtt| jdd dD ]@\}}|	d|d |d |d |d |jt|j|jf  q\W xHt| jD ]:\}}|	d|d |d |d |d |jd|jf  qW | jr|	d t  }xt| jD ]\}}||kr(q|| |tt| |	d|d |d |d |d |d |d |d |d |jf	  d}
x|jD ]x}|
r|
d dkr|	d |
|j dkr|	d d}
n|
|j dkr|	d d}
|
d7 }
|	d|  qW |	d qW |	dd| | jdkr:dnd f  xt| jD ]\}}|	d!|d"t |j! |j"f  |j!|j#kr|j"|j$kr|	d#dt |j! | |j"f  n|	d#dt |j# |j$f  qPW |	d$ d%S )&z= Private method to write parameter items to open file object r!   zMixed 1-4 scaling not supportedg      ?zATOMS
Fz
BONDS
z%-6s %-6s %7.2f %10.4f
r   z
ANGLES
z%-6s %-6s %-6s %7.2f %8.2f
r   z
DIHEDRALS
z%%-6s %-6s %-6s %-6s %11.4f %2d %8.2f
rE   z
IMPROPERS
c             S   s   | d S )Nr   r&   )ri   r&   r&   r(   rj   x  rk   z2CharmmParameterSet._write_par_to.<locals>.<lambda>)rK   z
CMAPS
z-%-6s %-6s %-6s %-6s %-6s %-6s %-6s %-6s %5d

r   r   r5   r   r   z

z %13.6fz


z
NONBONDED  nbxmod  5 atom cdiel fshift vatom vdistance vfswitch -
cutnb 14.0 ctofnb 12.0 ctonnb 10.0 eps 1.0 e14fac %s wmin 1.5%s

r   z GEOMr%   z%-6s %14.6f %10.6f %14.6fg        z%10.6f %10.6f %14.6f
z
END
N)%setr   r{   r   addscnbr}   rR   popr   r   rx   rG   reversedrm   r   ry   r   Zphi_kr   r   r   rH   r>   r=   Zpsi_kZpsi_eqr|   Z
resolutionZgridr   rv   r   r   r   Z
epsilon_14Zrmin_14)r'   r   r   r   r   rC   tZwrittenrK   Ztorr   r   r&   r&   r(   r   O  s    
  

 
  

 
.

 

<
 60

 
 *


  $$z CharmmParameterSet._write_par_to)r%   NN)F)NNN)N)NNN)r,   r-   r.   r/   rN   staticmethodrX   r[   classmethodr   r   r   rc   rb   rd   r   r   r   r   __classcell__r&   r&   )rQ   r(   rL   U   s*   "L#(
   ; y
7rL   c             C   s$   x| D ]}d |_  |_|_qW dS )a  
    Determines cartesian coordinates from an internal coordinate table stored in
    CHARMM residue topology files

    Parameters
    ----------
    res : ResidueTemplate
        The residue template for which coordinates are being determined
    ictable : list[tuple(atoms, measurements)]
        The internal coordinate table

    Notes
    -----
    This method assigns an xx, xy, and xz attribute to ``res``. For the time
    being, this is just a placeholder, as its functionality has not yet been
    implemented (CHARMM does not use a 'traditional' Z-matrix, and I don't know
    of any existing code that will compute the proper cartesian coordinates from
    the form used by CHARMM)
    g        N)ZxxZxyZxz)r   r   r   r&   r&   r(   r     s    
r   ):r/   Z
__future__r   r   r   r_   rer   r   rh   collectionsr   	itertoolsr   Z	constantsr	   
exceptionsr
   r   Zmodellerr   r   Z
parametersr   Zperiodic_tabler   r   Ztopologyobjectsr   r   r   r   r   r   r   r   r   r   r   Zutils.ior   Z	utils.sixr   r   r   Zutils.six.movesr    Z_charmmfiler"   r#   compiler   objectr$   r:   r;   rL   r   r&   r&   r&   r(   <module>   s>   4

"        U