# Path: perses/dispersed/feptasks.py
# class Particle():
#     def __init__(self,
#                  thermodynamic_state,
#                  sampler_state,
#                  nsteps,
#                  direction,
#                  splitting = 'V R O R V',
#                  temperature = 300*unit.kelvin,
#                  collision_rate = np.inf/unit.picoseconds,
#                  timestep = 1.0*unit.femtosecond,
#                  work_save_interval = None,
#                  top = None,
#                  subset_atoms = None,
#                  save_configuration = False,
#                  lambda_protocol = 'default',
#                  measure_shadow_work = False,
#                  label = None,
#                  trajectory_filename  = None):
#     def anneal(self, new, num_integration_steps = 1):
#     def attempt_termination(self):
#     def compute_incremental_work(self, _lambda):
#     def save_configuration(self, iteration):
#     def launch_particle(task):
#     def distribute_anneal(task, new, num_integration_steps = 1):
#     def update_incremental_work(task, index):
#     def pull_sampler_state(task):
#     def pull_cumulative_work(task):
#     def pull_cumulative_work_profile(task):
#     def pull_work_increments(task):
#     def pull_current_lambda(task):
#     def pull_shadow_work(task):
#     def pull_timers(task):
#     def pull_success(task):
#     def pull_labels(task):
#     def pull_last_label(task):
#     def push_resamples(task, sampler_state, label, work):
#     def push_cumulative_work(task, work):
#     def check_NonequilibriumFEPTask(task):
#     def write_nonequilibrium_trajectory(nonequilibrium_trajectory, trajectory_filename):
# def check_EquilibriumFEPTask(task):
# def minimize(thermodynamic_state: states.ThermodynamicState, sampler_state: states.SamplerState,
#              max_iterations: int=100) -> states.SamplerState:
# def compute_reduced_potential(thermodynamic_state: states.ThermodynamicState, sampler_state: states.SamplerState) -> float:
# def write_nonequilibrium_trajectory(nonequilibrium_trajectory, trajectory_filename) -> float:
# def write_equilibrium_trajectory(trajectory: md.Trajectory, trajectory_filename: str) -> float:
# def compute_nonalchemical_perturbation(alchemical_thermodynamic_state: states.ThermodynamicState,  growth_thermodynamic_state: states.ThermodynamicState, hybrid_sampler_state: states.SamplerState, hybrid_factory: HybridTopologyFactory, nonalchemical_thermodynamic_state: states.ThermodynamicState, lambda_state: int) -> tuple:
# def compute_timeseries(reduced_potentials: np.array) -> list:
# def run_equilibrium(task):
# 
# Path: perses/app/setup_relative_calculation.py
# class TimeFilter(logging.Filter):
#     def filter(self, record):
# def getSetupOptions(filename):
# def get_openmm_platform(platform_name=None):
# def run_setup(setup_options, serialize_systems=True, build_samplers=True):
# def run(yaml_filename=None):
# def _resume_run(setup_options):
# LOGLEVEL = os.environ.get("LOGLEVEL", "INFO").upper()
# ENERGY_THRESHOLD = 1e-4
#                 LSF = setup_options['LSF']


import os
import mdtraj as md
            import traceback
            import warnings
            import traceback
            import warnings
from pkg_resources import resource_filename
from simtk import unit
from perses.dispersed import feptasks
from perses.app import setup_relative_calculation
from openmmtools import states, alchemy, testsystems, cache
from unittest import skipIf
    from perses.tests.utils import enter_temp_directory
        from perses.app.setup_relative_calculation import getSetupOptions
    from perses.tests.utils import enter_temp_directory
        from perses.app.setup_relative_calculation import getSetupOptions
    from perses.app.relative_setup import RelativeFEPSetup

    #construct the openmmtools objects for it
    sampler_state = states.SamplerState(positions, box_vectors=system.getDefaultPeriodicBoxVectors())
    thermodynamic_state = states.ThermodynamicState(system, temperature=temperature, pressure=pressure)

    #make an alchemical state
    alchemical_state = alchemy.AlchemicalState.from_system(system)
    alchemical_state.set_alchemical_parameters(0.0)

    #make a compound thermodynamic state
    cpd_thermodynamic_state = states.CompoundThermodynamicState(thermodynamic_state, [alchemical_state])

    return cpd_thermodynamic_state, sampler_state, water_ts.topology

# TODO fails as integrator not bound to context
@skipIf(running_on_github_actions, "Skip analysis test on GH Actions.  Currently broken")
def test_run_nonequilibrium_switching_move():
    """
    Test that the NonequilibriumSwitchingMove changes lambda from 0 to 1 in multiple iterations
    """
    n_iterations = 5
    cpd_thermodynamic_state, sampler_state, topology = generate_example_waterbox_states()

    md_topology = md.Topology.from_openmm(topology)

    #make the EquilibriumResult object that will be used to initialize the protocol runs:
    eq_result = feptasks.EquilibriumResult(0.0, sampler_state)

    #run the NE switching move task n_iterations times, checking that the context is correctly handled.
    for i in range(n_iterations):

