# 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/respa.py
# class MTSIntegrator(CustomIntegrator):
#     def __init__(self, dt, groups):
#     def _createSubsteps(self, parentSubsteps, groups):
# 
# Path: openmmtools/utils.py
# def temporary_directory():
# def time_it(task_name):
# def with_timer(task_name):
#     def _with_timer(func):
#         def _wrapper(*args, **kwargs):
#     def __init__(self):
#     def reset_timing_statistics(self, benchmark_id=None):
#     def start(self, benchmark_id):
#     def stop(self, benchmark_id):
#     def partial(self, benchmark_id):
#     def report_timing(self, clear=True):
# def sanitize_expression(expression, variables):
# def math_eval(expression, variables=None, functions=None):
#     def _math_eval(node):
# def _changes_state(func):
#     def wrapper(self, *args, **kwargs):
#     def __init__(self, *args, **kwargs):
#     def __getitem__(self, item):
#     def __init__(self, tracked_quantity, *args, **kwargs):
#     def __getitem__(self, item):
#     def __setitem__(self, key, value):
# def is_quantity_close(quantity1, quantity2, rtol=1e-10, atol=0.0):
# def quantity_from_string(expression):
# def typename(atype):
# def platform_supports_precision(platform, precision):
# def get_available_platforms(minimum_precision='mixed'):
# def get_fastest_platform(minimum_precision='mixed'):
# def serialize(instance, **kwargs):
# def deserialize(serialization):
# def with_metaclass(metaclass, *bases):
#         def __new__(cls, name, this_bases, d):
#     def __subclasshook__(cls, subclass):
# def find_all_subclasses(parent_cls, discard_abstract=False, include_parent=True):
# def find_subclass(parent_cls, subcls_name):
#     def __init__(self, *args, **kwargs):
#     def is_restorable(cls, openmm_object):
#     def restore_interface(cls, openmm_object):
#     def _hash_parameter_name(self):
#     def _get_hash_parameter_name(cls, openmm_object):
#     def _add_global_parameter(cls, openmm_object, parameter_name, parameter_value):
#     def _get_global_parameter(cls, openmm_object, parameter_name):
#     def _get_force_parameter_by_name(cls, force, parameter_name):
#     def deserialize_xml(cls, xml_serialization):
#     def __deepcopy__(self, memo):
#     def __copy__(self):
#     def _is_force(openmm_object):
#     def _compute_class_hash(openmm_class):
# class Timer(object):
# class TrackedQuantity(unit.Quantity):
# class TrackedQuantityView(unit.Quantity):
#     class Metaclass(metaclass):
# class SubhookedABCMeta(with_metaclass(abc.ABCMeta)):
# class RestorableOpenMMObjectError(Exception):
# class RestorableOpenMMObject(object):
# _RESERVED_WORDS_PATTERNS = {
#     'lambda': re.compile(r'(?<![a-zA-Z0-9_])lambda(?![a-zA-Z0-9_])')
# }
# _VALID_UNITS = {method: getattr(unit, method) for method in dir(unit) if type(getattr(unit, method)) is unit.Unit}
# _VALID_UNIT_FUNCTIONS = {method: getattr(unit, method) for method in dir(unit)
#                          if callable(getattr(unit, method)) and type(getattr(unit, method)) is not type}
#     SUPPORTED_PRECISIONS = ['single', 'mixed', 'double']
# _SERIALIZED_MANGLED_PREFIX = '_serialized__'


import logging
import re
import numpy as np
    import openmm.unit as unit
    import openmm as mm
    import simtk.unit as unit
    import simtk.openmm as mm
    import doctest
from openmmtools.constants import kB
from openmmtools import respa, utils
        if not hasattr(self, 'getNumComputations'):
            raise Exception('This integrator is not a CustomIntegrator.')

        readable_lines = []
        indent_level = 0
        for step in range(self.getNumComputations()):
            line = ''
            step_type, target, expr = self.getComputationStep(step)
            highlight = True if (step_types_to_highlight is not None) and (step_type in step_types_to_highlight) else False
            if step_type in [8]:
                indent_level -= 1
            if highlight:
                line += '\x1b[6;30;42m'
            line += 'step {:6d} : '.format(step) + '   ' * indent_level + step_type_dict[step_type].format(target=target, expr=expr)
            if highlight:
                line += '\x1b[0m'
            if step_type in [6, 7]:
                indent_level += 1
            readable_lines.append(line)

        if as_list:
            return readable_lines
        else:
            return '\n'.join(readable_lines)

    def pretty_print(self):
        """Pretty-print the computation steps of this integrator."""
        print(self.pretty_format())



