# Path: snntoolbox/parsing/utils.py
# @abstractmethod
# def get_inbound_layers(self, layer):
#     """Get inbound layers of ``layer``.
# 
#     Returns
#     -------
# 
#     inbound: Sequence
#     """
# 
#     pass


import os
import json
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten, AveragePooling2D, \
    MaxPooling2D, Conv2D, DepthwiseConv2D, ZeroPadding2D, Reshape, Layer, \
    Concatenate, Conv1D, Conv2DTranspose, UpSampling2D
from tensorflow.python.keras.utils import conv_utils
from snntoolbox.parsing.utils import get_inbound_layers
            from snntoolbox.bin.utils import load_config
        from snntoolbox.utils.utils import get_abs_path
        from snntoolbox.bin.utils import get_log_keys, get_plot_keys
        """

        i = self.get_layer_idx()
        m = tf.clip_by_value(1 - (1 - 2 * self.time / self.duration) * i / 50,
                             0, 1)
        self.bias.assign(self.bias * m)


def add_payloads(prev_layer, input_spikes):
    """Get payloads from previous layer."""

    # Get only payloads of those pre-synaptic neurons that spiked
    payloads = tf.where(tf.equal(input_spikes, 0.),
                        tf.zeros_like(input_spikes), prev_layer.payloads)
    print("Using spikes with payloads from layer {}".format(prev_layer.name))
    return input_spikes + payloads


def spike_call(call):
    @tf.function
    def decorator(self, x):

        if clamp_var:
            # Clamp membrane potential if spike rate variance too high
            self.update_avg_variance(x)
        if self.online_normalization:
            # Modify threshold if firing rate of layer too low
            self.v_thresh.assign(self.get_new_thresh())
        if self.payloads:
            # Add payload from previous layer

# Path: snntoolbox/parsing/utils.py
# @abstractmethod
# def get_inbound_layers(self, layer):
#     """Get inbound layers of ``layer``.
# 
#     Returns
#     -------
# 
#     inbound: Sequence
#     """
# 
#     pass


# Path: snntoolbox/simulation/backends/inisim/temporal_mean_rate_tensorflow.py
import os
import json
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten, AveragePooling2D, \
    MaxPooling2D, Conv2D, DepthwiseConv2D, ZeroPadding2D, Reshape, Layer, \
    Concatenate, Conv1D, Conv2DTranspose, UpSampling2D
from tensorflow.python.keras.utils import conv_utils
from snntoolbox.parsing.utils import get_inbound_layers
            from snntoolbox.bin.utils import load_config
        from snntoolbox.utils.utils import get_abs_path
        from snntoolbox.bin.utils import get_log_keys, get_plot_keys

        """

        i = self.get_layer_idx()
        m = tf.clip_by_value(1 - (1 - 2 * self.time / self.duration) * i / 50,
                             0, 1)
        self.bias.assign(self.bias * m)


def add_payloads(prev_layer, input_spikes):
    """Get payloads from previous layer."""

    # Get only payloads of those pre-synaptic neurons that spiked
    payloads = tf.where(tf.equal(input_spikes, 0.),
                        tf.zeros_like(input_spikes), prev_layer.payloads)
    print("Using spikes with payloads from layer {}".format(prev_layer.name))
    return input_spikes + payloads


def spike_call(call):
    @tf.function
    def decorator(self, x):

        if clamp_var:
            # Clamp membrane potential if spike rate variance too high
            self.update_avg_variance(x)
        if self.online_normalization:
            # Modify threshold if firing rate of layer too low
            self.v_thresh.assign(self.get_new_thresh())
        if self.payloads:
            # Add payload from previous layer

            x = add_payloads(get_inbound_layers(self)[0], x)