# Path: perses/dispersed/feptasks.py
# class Particle():
#     def __init__(self,
#                  thermodynamic_state,
#                  sampler_state,
#                  nsteps,
#                  direction,
#                  splitting = 'V R O R V',
#                  temperature = 300*unit.kelvin,
#                  collision_rate = np.inf/unit.picoseconds,
#                  timestep = 1.0*unit.femtosecond,
#                  work_save_interval = None,
#                  top = None,
#                  subset_atoms = None,
#                  save_configuration = False,
#                  lambda_protocol = 'default',
#                  measure_shadow_work = False,
#                  label = None,
#                  trajectory_filename  = None):
#     def anneal(self, new, num_integration_steps = 1):
#     def attempt_termination(self):
#     def compute_incremental_work(self, _lambda):
#     def save_configuration(self, iteration):
#     def launch_particle(task):
#     def distribute_anneal(task, new, num_integration_steps = 1):
#     def update_incremental_work(task, index):
#     def pull_sampler_state(task):
#     def pull_cumulative_work(task):
#     def pull_cumulative_work_profile(task):
#     def pull_work_increments(task):
#     def pull_current_lambda(task):
#     def pull_shadow_work(task):
#     def pull_timers(task):
#     def pull_success(task):
#     def pull_labels(task):
#     def pull_last_label(task):
#     def push_resamples(task, sampler_state, label, work):
#     def push_cumulative_work(task, work):
#     def check_NonequilibriumFEPTask(task):
#     def write_nonequilibrium_trajectory(nonequilibrium_trajectory, trajectory_filename):
# def check_EquilibriumFEPTask(task):
# def minimize(thermodynamic_state: states.ThermodynamicState, sampler_state: states.SamplerState,
#              max_iterations: int=100) -> states.SamplerState:
# def compute_reduced_potential(thermodynamic_state: states.ThermodynamicState, sampler_state: states.SamplerState) -> float:
# def write_nonequilibrium_trajectory(nonequilibrium_trajectory, trajectory_filename) -> float:
# def write_equilibrium_trajectory(trajectory: md.Trajectory, trajectory_filename: str) -> float:
# def compute_nonalchemical_perturbation(alchemical_thermodynamic_state: states.ThermodynamicState,  growth_thermodynamic_state: states.ThermodynamicState, hybrid_sampler_state: states.SamplerState, hybrid_factory: HybridTopologyFactory, nonalchemical_thermodynamic_state: states.ThermodynamicState, lambda_state: int) -> tuple:
# def compute_timeseries(reduced_potentials: np.array) -> list:
# def run_equilibrium(task):
# 
# Path: perses/app/setup_relative_calculation.py
# class TimeFilter(logging.Filter):
#     def filter(self, record):
# def getSetupOptions(filename):
# def get_openmm_platform(platform_name=None):
# def run_setup(setup_options, serialize_systems=True, build_samplers=True):
# def run(yaml_filename=None):
# def _resume_run(setup_options):
# LOGLEVEL = os.environ.get("LOGLEVEL", "INFO").upper()
# ENERGY_THRESHOLD = 1e-4
#                 LSF = setup_options['LSF']


# Path: perses/tests/test_relative_setup.py
import os
import mdtraj as md
            import traceback
            import warnings
            import traceback
            import warnings
from pkg_resources import resource_filename
from simtk import unit
from perses.dispersed import feptasks
from perses.app import setup_relative_calculation
from openmmtools import states, alchemy, testsystems, cache
from unittest import skipIf
    from perses.tests.utils import enter_temp_directory
        from perses.app.setup_relative_calculation import getSetupOptions
    from perses.tests.utils import enter_temp_directory
        from perses.app.setup_relative_calculation import getSetupOptions
    from perses.app.relative_setup import RelativeFEPSetup


    #construct the openmmtools objects for it
    sampler_state = states.SamplerState(positions, box_vectors=system.getDefaultPeriodicBoxVectors())
    thermodynamic_state = states.ThermodynamicState(system, temperature=temperature, pressure=pressure)

    #make an alchemical state
    alchemical_state = alchemy.AlchemicalState.from_system(system)
    alchemical_state.set_alchemical_parameters(0.0)

    #make a compound thermodynamic state
    cpd_thermodynamic_state = states.CompoundThermodynamicState(thermodynamic_state, [alchemical_state])

    return cpd_thermodynamic_state, sampler_state, water_ts.topology

# TODO fails as integrator not bound to context
@skipIf(running_on_github_actions, "Skip analysis test on GH Actions.  Currently broken")
def test_run_nonequilibrium_switching_move():
    """
    Test that the NonequilibriumSwitchingMove changes lambda from 0 to 1 in multiple iterations
    """
    n_iterations = 5
    cpd_thermodynamic_state, sampler_state, topology = generate_example_waterbox_states()

    md_topology = md.Topology.from_openmm(topology)

    #make the EquilibriumResult object that will be used to initialize the protocol runs:
    eq_result = feptasks.EquilibriumResult(0.0, sampler_state)

    #run the NE switching move task n_iterations times, checking that the context is correctly handled.
    for i in range(n_iterations):

        ne_move = feptasks.NonequilibriumSwitchingMove(default_forward_functions, splitting="V R O H R V", temperature=300.0*unit.kelvin, nsteps_neq=10, timestep=1.0*unit.femtoseconds, top=md_topology, work_save_interval=10)