# 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/respa.py
# class MTSIntegrator(CustomIntegrator):
#     def __init__(self, dt, groups):
#     def _createSubsteps(self, parentSubsteps, groups):
# 
# Path: openmmtools/utils.py
# def temporary_directory():
# def time_it(task_name):
# def with_timer(task_name):
#     def _with_timer(func):
#         def _wrapper(*args, **kwargs):
#     def __init__(self):
#     def reset_timing_statistics(self, benchmark_id=None):
#     def start(self, benchmark_id):
#     def stop(self, benchmark_id):
#     def partial(self, benchmark_id):
#     def report_timing(self, clear=True):
# def sanitize_expression(expression, variables):
# def math_eval(expression, variables=None, functions=None):
#     def _math_eval(node):
# def _changes_state(func):
#     def wrapper(self, *args, **kwargs):
#     def __init__(self, *args, **kwargs):
#     def __getitem__(self, item):
#     def __init__(self, tracked_quantity, *args, **kwargs):
#     def __getitem__(self, item):
#     def __setitem__(self, key, value):
# def is_quantity_close(quantity1, quantity2, rtol=1e-10, atol=0.0):
# def quantity_from_string(expression):
# def typename(atype):
# def platform_supports_precision(platform, precision):
# def get_available_platforms(minimum_precision='mixed'):
# def get_fastest_platform(minimum_precision='mixed'):
# def serialize(instance, **kwargs):
# def deserialize(serialization):
# def with_metaclass(metaclass, *bases):
#         def __new__(cls, name, this_bases, d):
#     def __subclasshook__(cls, subclass):
# def find_all_subclasses(parent_cls, discard_abstract=False, include_parent=True):
# def find_subclass(parent_cls, subcls_name):
#     def __init__(self, *args, **kwargs):
#     def is_restorable(cls, openmm_object):
#     def restore_interface(cls, openmm_object):
#     def _hash_parameter_name(self):
#     def _get_hash_parameter_name(cls, openmm_object):
#     def _add_global_parameter(cls, openmm_object, parameter_name, parameter_value):
#     def _get_global_parameter(cls, openmm_object, parameter_name):
#     def _get_force_parameter_by_name(cls, force, parameter_name):
#     def deserialize_xml(cls, xml_serialization):
#     def __deepcopy__(self, memo):
#     def __copy__(self):
#     def _is_force(openmm_object):
#     def _compute_class_hash(openmm_class):
# class Timer(object):
# class TrackedQuantity(unit.Quantity):
# class TrackedQuantityView(unit.Quantity):
#     class Metaclass(metaclass):
# class SubhookedABCMeta(with_metaclass(abc.ABCMeta)):
# class RestorableOpenMMObjectError(Exception):
# class RestorableOpenMMObject(object):
# _RESERVED_WORDS_PATTERNS = {
#     'lambda': re.compile(r'(?<![a-zA-Z0-9_])lambda(?![a-zA-Z0-9_])')
# }
# _VALID_UNITS = {method: getattr(unit, method) for method in dir(unit) if type(getattr(unit, method)) is unit.Unit}
# _VALID_UNIT_FUNCTIONS = {method: getattr(unit, method) for method in dir(unit)
#                          if callable(getattr(unit, method)) and type(getattr(unit, method)) is not type}
#     SUPPORTED_PRECISIONS = ['single', 'mixed', 'double']
# _SERIALIZED_MANGLED_PREFIX = '_serialized__'


# Path: openmmtools/integrators.py
import logging
import re
import numpy as np
    import openmm.unit as unit
    import openmm as mm
    import simtk.unit as unit
    import simtk.openmm as mm
    import doctest
from openmmtools.constants import kB
from openmmtools import respa, utils

        if not hasattr(self, 'getNumComputations'):
            raise Exception('This integrator is not a CustomIntegrator.')

        readable_lines = []
        indent_level = 0
        for step in range(self.getNumComputations()):
            line = ''
            step_type, target, expr = self.getComputationStep(step)
            highlight = True if (step_types_to_highlight is not None) and (step_type in step_types_to_highlight) else False
            if step_type in [8]:
                indent_level -= 1
            if highlight:
                line += '\x1b[6;30;42m'
            line += 'step {:6d} : '.format(step) + '   ' * indent_level + step_type_dict[step_type].format(target=target, expr=expr)
            if highlight:
                line += '\x1b[0m'
            if step_type in [6, 7]:
                indent_level += 1
            readable_lines.append(line)

        if as_list:
            return readable_lines
        else:
            return '\n'.join(readable_lines)

    def pretty_print(self):
        """Pretty-print the computation steps of this integrator."""
        print(self.pretty_format())



class ThermostatedIntegrator(utils.RestorableOpenMMObject, PrettyPrintableIntegrator,