B
    b_                 @   s   d Z ddlmZmZm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 ddlmZ dd	lmZ dd
lmZmZ ddlmZ ddlZedZeeG dd deZG dd deZ dS )z:
XML file parsing utilities for OpenMM serialized objects
    )divisionprint_functionabsolute_import)closingN)Vec3)FileFormatType)!box_vectors_to_lengths_and_angles)needs_openmm)genopen)add_metaclassstring_types)StringIOz	<(.*?)/?>c               @   s,   e Zd ZdZedd Zeedd ZdS )XmlFilez
    Wrapper for parsing OpenMM-serialized objects. Supports serialized State,
    System, Integrator, and ForceField objects.
    c          	   C   s   t t| dh}x`|D ]X}| }|s(qt|}|s:dS | d }|d dkrTq| d }|dkrldS dS W W dQ R X dS )a   Identifies the file type as an XML file

        Parameters
        ----------
        filename : str
            Name of the file to check format for

        Returns
        -------
        is_fmt : bool
            True if it is an XML format, False otherwise
        rFr   z?!)ZSystemState
ForceFieldZ
IntegratorTN)r   r
   strip_xmlrematchgroupssplit)filenameflineZrematchstuffZkind r   4lib/python3.7/site-packages/parmed/openmm/xmlfile.py	id_format   s    
 
zXmlFile.id_formatc          	   C   s   ddl m} ddl m} t| trFtt| d}| }W dQ R X n|  }d|krzt }|	| |
d ||S |j|}t||jrt|S |S )aB  
        Parses XML file and returns deserialized object. The return value
        depends on the serialized object, summarized below

            - System : returns simtk.openmm.System
            - State : returns simtk.openmm.State
            - Integrator : returns simtk.openmm.Integrator subclass
            - ForceField : returns simtk.openmm.app.ForceField

        Parameters
        ----------
        filename : str or file-like
            The file name or file object containing the XML-serialized object

        Returns
        -------
        obj : System, State, Integrator, or ForceField
            The deserialized object

        Notes
        -----
        OpenMM requires the entire contents of this file read into memory. As a
        result, this function may require a significant amount of memory.
        r   N)appr   z<ForceField)Zsimtk.openmmZopenmmr   
isinstancer   r   r
   readr   writeseekr   ZXmlSerializerZdeserializer   _OpenMMStateContents)r   Zmmr   r   contentsobjr   r   r   parse8   s    



zXmlFile.parseN)__name__
__module____qualname____doc__staticmethodr   r	   r&   r   r   r   r   r      s   r   c               @   s2   e Zd ZdZed	ddZdd Zedd ZdS )
r#   ax  
    A container that holds all of the information present in the OpenMM State
    object that gets deserialized. This is an internal class that is only
    intended to be *instantiated* by XmlFile.parse.

    Parameters
    ----------
    state : :class:`simtk.openmm.State`
        OpenMM State containing relevant state information

    Attributes
    ----------
    coordinates : np.ndarray with shape(1, natom, 3)
        Atomic coordinates. If not present in the State, just set to None. Units
        are Angstrom
    positions : list of Vec3
        Atomic coordinates of first frame with applied units
    velocities : np.ndarray with shape(1, natom, 3)
        Atomic velocities. If not present in the State, just set to None. Units
        are Angstrom/picosecond
    forces : np.ndarray with shape(1, natom, 3)
        Atomic forces. If not present in the State, just set to None. Units are
        kcal/mol/Angstrom
    energy : float
        Energy of this configuration in kcal/mol. If not specified, it is set to
        None
    time : float
        The time associated with this State in ps. If not specified, set to None
    Nc             K   sN   yt | |f |}W n tk
r(   d S X ||}|d k	rF||}|S d S )N)getattr	Exceptionvalue_in_unitZreshape)stategetterunitshapekwargsr   r   r   r   	_get_data   s    

z_OpenMMStateContents._get_datac             C   s   | j |dtjddd| _| j |dtjtj ddd| _| j |dtjtj ddd| _|  |dtj| _|  |dtj| _	| j |d	tj
d
dd}|d k	rt| \}}|tj}|tj}tt|t| | _nd | _d S )NZgetPositions)      T)ZasNumpyZgetVelocitiesZ	getForcesZgetPotentialEnergyZgetTimeZgetPeriodicBoxVectors)r7   r7   )r4   uZangstromcoordinatesZ
picosecondZ
velocitiesZkilocalorie_per_moleZforcesZenergyZtimeZ	angstromsr   r.   ZdegreenpZarraylistbox)selfr/   r<   ZlengZangr   r   r   __init__   s&    



z_OpenMMStateContents.__init__c             C   s   dd | j d D S )Nc             S   s   g | ]}t | qS r   )r   ).0Zxyzr   r   r   
<listcomp>   s    z2_OpenMMStateContents.positions.<locals>.<listcomp>r   )r9   )r=   r   r   r   	positions   s    z_OpenMMStateContents.positions)N)	r'   r(   r)   r*   r+   r4   r>   propertyrA   r   r   r   r   r#   f   s
   r#   )!r*   Z
__future__r   r   r   
contextlibr   Znumpyr:   Zparmed.vec3r   Zparmed.formats.registryr   Zparmed.geometryr   Zparmed.unitr1   r8   Zparmed.utils.decoratorsr	   Zparmed.utils.ior
   Zparmed.utils.sixr   r   Zparmed.utils.six.movesr   recompiler   objectr   r#   r   r   r   r   <module>   s    
Q