# Path: harold/_arg_utils.py
# def _check_for_state_or_transfer(G, custom_msg=None):
#     """
#     A helper function to assert whether the given object is a State or
#     Transfer.
#     """
#     if not isinstance(G, (State, Transfer)):
#         if custom_msg is None:
#             custom_msg = 'The argument should be a Transfer or a State'\
#                          '. Instead found a {}'.format(type(G).__qualname__)
#         raise ValueError(custom_msg)
# 
# Path: harold/_time_domain.py
# def simulate_step_response(sys, t=None):
#     """
#     Compute the linear model response to an Heaviside function (or all-ones
#     array) sampled at given time instances.
# 
#     If the time array is omitted then a time sequence is generated based on
#     the poles of the model.
# 
#     Parameters
#     ----------
#     sys : {State, Transfer}
#         The system model to be simulated
#     t : array_like
#         The real-valued sequence to be used for the evolution of the system.
#         The values should be equally spaced otherwise an error is raised. For
#         discrete time models increments different than the sampling period also
#         raises an error. On the other hand for discrete models this can be
#         omitted and a time sequence will be generated automatically.
# 
#     Returns
#     -------
#     yout : ndarray
#         The resulting response array. The array is 1D if sys is SISO and
#         has p columns if sys has p outputs. If there are also m inputs the
#         array is 3D array with the shape (<num of samples>, p, m)
#     tout : ndarray
#         The time sequence used in the simulation. If the parameter t is not
#         None then a copy of t is given.
# 
#     """
#     _check_for_state_or_transfer(sys)
#     # Always works with State Models
#     try:
#         _check_for_state(sys)
#     except ValueError:
#         sys = transfer_to_state(sys)
# 
#     if t is None:
#         tf, ts = _compute_tfinal_and_dt(sys)
#         t = np.arange(0, tf+ts, ts, dtype=float)
#     else:
#         t, ts = _check_custom_time_input(t)
# 
#     m = sys.shape[1]
#     u = np.ones([len(t), m], dtype=float)
# 
#     return simulate_linear_system(sys, u=u, t=t, per_channel=1)
# 
# def simulate_impulse_response(sys, t=None):
#     """
#     Compute the linear model response to an Dirac delta pulse (or all-zeros
#     array except the first sample being 1/dt at each channel) sampled at given
#     time instances.
# 
#     If the time array is omitted then a time sequence is generated based on
#     the poles of the model.
# 
#     Parameters
#     ----------
#     sys : {State, Transfer}
#         The system model to be simulated
#     t : array_like
#         The real-valued sequence to be used for the evolution of the system.
#         The values should be equally spaced otherwise an error is raised. For
#         discrete time models increments different than the sampling period also
#         raises an error. On the other hand for discrete models this can be
#         omitted and a time sequence will be generated automatically.
# 
#     Returns
#     -------
#     yout : ndarray
#         The resulting response array. The array is 1D if sys is SISO and
#         has p columns if sys has p outputs. If there are also m inputs the
#         array is 3D array with the shape (<num of samples>, p, m)
#     tout : ndarray
#         The time sequence used in the simulation. If the parameter t is not
#         None then a copy of t is given.
# 
#     """
#     _check_for_state_or_transfer(sys)
#     # Always works with State Models
#     try:
#         _check_for_state(sys)
#     except ValueError:
#         sys = transfer_to_state(sys)
# 
#     if t is None:
#         tf, ts = _compute_tfinal_and_dt(sys, is_step=False)
#         t = np.arange(0, tf+ts, ts, dtype=float)
#     else:
#         t, ts = _check_custom_time_input(t)
# 
#     m = sys.shape[1]
#     u = np.zeros([len(t), m], dtype=float)
#     u[0] = 1./ts
# 
#     return simulate_linear_system(sys, u=u, t=t, per_channel=1)


import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from ._arg_utils import _check_for_state_or_transfer
from ._time_domain import simulate_step_response, simulate_impulse_response

__all__ = ['step_response_plot', 'impulse_response_plot']


def _check_sys_args(sys):
    """Check the arguments of time domain plotting funcs.

    Parameters
    ----------
    sys : State, Transfer or iterable containing State or Transfer objects.

    Returns
    -------
    syslist : list
        Resulting system list including singletons.

    """
    try:

