# Path: pysaliency/utils.py
# class LazyList(Sequence):
#     """
#     A list-like class that is able to generate it's entries only
#     when needed. Entries can be cached.
# 
#     LayList implements `collections.Sequence` and therefore `__contains__`.
#     However, to use it, in the worst case all elements of the list have
#     to be generated.
# 
#     .. note::
#         As `LazyList` stores the generator function, pickling it
#         will usually fail. To pickle a `LazyList`, use `dill`.
#     """
#     def __init__(self, generator, length, cache=True, pickle_cache=False):
#         """
#         Parameters
#         ----------
# 
#         @type  generator: callable
#         @param generator: A function that takes an integer `n` and returns the
#                           `n`-th element of the list.
# 
#         @type  length:   int
#         @param length:   The length of the list
# 
#         @type  cache: bool, defaults to `True`
#         @param cache: Wether to cache the list items.
# 
#         @type  pickle_cache: bool, defaults to `False`
#         @param pickle_cache: Whether the cache should be saved when
#                              pickling the object.
#         """
#         self.generator = generator
#         self.length = length
#         self.cache = cache
#         self.pickle_cache = pickle_cache
#         self._cache = {}
# 
#     def __len__(self):
#         return self.length
# 
#     def __getitem__(self, index):
#         if isinstance(index, slice):
#             return [self[i] for i in range(len(self))[index]]
#         elif isinstance(index, list):
#             return [self[i] for i in index]
#         else:
#             return self._getitem(index)
# 
#     def _getitem(self, index):
#         if not 0 <= index < self.length:
#             raise IndexError(index)
#         if index in self._cache:
#             return self._cache[index]
#         value = self.generator(index)
#         if self.cache:
#             self._cache[index] = value
#         return value
# 
#     def __getstate__(self):
#         # we don't want to save the cache
#         state = dict(self.__dict__)
#         if not self.pickle_cache:
#             state.pop('_cache')
#         return state
# 
#     def __setstate__(self, state):
#         if not '_cache' in state:
#             state['_cache'] = {}
#         self.__dict__ = dict(state)
# 
# def build_padded_2d_array(arrays, max_length=None, padding_value=np.nan):
#     if max_length is None:
#         max_length = np.max([len(a) for a in arrays])
# 
#     output = np.ones((len(arrays), max_length), dtype=np.asarray(arrays[0]).dtype)
#     output *= padding_value
#     for i, array in enumerate(arrays):
#         output[i, :len(array)] = array
# 
#     return output


import os
import json
import numpy as np
                import h5py
    import h5py
    import h5py
        import h5py
from hashlib import sha1
from collections import Sequence
from functools import wraps
from weakref import WeakValueDictionary
from six.moves import range as xrange
from six import string_types
from boltons.cacheutils import cached
from imageio import imread
from PIL import Image
from tqdm import tqdm
from .utils import LazyList, build_padded_2d_array
        return self.stimuli.sizes[self.index]


class Stimuli(Sequence):
    """
    Manages a list of stimuli (i.e. images).

    The stimuli can be given as numpy arrays. Using the class `FileStimuli`, the stimuli
    can also be saved on disk and will be loaded only when needed.

    Attributes
    ----------
    stimuli :
        The stimuli as list of numpy arrays
    shapes :
        The shapes of the stimuli. For a grayscale stimulus this will
        be a 2-tuple, for a color stimulus a 3-tuple
    sizes :
        The sizes of all stimuli in pixels as pairs (height, width). In difference
        to `shapes`, the color dimension is ignored here.
    stimulus_ids:
        A unique id for each stimulus. Can be used to cache results for stimuli
    stimulus_objects:
        A `Stimulus` instance for each stimulus. Mainly for caching.

    """
    __attributes__ = []
    def __init__(self, stimuli, attributes=None):
        self.stimuli = stimuli
        self.shapes = [s.shape for s in self.stimuli]

