# Path: snntoolbox/parsing/model_libs/keras_input_lib.py
# def load(path, filename, **kwargs):
#     """Load network from file.
# 
#     Parameters
#     ----------
# 
#     path: str
#         Path to directory where to load model from.
# 
#     filename: str
#         Name of file to load model from.
# 
#     Returns
#     -------
# 
#     : dict[str, Union[keras.models.Sequential, function]]
#         A dictionary of objects that constitute the input model. It must
#         contain the following two keys:
# 
#         - 'model': keras.models.Sequential
#             Keras model instance of the network.
#         - 'val_fn': function
#             Function that allows evaluating the original model.
#     """
# 
#     filepath = str(os.path.join(path, filename))
# 
#     if os.path.exists(filepath + '.json'):
#         model = models.model_from_json(open(filepath + '.json').read())
#         try:
#             model.load_weights(filepath + '.h5')
#         except OSError:
#             # Allows h5 files without a .h5 extension to be loaded.
#             model.load_weights(filepath)
#         # With this loading method, optimizer and loss cannot be recovered.
#         # Could be specified by user, but since they are not really needed
#         # at inference time, set them to the most common choice.
#         # TODO: Proper reinstantiation should be doable since Keras2
#         model.compile('sgd', 'categorical_crossentropy',
#                       ['accuracy', metrics.top_k_categorical_accuracy])
#     else:
#         filepath_custom_objects = kwargs.get('filepath_custom_objects', None)
#         if filepath_custom_objects is not None:
#             filepath_custom_objects = str(filepath_custom_objects)  # python 2
# 
#         custom_dicts = assemble_custom_dict(
#             get_custom_activations_dict(filepath_custom_objects),
#             get_custom_layers_dict())
#         try:
#             model = models.load_model(filepath + '.h5', custom_dicts)
#         except OSError as e:
#             print(e)
#             print("Trying to load without '.h5' extension.")
#             model = models.load_model(filepath, custom_dicts)
#         model.compile(model.optimizer, model.loss,
#                       ['accuracy', metrics.top_k_categorical_accuracy])
# 
#     model.summary()
#     return {'model': model, 'val_fn': model.evaluate}


import os
    import tensorflow.keras.backend as k
        import matplotlib
            import warnings
        import nxsdk.api.n2a as sim
from importlib import import_module
from snntoolbox.parsing.model_libs.keras_input_lib import load
    from snntoolbox.datasets.utils import get_dataset
    from snntoolbox.conversion.utils import normalize_parameters
        from functools import wraps
                from snntoolbox.simulation.plotting import plot_param_sweep
    from snntoolbox.utils.utils import import_configparser
    from textwrap import dedent
        Results are added to the queue to be displayed in the GUI.

    Returns
    -------

    results: list
        List of the accuracies obtained after simulating with each parameter
        value in config.get('parameter_sweep', 'param_values').
    """


    num_to_test = config.getint('simulation', 'num_to_test')

    # Instantiate an empty spiking network
    target_sim = import_target_sim(config)
    spiking_model = target_sim.SNN(config, queue)

    # ___________________________ LOAD DATASET ______________________________ #

    normset, testset = get_dataset(config)

    results = None
    parsed_model = None
    if config.getboolean('tools', 'parse') and not is_stop(queue):

        # __________________________ LOAD MODEL _____________________________ #

        model_lib = import_module('snntoolbox.parsing.model_libs.' +
                                  config.get('input', 'model_lib') +
                                  '_input_lib')

# Path: snntoolbox/parsing/model_libs/keras_input_lib.py
# def load(path, filename, **kwargs):
#     """Load network from file.
# 
#     Parameters
#     ----------
# 
#     path: str
#         Path to directory where to load model from.
# 
#     filename: str
#         Name of file to load model from.
# 
#     Returns
#     -------
# 
#     : dict[str, Union[keras.models.Sequential, function]]
#         A dictionary of objects that constitute the input model. It must
#         contain the following two keys:
# 
#         - 'model': keras.models.Sequential
#             Keras model instance of the network.
#         - 'val_fn': function
#             Function that allows evaluating the original model.
#     """
# 
#     filepath = str(os.path.join(path, filename))
# 
#     if os.path.exists(filepath + '.json'):
#         model = models.model_from_json(open(filepath + '.json').read())
#         try:
#             model.load_weights(filepath + '.h5')
#         except OSError:
#             # Allows h5 files without a .h5 extension to be loaded.
#             model.load_weights(filepath)
#         # With this loading method, optimizer and loss cannot be recovered.
#         # Could be specified by user, but since they are not really needed
#         # at inference time, set them to the most common choice.
#         # TODO: Proper reinstantiation should be doable since Keras2
#         model.compile('sgd', 'categorical_crossentropy',
#                       ['accuracy', metrics.top_k_categorical_accuracy])
#     else:
#         filepath_custom_objects = kwargs.get('filepath_custom_objects', None)
#         if filepath_custom_objects is not None:
#             filepath_custom_objects = str(filepath_custom_objects)  # python 2
# 
#         custom_dicts = assemble_custom_dict(
#             get_custom_activations_dict(filepath_custom_objects),
#             get_custom_layers_dict())
#         try:
#             model = models.load_model(filepath + '.h5', custom_dicts)
#         except OSError as e:
#             print(e)
#             print("Trying to load without '.h5' extension.")
#             model = models.load_model(filepath, custom_dicts)
#         model.compile(model.optimizer, model.loss,
#                       ['accuracy', metrics.top_k_categorical_accuracy])
# 
#     model.summary()
#     return {'model': model, 'val_fn': model.evaluate}


# Path: snntoolbox/bin/utils.py
import os
    import tensorflow.keras.backend as k
        import matplotlib
            import warnings
        import nxsdk.api.n2a as sim
from importlib import import_module
from snntoolbox.parsing.model_libs.keras_input_lib import load
    from snntoolbox.datasets.utils import get_dataset
    from snntoolbox.conversion.utils import normalize_parameters
        from functools import wraps
                from snntoolbox.simulation.plotting import plot_param_sweep
    from snntoolbox.utils.utils import import_configparser
    from textwrap import dedent

        Results are added to the queue to be displayed in the GUI.

    Returns
    -------

    results: list
        List of the accuracies obtained after simulating with each parameter
        value in config.get('parameter_sweep', 'param_values').
    """


    num_to_test = config.getint('simulation', 'num_to_test')

    # Instantiate an empty spiking network
    target_sim = import_target_sim(config)
    spiking_model = target_sim.SNN(config, queue)

    # ___________________________ LOAD DATASET ______________________________ #

    normset, testset = get_dataset(config)

    results = None
    parsed_model = None
    if config.getboolean('tools', 'parse') and not is_stop(queue):

        # __________________________ LOAD MODEL _____________________________ #

        model_lib = import_module('snntoolbox.parsing.model_libs.' +
                                  config.get('input', 'model_lib') +
                                  '_input_lib')

        input_model = model_lib.load(config.get('paths', 'path_wd'),