# Path: harold/_arg_utils.py
# def _check_for_state_or_transfer(G, custom_msg=None):
#     """
#     A helper function to assert whether the given object is a State or
#     Transfer.
#     """
#     if not isinstance(G, (State, Transfer)):
#         if custom_msg is None:
#             custom_msg = 'The argument should be a Transfer or a State'\
#                          '. Instead found a {}'.format(type(G).__qualname__)
#         raise ValueError(custom_msg)
# 
# Path: harold/_time_domain.py
# def simulate_step_response(sys, t=None):
#     """
#     Compute the linear model response to an Heaviside function (or all-ones
#     array) sampled at given time instances.
# 
#     If the time array is omitted then a time sequence is generated based on
#     the poles of the model.
# 
#     Parameters
#     ----------
#     sys : {State, Transfer}
#         The system model to be simulated
#     t : array_like
#         The real-valued sequence to be used for the evolution of the system.
#         The values should be equally spaced otherwise an error is raised. For
#         discrete time models increments different than the sampling period also
#         raises an error. On the other hand for discrete models this can be
#         omitted and a time sequence will be generated automatically.
# 
#     Returns
#     -------
#     yout : ndarray
#         The resulting response array. The array is 1D if sys is SISO and
#         has p columns if sys has p outputs. If there are also m inputs the
#         array is 3D array with the shape (<num of samples>, p, m)
#     tout : ndarray
#         The time sequence used in the simulation. If the parameter t is not
#         None then a copy of t is given.
# 
#     """
#     _check_for_state_or_transfer(sys)
#     # Always works with State Models
#     try:
#         _check_for_state(sys)
#     except ValueError:
#         sys = transfer_to_state(sys)
# 
#     if t is None:
#         tf, ts = _compute_tfinal_and_dt(sys)
#         t = np.arange(0, tf+ts, ts, dtype=float)
#     else:
#         t, ts = _check_custom_time_input(t)
# 
#     m = sys.shape[1]
#     u = np.ones([len(t), m], dtype=float)
# 
#     return simulate_linear_system(sys, u=u, t=t, per_channel=1)
# 
# def simulate_impulse_response(sys, t=None):
#     """
#     Compute the linear model response to an Dirac delta pulse (or all-zeros
#     array except the first sample being 1/dt at each channel) sampled at given
#     time instances.
# 
#     If the time array is omitted then a time sequence is generated based on
#     the poles of the model.
# 
#     Parameters
#     ----------
#     sys : {State, Transfer}
#         The system model to be simulated
#     t : array_like
#         The real-valued sequence to be used for the evolution of the system.
#         The values should be equally spaced otherwise an error is raised. For
#         discrete time models increments different than the sampling period also
#         raises an error. On the other hand for discrete models this can be
#         omitted and a time sequence will be generated automatically.
# 
#     Returns
#     -------
#     yout : ndarray
#         The resulting response array. The array is 1D if sys is SISO and
#         has p columns if sys has p outputs. If there are also m inputs the
#         array is 3D array with the shape (<num of samples>, p, m)
#     tout : ndarray
#         The time sequence used in the simulation. If the parameter t is not
#         None then a copy of t is given.
# 
#     """
#     _check_for_state_or_transfer(sys)
#     # Always works with State Models
#     try:
#         _check_for_state(sys)
#     except ValueError:
#         sys = transfer_to_state(sys)
# 
#     if t is None:
#         tf, ts = _compute_tfinal_and_dt(sys, is_step=False)
#         t = np.arange(0, tf+ts, ts, dtype=float)
#     else:
#         t, ts = _check_custom_time_input(t)
# 
#     m = sys.shape[1]
#     u = np.zeros([len(t), m], dtype=float)
#     u[0] = 1./ts
# 
#     return simulate_linear_system(sys, u=u, t=t, per_channel=1)


# Path: harold/_time_domain_plots.py
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from ._arg_utils import _check_for_state_or_transfer
from ._time_domain import simulate_step_response, simulate_impulse_response


__all__ = ['step_response_plot', 'impulse_response_plot']


def _check_sys_args(sys):
    """Check the arguments of time domain plotting funcs.

    Parameters
    ----------
    sys : State, Transfer or iterable containing State or Transfer objects.

    Returns
    -------
    syslist : list
        Resulting system list including singletons.

    """
    try:

        _check_for_state_or_transfer(sys)