# Path: pysaliency/utils.py
# class LazyList(Sequence):
#     """
#     A list-like class that is able to generate it's entries only
#     when needed. Entries can be cached.
# 
#     LayList implements `collections.Sequence` and therefore `__contains__`.
#     However, to use it, in the worst case all elements of the list have
#     to be generated.
# 
#     .. note::
#         As `LazyList` stores the generator function, pickling it
#         will usually fail. To pickle a `LazyList`, use `dill`.
#     """
#     def __init__(self, generator, length, cache=True, pickle_cache=False):
#         """
#         Parameters
#         ----------
# 
#         @type  generator: callable
#         @param generator: A function that takes an integer `n` and returns the
#                           `n`-th element of the list.
# 
#         @type  length:   int
#         @param length:   The length of the list
# 
#         @type  cache: bool, defaults to `True`
#         @param cache: Wether to cache the list items.
# 
#         @type  pickle_cache: bool, defaults to `False`
#         @param pickle_cache: Whether the cache should be saved when
#                              pickling the object.
#         """
#         self.generator = generator
#         self.length = length
#         self.cache = cache
#         self.pickle_cache = pickle_cache
#         self._cache = {}
# 
#     def __len__(self):
#         return self.length
# 
#     def __getitem__(self, index):
#         if isinstance(index, slice):
#             return [self[i] for i in range(len(self))[index]]
#         elif isinstance(index, list):
#             return [self[i] for i in index]
#         else:
#             return self._getitem(index)
# 
#     def _getitem(self, index):
#         if not 0 <= index < self.length:
#             raise IndexError(index)
#         if index in self._cache:
#             return self._cache[index]
#         value = self.generator(index)
#         if self.cache:
#             self._cache[index] = value
#         return value
# 
#     def __getstate__(self):
#         # we don't want to save the cache
#         state = dict(self.__dict__)
#         if not self.pickle_cache:
#             state.pop('_cache')
#         return state
# 
#     def __setstate__(self, state):
#         if not '_cache' in state:
#             state['_cache'] = {}
#         self.__dict__ = dict(state)
# 
# def build_padded_2d_array(arrays, max_length=None, padding_value=np.nan):
#     if max_length is None:
#         max_length = np.max([len(a) for a in arrays])
# 
#     output = np.ones((len(arrays), max_length), dtype=np.asarray(arrays[0]).dtype)
#     output *= padding_value
#     for i, array in enumerate(arrays):
#         output[i, :len(array)] = array
# 
#     return output


# Path: pysaliency/datasets.py
import os
import json
import numpy as np
                import h5py
    import h5py
    import h5py
        import h5py
from hashlib import sha1
from collections import Sequence
from functools import wraps
from weakref import WeakValueDictionary
from six.moves import range as xrange
from six import string_types
from boltons.cacheutils import cached
from imageio import imread
from PIL import Image
from tqdm import tqdm
from .utils import LazyList, build_padded_2d_array

        return self.stimuli.sizes[self.index]


class Stimuli(Sequence):
    """
    Manages a list of stimuli (i.e. images).

    The stimuli can be given as numpy arrays. Using the class `FileStimuli`, the stimuli
    can also be saved on disk and will be loaded only when needed.

    Attributes
    ----------
    stimuli :
        The stimuli as list of numpy arrays
    shapes :
        The shapes of the stimuli. For a grayscale stimulus this will
        be a 2-tuple, for a color stimulus a 3-tuple
    sizes :
        The sizes of all stimuli in pixels as pairs (height, width). In difference
        to `shapes`, the color dimension is ignored here.
    stimulus_ids:
        A unique id for each stimulus. Can be used to cache results for stimuli
    stimulus_objects:
        A `Stimulus` instance for each stimulus. Mainly for caching.

    """
    __attributes__ = []
    def __init__(self, stimuli, attributes=None):
        self.stimuli = stimuli
        self.shapes = [s.shape for s in self.stimuli]

        self.sizes = LazyList(lambda n: (self.shapes[n][0], self.shapes[n][1]),