# Path: pysaliency/saliency_map_models.py
# class GaussianSaliencyMapModel(SaliencyMapModel):
#     """Gaussian saliency map model with given width"""
#     def __init__(self, width=0.5, center_x=0.5, center_y=0.5, **kwargs):
#         super(GaussianSaliencyMapModel, self).__init__(**kwargs)
#         self.width = width
#         self.center_x = center_x
#         self.center_y = center_y
# 
#     def _saliency_map(self, stimulus):
#         height = stimulus.shape[0]
#         width = stimulus.shape[1]
#         YS, XS = np.mgrid[:height, :width].astype(float)
#         XS /= width
#         YS /= height
#         XS -= self.center_x
#         YS -= self.center_y
#         r_squared = XS**2 + YS**2
#         return np.ones((stimulus.shape[0], stimulus.shape[1]))*np.exp(-0.5*r_squared/(self.width)**2)
# 
# Path: pysaliency/sampling_models.py
# class SamplingModelMixin(object):
#     """A sampling model is supports sampling fixations and whole scanpaths."""
#     def sample_scanpath(
#         self, stimulus, x_hist, y_hist, t_hist, samples, attributes=None, verbose=False, rst=None
#     ):
#         """return xs, ys, ts"""
#         xs = list(remove_trailing_nans(x_hist))
#         ys = list(remove_trailing_nans(y_hist))
#         ts = list(remove_trailing_nans(t_hist))
#         if not len(xs) == len(ys) == len(ts):
#             raise ValueError("Histories for x, y and t have to be the same length")
# 
#         for i in range(samples):
#             x, y, t = self.sample_fixation(stimulus, xs, ys, ts, attributes=attributes, verbose=verbose, rst=rst)
#             xs.append(x)
#             ys.append(y)
#             ts.append(t)
# 
#         return xs, ys, ts
# 
#     @abstractmethod
#     def sample_fixation(self, stimulus, x_hist, y_hist, t_hist, attributes=None, verbose=False, rst=None):
#         """return x, y, t"""
#         raise NotImplementedError()
# 
# class ScanpathSamplingModelMixin(SamplingModelMixin):
#     """A sampling model which only has to implement sample_scanpath instead of sample_fixation"""
#     @abstractmethod
#     def sample_scanpath(
#             self, stimulus, x_hist, y_hist, t_hist, samples, attributes=None, verbose=False, rst=None
#     ):
#         raise NotImplementedError()
# 
#     def sample_fixation(self, stimulus, x_hist, y_hist, t_hist, attributes=None, verbose=False, rst=None):
#         samples = 1
#         xs, ys, ts = self.sample_scanpath(stimulus, x_hist, y_hist, t_hist, samples, attributes=attributes,
#                                           verbose=verbose, rst=rst)
#         return xs[-1], ys[-1], ts[-1]


import numpy as np
from pysaliency.saliency_map_models import GaussianSaliencyMapModel
from pysaliency.sampling_models import SamplingModelMixin, ScanpathSamplingModelMixin



def test_fixation_sampling():
    class SamplingModel(SamplingModelMixin, GaussianSaliencyMapModel):
        def sample_fixation(self, stimulus, x_hist, y_hist, t_hist, attributes=None, verbose=False, rst=None):
            return x_hist[-1] + 1, y_hist[-1] + 1, t_hist[-1] + 1

    model = SamplingModel()

    xs, ys, ts = model.sample_scanpath(np.zeros((40, 40, 3)), [0], [1], [2], 4)
    assert xs == [0, 1, 2, 3, 4]
    assert ys == [1, 2, 3, 4, 5]
    assert ts == [2, 3, 4, 5, 6]


def test_scanpath_sampling():

# Path: pysaliency/saliency_map_models.py
# class GaussianSaliencyMapModel(SaliencyMapModel):
#     """Gaussian saliency map model with given width"""
#     def __init__(self, width=0.5, center_x=0.5, center_y=0.5, **kwargs):
#         super(GaussianSaliencyMapModel, self).__init__(**kwargs)
#         self.width = width
#         self.center_x = center_x
#         self.center_y = center_y
# 
#     def _saliency_map(self, stimulus):
#         height = stimulus.shape[0]
#         width = stimulus.shape[1]
#         YS, XS = np.mgrid[:height, :width].astype(float)
#         XS /= width
#         YS /= height
#         XS -= self.center_x
#         YS -= self.center_y
#         r_squared = XS**2 + YS**2
#         return np.ones((stimulus.shape[0], stimulus.shape[1]))*np.exp(-0.5*r_squared/(self.width)**2)
# 
# Path: pysaliency/sampling_models.py
# class SamplingModelMixin(object):
#     """A sampling model is supports sampling fixations and whole scanpaths."""
#     def sample_scanpath(
#         self, stimulus, x_hist, y_hist, t_hist, samples, attributes=None, verbose=False, rst=None
#     ):
#         """return xs, ys, ts"""
#         xs = list(remove_trailing_nans(x_hist))
#         ys = list(remove_trailing_nans(y_hist))
#         ts = list(remove_trailing_nans(t_hist))
#         if not len(xs) == len(ys) == len(ts):
#             raise ValueError("Histories for x, y and t have to be the same length")
# 
#         for i in range(samples):
#             x, y, t = self.sample_fixation(stimulus, xs, ys, ts, attributes=attributes, verbose=verbose, rst=rst)
#             xs.append(x)
#             ys.append(y)
#             ts.append(t)
# 
#         return xs, ys, ts
# 
#     @abstractmethod
#     def sample_fixation(self, stimulus, x_hist, y_hist, t_hist, attributes=None, verbose=False, rst=None):
#         """return x, y, t"""
#         raise NotImplementedError()
# 
# class ScanpathSamplingModelMixin(SamplingModelMixin):
#     """A sampling model which only has to implement sample_scanpath instead of sample_fixation"""
#     @abstractmethod
#     def sample_scanpath(
#             self, stimulus, x_hist, y_hist, t_hist, samples, attributes=None, verbose=False, rst=None
#     ):
#         raise NotImplementedError()
# 
#     def sample_fixation(self, stimulus, x_hist, y_hist, t_hist, attributes=None, verbose=False, rst=None):
#         samples = 1
#         xs, ys, ts = self.sample_scanpath(stimulus, x_hist, y_hist, t_hist, samples, attributes=attributes,
#                                           verbose=verbose, rst=rst)
#         return xs[-1], ys[-1], ts[-1]


# Path: tests/test_sampling.py
import numpy as np
from pysaliency.saliency_map_models import GaussianSaliencyMapModel
from pysaliency.sampling_models import SamplingModelMixin, ScanpathSamplingModelMixin




def test_fixation_sampling():
    class SamplingModel(SamplingModelMixin, GaussianSaliencyMapModel):
        def sample_fixation(self, stimulus, x_hist, y_hist, t_hist, attributes=None, verbose=False, rst=None):
            return x_hist[-1] + 1, y_hist[-1] + 1, t_hist[-1] + 1

    model = SamplingModel()

    xs, ys, ts = model.sample_scanpath(np.zeros((40, 40, 3)), [0], [1], [2], 4)
    assert xs == [0, 1, 2, 3, 4]
    assert ys == [1, 2, 3, 4, 5]
    assert ts == [2, 3, 4, 5, 6]


def test_scanpath_sampling():

    class SamplingModel(ScanpathSamplingModelMixin, GaussianSaliencyMapModel):