def HyperG(x, y, BlackBackground, jetter, Bound):

    orientations = [i * np.pi / 8 for i in range(4)]
    sizes = [1.0 / 3, 1.0 / 6, 1.0 / 12]
    thickness = [1.0 / 30, 1.0 / 60, 1.0 / 120]
    smoothing = [1.0 / 15, 1.0 / 30, 1.0 / 60]
    s_t_m = zip(sizes, thickness, smoothing)
    paras = [(o, s, t, m) for o in orientations for s, t, m in s_t_m]

    if jetter:
        paras = pert.modulation_of_jetter(paras, 'HG')

    # generates images and saved into a numpy array
    HG = np.empty(len(paras), dtype=np.object)
    idx = 0
    for par in paras:
        HG[idx] = HyperbolicGrating(bounds=Bound,
                                    thickness=par[2],
                                    size=par[1],
                                    orientation=par[0],
                                    smoothing=par[3],
                                    xdensity=x,
                                    ydensity=y)()
        if BlackBackground:
            assert HG[idx].max() <= 1.0 and HG[idx].min() >= 0
            HG[idx] = 1 - HG[idx]
        idx += 1

    return HG
def Targets(x, y, BlackBackground, jetter, Bound):
    sizes = [1.0 / 3, 1.0 / 6, 1.0 / 12]
    thickness = [1.0 / 30, 1.0 / 60, 1.0 / 120]
    smoothing = [1.0 / 15, 1.0 / 30, 1.0 / 60]
    paras = zip([0] * 3, sizes, thickness, smoothing, [1] * 3)

    if jetter:
        paras = pert.modulation_of_jetter(paras, 'T')

    T = np.empty(len(paras), dtype=np.object)
    idx = 0
    for par in paras:
        T[idx] = ConcentricRings(bounds=Bound,
                                 aspect_ratio=par[4],
                                 smoothing=par[3],
                                 thickness=par[2],
                                 size=par[1],
                                 orientation=par[0],
                                 xdensity=x,
                                 ydensity=y)()
        if BlackBackground:
            assert T[idx].max() <= 1.0 and T[idx].min() >= 0
            T[idx] = 1 - T[idx]
        idx += 1

    return T
def RadialG(x, y, BlackBackground, jetter, Bound):
    parts = [1] * 4 + [2, 4, 8, 16]
    orien = [np.pi / 2 * j for j in range(4)] + [0] * 4
    smooth = [0.7] * 4 + [0.7] * 4

    paras = zip(orien, smooth, parts)

    if jetter:
        paras = pert.modulation_of_jetter(paras, 'RG')

    RG = np.empty(len(paras), dtype=np.object)
    idx = 0
    for par in paras:
        if par[2] == 1:
            RG[idx] = ig.RadialGrating(bounds=Bound,
                                       parts=par[2],
                                       smoothing=par[1],
                                       orientation=par[0],
                                       xdensity=x,
                                       ydensity=y)()
        else:
            RG[idx] = RadialGrating(bounds=Bound,
                                    parts=par[2],
                                    smoothing=par[1],
                                    orientation=par[0],
                                    xdensity=x,
                                    ydensity=y)()
        if BlackBackground:
            assert RG[idx].max() <= 1.0 and RG[idx].min() >= 0
            RG[idx] = 1 - RG[idx]
        idx += 1

    return RG
def SineG(x, y, BlackBackground, jetter, Bound):
    # creates parameter list
    orientations = [i * np.pi / 12 for i in range(12)]
    frequencies = [3, 6, 12]
    of = list(itertools.product(orientations, frequencies))
    if jetter:
        of = pert.modulation_of_jetter(of, 'SG')

    # generates images and saved into a numpy array
    SG = np.empty(len(of), dtype=np.object)
    idx = 0
    for ith_of in of:
        SG[idx] = ig.SineGrating(bounds=Bound,
                                 phase=np.pi / 2,
                                 orientation=ith_of[0],
                                 frequency=ith_of[1],
                                 xdensity=x,
                                 ydensity=y)()
        # SG[idx] = ig.SineGrating(bounds=Bound, phase=0, orientation=ith_of[0],
        #                           frequency=ith_of[1], xdensity=x, ydensity=y)()

        if BlackBackground:
            assert SG[idx].max() <= 1.0 and SG[idx].min() >= 0
            SG[idx] = 1 - SG[idx]
        idx += 1
    return SG
def SpiralG(x, y, BlackBackground, jetter, Bound):
    turning = [0.2, 0.1, 0.05]
    turning_inc = [0.3, 0.15, 0.075]
    smooth = [0.16, 0.08, 0.04]
    smooth_inc = [0.018, 0.009, 0.0045]
    t_s = zip(turning, turning_inc, smooth, smooth_inc)
    parts = [2, 4, 6, 8]
    t = [p[0] + p[1] * (part / 2 - 1) for p in t_s for part in parts]
    s = [p[2] + p[3] * (part / 2 - 1) for p in t_s for part in parts]

    # turning = [1.0/3,1.0/6,1.0/12]
    # smooth = [0.16,0.08,0.04]
    # parts = [2, 4, 6, 8]
    # t = [p/part for p in turning for part in parts]
    # s = [p/part for p in smooth for part in parts]

    parts_m = [part for p in turning for part in parts]
    paras = zip([0.0] * len(t), t, s, parts_m)

    if jetter:
        paras = pert.modulation_of_jetter(paras, 'SpG')

    SpG = np.empty(len(paras), dtype=np.object)
    idx = 0
    for par in paras:
        SpG[idx] = ig.SpiralGrating(bounds=Bound,
                                    parts=par[3],
                                    turning=par[1],
                                    smoothing=par[2],
                                    orientation=par[0],
                                    xdensity=x,
                                    ydensity=y)()
        if BlackBackground:
            assert SpG[idx].max() <= 1.0 and SpG[idx].min() >= 0
            SpG[idx] = 1 - SpG[idx]
        idx += 1

    return SpG
def Bar(x, y, BlackBackground, jetter, Bound):
    orientations = [i * np.pi / 18 for i in range(18)]
    sizes = [0.5, 0.25]
    paras = list(itertools.product(orientations, sizes))
    if jetter:
        paras = pert.modulation_of_jetter(paras, 'Bar')

    Ba = np.empty(len(paras), dtype=np.object)
    idx = 0
    for par in paras:
        Ba[idx] = ig.Rectangle(bounds=Bound,
                               smoothing=0.015,
                               aspect_ratio=0.1,
                               size=par[1],
                               orientation=par[0],
                               xdensity=x,
                               ydensity=y)()
        if BlackBackground:
            assert Ba[idx].max() <= 1.0 and Ba[idx].min >= 0
            Ba[idx] = 1 - Ba[idx]
        idx += 1

    return Ba