# Path: openmmtools/constants.py
# E_CHARGE = 1.602176634e-19 * u.coulomb
# EPSILON0 = 1e-6*8.8541878128e-12/(u.AVOGADRO_CONSTANT_NA*E_CHARGE**2) * u.farad/u.meter
# ONE_4PI_EPS0 = 1/(4*pi*EPSILON0) * EPSILON0.unit  # we need it unitless
# LITER = 1000.0 * u.centimeters**3
# STANDARD_STATE_VOLUME = LITER / (u.AVOGADRO_CONSTANT_NA*u.mole)


import os
import os.path
import numpy as np
import numpy.random
import itertools
import copy
import inspect
import scipy
import scipy.special
import scipy.integrate
    import openmm
        import mdtraj as md
        import pandas as pd
        import mdtraj as md
        import mdtraj as md  # TODO: would like to remove mdtraj dependence
    from openmm import unit
    from openmm import app
    from simtk import openmm
    from simtk import unit
    from simtk.openmm import app
from .constants import kB
    from openeye import oechem
    from pkg_resources import resource_filename
        from openmmtools import sobol
            from openmm import XmlSerializer
            from simtk.openmm import XmlSerializer
        from openmmtools.alchemy import AlchemicalRegion, AbsoluteAlchemicalFactory
        from openmmtools.alchemy import AlchemicalRegion, AbsoluteAlchemicalFactory
            from parmed.amber import AmberParm
        from scipy.integrate import quadrature
        self._mdtraj_topology = None

    @topology.deleter
    def topology(self):
        del self._topology

    @property
    def mdtraj_topology(self):
        """The mdtraj.Topology object corresponding to the test system (read-only)."""
        if self._mdtraj_topology is None:
            self._mdtraj_topology = md.Topology.from_openmm(self._topology)
        return self._mdtraj_topology

    @property
    def analytical_properties(self):
        """A list of available analytical properties, accessible via 'get_propertyname(thermodynamic_state)' calls."""
        return [method[4:] for method in dir(self) if (method[0:4] == 'get_')]

    def reduced_potential_expectation(self, state_sampled_from, state_evaluated_in):
        """Calculate the expected potential energy in state_sampled_from, divided by kB * T in state_evaluated_in.

        Notes
        -----

        This is not called get_reduced_potential_expectation because this function
        requires two, not one, inputs.
        """

        if hasattr(self, "get_potential_expectation"):
            U = self.get_potential_expectation(state_sampled_from)

# Path: openmmtools/constants.py
# E_CHARGE = 1.602176634e-19 * u.coulomb
# EPSILON0 = 1e-6*8.8541878128e-12/(u.AVOGADRO_CONSTANT_NA*E_CHARGE**2) * u.farad/u.meter
# ONE_4PI_EPS0 = 1/(4*pi*EPSILON0) * EPSILON0.unit  # we need it unitless
# LITER = 1000.0 * u.centimeters**3
# STANDARD_STATE_VOLUME = LITER / (u.AVOGADRO_CONSTANT_NA*u.mole)


# Path: openmmtools/testsystems.py
import os
import os.path
import numpy as np
import numpy.random
import itertools
import copy
import inspect
import scipy
import scipy.special
import scipy.integrate
    import openmm
        import mdtraj as md
        import pandas as pd
        import mdtraj as md
        import mdtraj as md  # TODO: would like to remove mdtraj dependence
    from openmm import unit
    from openmm import app
    from simtk import openmm
    from simtk import unit
    from simtk.openmm import app
from .constants import kB
    from openeye import oechem
    from pkg_resources import resource_filename
        from openmmtools import sobol
            from openmm import XmlSerializer
            from simtk.openmm import XmlSerializer
        from openmmtools.alchemy import AlchemicalRegion, AbsoluteAlchemicalFactory
        from openmmtools.alchemy import AlchemicalRegion, AbsoluteAlchemicalFactory
            from parmed.amber import AmberParm
        from scipy.integrate import quadrature

        self._mdtraj_topology = None

    @topology.deleter
    def topology(self):
        del self._topology

    @property
    def mdtraj_topology(self):
        """The mdtraj.Topology object corresponding to the test system (read-only)."""
        if self._mdtraj_topology is None:
            self._mdtraj_topology = md.Topology.from_openmm(self._topology)
        return self._mdtraj_topology

    @property
    def analytical_properties(self):
        """A list of available analytical properties, accessible via 'get_propertyname(thermodynamic_state)' calls."""
        return [method[4:] for method in dir(self) if (method[0:4] == 'get_')]

    def reduced_potential_expectation(self, state_sampled_from, state_evaluated_in):
        """Calculate the expected potential energy in state_sampled_from, divided by kB * T in state_evaluated_in.

        Notes
        -----

        This is not called get_reduced_potential_expectation because this function
        requires two, not one, inputs.
        """

        if hasattr(self, "get_potential_expectation"):
            U = self.get_potential_expectation(state_sampled_from)

            U_red = U / (kB * state_evaluated_in.temperature)