def make_vague(impulse=False): import os import numpy as np import MotionClouds as mc mc.N_X, mc.N_Y, mc.N_frame = 50, 2, 2048 fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame) theta, B_theta = 0., np.pi / 8. alpha, sf_0, B_sf, B_V = 1., .02, .1, .1 seed = 1234565 V_X, V_Y = .1, 0. mc_wave = mc.envelope_gabor(fx, fy, ft, V_X=V_X, V_Y=V_Y, B_V=B_V, theta=theta, B_theta=B_theta, sf_0=sf_0, B_sf=B_sf, alpha=alpha) wave = mc.random_cloud(mc_wave, seed=seed, impulse=impulse) wave -= wave.mean() wave /= np.abs(wave).max() return wave
def MotionCloudNoise(sf_0=0.125, B_sf=3., figure_type='', save=False): mc.N_X, mc.N_Y, mc.N_frame = 128, 128, 1 fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame) name = 'static' env = mc.envelope_gabor(fx, fy, ft, sf_0=sf_0, B_sf=B_sf, B_theta=np.inf, V_X=0., V_Y=0., B_V=0, alpha=.5) z = mc.rectif(mc.random_cloud(env)) z = z.reshape((mc.N_X, mc.N_Y)) if figure_type == 'cmap': fig, ax = plt.subplots(figsize=(13, 10.725)) cmap = ax.pcolor(np.arange(-mc.N_X / 2, mc.N_X / 2), np.arange(-mc.N_X / 2, mc.N_X / 2), MotionCloudNoise(), cmap='Greys_r') fig.colorbar(cmap) if save: plt.savefig('motioncloud_noise.pdf') return fig, ax else: return z
def source(dim, bwd): """ Create motion cloud source """ fx, fy, ft = dim z = mc.envelope_gabor(fx, fy, ft, B_sf=bwd[0], B_V=bwd[1], B_theta=bwd[2]) data = mc.rectif(mc.random_cloud(z)) return data
def generate_random_cloud(theta, B_theta, downscale=1): fx, fy, ft = mc.get_grids(mc.N_X / downscale, mc.N_Y / downscale, 1) mc_i = mc.envelope_gabor(fx, fy, ft, V_X=0., V_Y=0., B_V=0, theta=theta, B_theta=B_theta) im = mc.random_cloud(mc_i) im = (mc.rectif(im) * 255).astype('uint8') fname = 'tmp/%s_%s.png' % (theta, B_theta) imageio.imwrite(fname, im[:, :, 0]) return fname
def generate_cloud(theta, b_theta, sf_0, N_X, N_Y, seed, contrast=1): fx, fy, ft = mc.get_grids(N_X, N_Y, 1) mc_i = mc.envelope_gabor(fx, fy, ft, V_X=0., V_Y=0., B_V=0., sf_0=sf_0, B_sf=sf_0, theta=theta, B_theta=b_theta) im_ = mc.rectif(mc.random_cloud(mc_i, seed=seed), contrast=contrast) return im_[:, :, 0]
def make_vague(impulse=False): name = 'waves' import os import numpy as np import MotionClouds as mc mc.N_X, mc.N_Y, mc.N_frame = 128, 32, 512 fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame) theta, B_theta, B_wave = 0., np.pi/8., .1 alpha, sf_0, B_sf, B_V = 2., .25, .3, 2. alpha, sf_0, B_sf, B_V = 1., .1, .3, 2. seed = 1234565 V_X, V_Y, g = .5, 0., .1 V_X, V_Y, g = .5, 0., 2 loggabor=True B_v = .025 def envelope_gravity(fx, fy, ft, B_wave, g=.1): """ Gravitational envelope: selects the plane corresponding to the speed (V_X, V_Y) with some thickness B_V """ k = fx*V_X+fy*V_Y env = np.exp(-.5*(((ft/.5)**2-g*np.sqrt(((k/.5)**2)))**2/(B_wave*mc.frequency_radius(fx, fy, ft, ft_0=np.inf))**2)) env *= (ft*k) < 0 return env def envelope_gabor_wave(fx, fy, ft, B_wave, V_X=mc.V_X, V_Y=mc.V_Y, B_V=mc.B_V, B_v=1., sf_0=mc.sf_0, B_sf=mc.B_sf, loggabor=mc.loggabor, theta=mc.theta, B_theta=mc.B_theta, alpha=mc.alpha): """ Returns the Motion Cloud kernel """ envelope = mc.envelope_gabor(fx, fy, ft, V_X=V_X, V_Y=V_Y, B_V=B_V, sf_0=sf_0, B_sf=B_sf, loggabor=loggabor, theta=theta, B_theta=B_theta, alpha=alpha) envelope *= envelope_gravity(fx, fy, ft, B_wave=B_wave) return envelope B_v_low, B_v_high = .025, .1 mc_vague = envelope_gabor_wave(fx, fy, ft, V_X=1., V_Y=0., B_wave=B_v_low, B_V=B_V, theta=theta, B_theta=B_theta, sf_0=sf_0, B_sf=B_sf, alpha=alpha) return mc.rectif(mc.random_cloud(mc_vague, seed=seed, impulse=impulse))
def create_stimulus(info, return_env=False): control(info) import numpy as np fx, fy, ft = mc.get_grids(info[height], info[width], info[frame]) env_color = 1 env_orientation = 1 env_radial = 1 env_speed = 1 if (info[color] == True): if (info[ft_0] == True): ft_0_color = np.inf else: ft_0_color = 1 env_color = mc.envelope_color(fx, fy, ft, alpha=info[alpha], ft_0=ft_0_color) if (info[orientation] == True): env_orientation = mc.envelope_orientation(fx, fy, ft, theta=info[theta], B_theta=info[B_theta]) if (info[radial] == True): if (info[ft_0b] == True): ft_0_radial = np.inf else: ft_0_radial = 1 env_radial = mc.envelope_radial(fx, fy, ft, sf_0=info[sf_0], B_sf=info[B_sf], ft_0=ft_0_radial, loggabor=info[loggabor]) if (info[speed] == True): env_speed = mc.envelope_speed(fx, fy, ft, V_X=info[V_X], V_Y=info[V_Y], B_V=info[B_V]) env = env_color * env_orientation * env_radial * env_speed if (info[random_cloud] == True): if (info[seed] == 'None'): seed_t = None else: seed_t = int(info[seed]) env = mc.random_cloud(env, seed=seed_t, impulse=info[impulse], do_amp=info[do_amp]) env = mc.rectif(env, contrast=1.) env = env * 255 if (return_env == True): return (env) stimulus = np.zeros([info[height], info[width], info[frame], 3]).astype(int) if (info[isoluminance] == True): stimulus[:, :, :, 0] = env stimulus[:, :, :, 1] = 255 - env stimulus[:, :, :, 2] = 127 else: for i in range(3): stimulus[:, :, :, i] = env[:, :, :] return(stimulus)
def make_vague(impulse=False): import os import numpy as np import MotionClouds as mc mc.N_X, mc.N_Y, mc.N_frame = 50, 2, 2048 fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame) theta, B_theta = 0., np.pi/8. alpha, sf_0, B_sf, B_V = 1., .02, .1, .1 seed = 1234565 V_X, V_Y = .1, 0. mc_wave = mc.envelope_gabor(fx, fy, ft, V_X=V_X, V_Y=V_Y, B_V=B_V, theta=theta, B_theta=B_theta, sf_0=sf_0, B_sf=B_sf, alpha=alpha) wave = mc.random_cloud(mc_wave, seed=seed, impulse=impulse) wave -= wave.mean() wave /= np.abs(wave).max() return wave
def wave(self): filename = f'{self.cachepath}/{self.opt.tag}_wave.npy' if self.opt.cache and os.path.isfile(filename): z = np.load(filename) else: # A simplistic model of a wave using https://github.com/NeuralEnsemble/MotionClouds import MotionClouds as mc fx, fy, ft = mc.get_grids(self.opt.nx, self.opt.ny, self.opt.nframe) env = mc.envelope_gabor(fx, fy, ft, V_X=self.opt.V_Y, V_Y=self.opt.V_X, B_V=self.opt.B_V, sf_0=self.opt.sf_0, B_sf=self.opt.B_sf, theta=self.opt.theta, B_theta=self.opt.B_theta) z = mc.rectif(mc.random_cloud(env, seed=self.opt.seed)) if self.opt.cache: np.save(filename, z) return z
def creation_stimulus(info, screen, param, name_database='blackwhite'): import MotionClouds as mc from MotionClouds.display import rectif # from libpy import lena if (param.condition == 1): stimulus = (np.random.rand(info[NS_X]/2, info[NS_Y]/2) > .5) # stimulus = (np.random.rand(64, 64) > .5) elif (param.condition == 2): im = Image(ParameterSet({'N_X' : info[NS_X], 'N_Y' : info[NS_Y], 'figpath':'.', 'matpath':'.', 'datapath':'database/', 'do_mask':False, 'seed':None})) stimulus, filename, croparea = im.patch(name_database) # stimulus = lena() stimulus = np.rot90(np.fliplr(stimulus)) stimulus = rectif(stimulus, contrast=1.) else: fx, fy, ft = mc.get_grids(info[NS_X], info[NS_Y], 1) if (param.condition == 3): t, b, B_sf, sf_0 = 0, np.pi/32, 0.1, 0.15 if (param.condition == 4): t, b, B_sf, sf_0= 0, np.pi/8, 0.1, 0.15 if (param.condition == 5): t, b, B_sf, sf_0= 0, np.pi/2, 0.1, 0.15 if (param.condition == 6): t, b, B_sf, sf_0= 0, np.pi/32, 0.1, 0.03 if (param.condition == 7): t, b, B_sf, sf_0= 0, np.pi/32, 0.1, 0.075 if (param.condition == 8): t, b, B_sf, sf_0= 0, np.pi/32, 0.25, 0.15 if (param.condition == 9): t, b, B_sf, sf_0= 0, np.pi/32, 0.5, 0.15 fx, fy, ft = mc.get_grids(info[NS_X], info[NS_Y], 1) cloud = mc.random_cloud(mc.envelope_gabor(fx, fy, ft, sf_0=sf_0, B_sf=B_sf, theta=t, B_theta=b, B_V=1000.)) cloud = rectif(cloud, contrast=1.) stimulus = cloud[:, :, 0] return (stimulus)
# Setting up the conditions: condList = data.importConditions(conditionsFilePath) grtList = [] for thisCondition in condList: # grating name: grtSz = thisCondition['szL'] thisSf = thisCondition['sfL'] thisBsf = thisCondition['BsfL'] if thisCondition['dirL'] < 0: # this means clockwise or CCW motion thisV = 0 else: # translational motion thisV = thisCondition['vL'] thisBv = thisCondition['BvL'] grtName = precompiledDir + os.sep + 'mc_' + str(thisV) + '_sf' + str(thisSf) + \ '_bsf' + str(thisBsf) + '_bv' + str(thisBv) + '_sz' + str(grtSz) if grtName not in grtList: grtList.append(grtName) # compiling the gratings: szX = grtSz szY = szX fx, fy, ft = mc.get_grids(szX, szY, nFrames) grtCol = mc.envelope_color(fx, fy, ft) z = mc.envelope_gabor(fx, fy, ft, sf_0=thisSf, B_sf=thisBsf, V_X=thisV, B_V=thisBv, B_theta=np.inf) zcl = mc.random_cloud(grtCol * z) grtL = 2*mc.rectif(zcl) - 1 # saving the gratings: np.save(grtName, grtL) # mc.figures(grtL, grtName, vext='.mkv') print 'precompiled ' + grtName
#import psychopy #import vispy #from vispy import scene #print(dir(mc)) #from vispy.visuals.transforms import STTransform,MatrixTransform # params: sf0 = 0.1 bsf = .05 vX = 9.6 vY = 0 bV = .5 theta = 60 bTheta = 1.27 #4/3.14 # define Fourier domain fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, 10) #mc.N_frame) # define an envelope envelope = mc.envelope_gabor(fx, fy, ft, V_X=vX, V_Y=vY, B_V=bV, sf_0=sf0, B_sf=bsf, theta=theta, B_theta=bTheta, alpha=1.) # Visualize the Fourier Spectrum #mc.visualize(envelope) #mc.figures(envelope,'test') movie=mc.random_cloud(envelope) movie=mc.rectif(movie) name = 'sf' + str(sf0) + '_bsf' + str(bsf) + '_vX' + str(vX) + '_vY' + str(vY) + '_bV' + str(bV) + '_th' + str(theta) + '_bTh' + str(bTheta) print name mypath = '/c/Users/Egor/Dropbox/Projects/mc/mc/test' #mc.cube(movie, name=name+'_cube') mc.anim_save(movie, name, display=False, vext='.mp4') #prev .mp4
info['timeStr'] = time.strftime("%b_%d_%H%M", time.localtime()) fileName = 'data/' + experiment + info['observer'] + '_' + info['timeStr'] + '.pickle' #save to a file for future use (ie storing as defaults) if dlg.OK: misc.toFile(fileName, info) else: print('Interrupted gui... quitting') core.quit() #user cancelled. quit print('generating data') fx, fy, ft = mc.get_grids(info['N_X'], info['N_Y'], info['N_frame_total']) color = mc.envelope_color(fx, fy, ft) up = 2*mc.rectif(mc.random_cloud(color * mc.envelope_gabor(fx, fy, ft, V_X=+.5))) - 1 down = 2*mc.rectif(mc.random_cloud(color * mc.envelope_gabor(fx, fy, ft, V_X=-.5))) - 1 print('go! ') win = visual.Window([info['screen_width'], info['screen_height']], fullscr=True) stim = visual.GratingStim(win, size=(info['screen_height'], info['screen_height']), units='pix', interpolate=True, mask = 'gauss', autoLog=False)#this stim changes too much for autologging to be useful wait_for_response = visual.TextStim(win, text = u"?", units='norm', height=0.15, color='DarkSlateBlue', pos=[0., -0.], alignHoriz='center', alignVert='center' ) wait_for_next = visual.TextStim(win,
name = 'concentric' play = False #True play = True #initialize fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame) color = mc.envelope_color(fx, fy, ft) name_ = mc.figpath + name seed = 123456 im = np.zeros((mc.N_X, mc.N_Y, mc.N_frame)) name_ = mc.figpath + name N = 20 if mc.anim_exist(name_): for i_N in xrange(N): im_ = mc.random_cloud(color * mc.envelope_gabor(fx, fy, ft, V_X=0., V_Y=0.), seed=seed+i_N) if i_N == 0: phase = 0.5 + 0. * im_[0, 0, :]#mc.N_X/2, mc.N_Y/2, :] #im += im_ - im_[mc.N_X/2, mc.N_Y/2, :] + phase im += im_ - im_[0, 0, :] + phase if play: mc.play(mc.rectif(im)) else: mc.anim_save(mc.rectif(im), name_) # mplayer figures/concentric.mpg -fs -loop 0
info['timeStr'] = time.strftime("%b_%d_%H%M", time.localtime()) fileName = 'data/discriminating_v2_' + info['observer'] + '_' + info['timeStr'] + '.pickle' #save to a file for future use (ie storing as defaults) if dlg.OK: misc.toFile(fileName, info) else: print('Interrupted gui... quitting') core.quit() #user cancelled. quit print('generating data') alphas = [-1., -.5, 0., 0.5, 1., 1.5, 2.] fx, fy, ft = mc.get_grids(info['N_X'], info['N_Y'], info['N_frame_total']) colors = [mc.envelope_color(fx, fy, ft, alpha=alpha) for alpha in alphas] slows = [2*mc.rectif(mc.random_cloud(color * mc.envelope_gabor(fx, fy, ft, V_Y=0., V_X = 1.1, B_sf = 10.))) - 1 for color in colors] fasts = [2*mc.rectif(mc.random_cloud(color * mc.envelope_gabor(fx, fy, ft, V_Y=0., V_X = 0.9, B_sf = 10.))) - 1 for color in colors] print('go! ') win = visual.Window([info['screen_width'], info['screen_height']], fullscr=True) stimLeft = visual.GratingStim(win, size=(info['screen_width']/2, info['screen_width']/2), pos=(-info['screen_width']/4, 0), units='pix', interpolate=True, mask = 'gauss', autoLog=False)#this stim changes too much for autologging to be useful stimRight = visual.GratingStim(win, size=(info['screen_width']/2, info['screen_width']/2),
#initialize fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame) #fx, fy, ft = mc.get_grids(256, 256, 256) #fx, fy, ft = mc.get_grids(512, 512, 128) color = mc.envelope_color(fx, fy, ft) name_ = mc.figpath + name # explore parameters for B_sf in [0.025, 0.05, 0.1, 0.2, 0.4, 0.8]: name_ = mc.figpath + name + '-B_sf' + str(B_sf).replace('.', '_') if mc.anim_exist(name_, vext=vext): z = color * mc.envelope_gabor(fx, fy, ft, B_sf=B_sf, B_theta=np.inf) # mc.visualize(z, name=name_ + '_envelope') im = mc.rectif(mc.random_cloud(z)) # mc.cube(im, name=name_ + '_cube') mc.anim_save(im, name_, display=False, vext=vext) # mc.anim_save(im, name_, display=False, vext='.gif') if DEBUG: # control enveloppe's shape z_low = mc.envelope_gabor(fx, fy, ft, B_sf=0.037, loggabor=False) z_high = mc.envelope_gabor(fx, fy, ft, B_sf=0.15, loggabor=False) import pylab, numpy pylab.clf() fig = pylab.figure(figsize=(12, 12)) a1 = fig.add_subplot(111) a1.contour(numpy.fliplr(z_low[:mc.N_X/2, mc.N_Y/2, mc.N_frame/2:].T), [z_low.max()*.5], colors='red')
name = 'contrast_methods-' #initialize fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame) color = mc.envelope_color(fx, fy, ft) ext = '.zip' contrast = 0.25 B_sf = 0.3 for method in ['Michelson', 'energy']: z = color * mc.envelope_gabor(fx, fy, ft, B_sf=B_sf) name_ = mc.figpath + name + method + '-contrast-' + str(contrast).replace('.', '_') + '-B_sf-' + str(B_sf).replace('.','_') if mc.anim_exist(name_): im = np.ravel(mc.random_cloud(z)) im_norm = mc.rectif(mc.random_cloud(z), contrast, method=method, verbose=True) plt.figure() plt.subplot(111) plt.title('Michelson normalised Histogram Ctr: ' + str(contrast)) plt.ylabel('pixel counts') plt.xlabel('grayscale') bins = int((np.max(im_norm[:])-np.min(im_norm[:])) * 256) plt.xlim([0, 1]) plt.hist(np.ravel(im_norm), bins=bins, normed=False, facecolor='blue', alpha=0.75) plt.savefig(name_) def image_entropy(img): """calculate the entropy of an image""" histogram = img.histogram()
# explore parameters for alpha in [0.0, 0.5, 1.0, 1.5, 2.0]: # resp. white(0), pink(1), red(2) or brownian noise (see http://en.wikipedia.org/wiki/1/f_noise name_ = name + '-alpha-' + str(alpha).replace('.', '_') z = mc.envelope_color(fx, fy, ft, alpha) mc.figures(z, name_) for ft_0 in [0.125, 0.25, 0.5, 1., 2., 4., np.inf]:# time space scaling name_ = name + '-ft_0-' + str(ft_0).replace('.', '_') z = mc.envelope_color(fx, fy, ft, ft_0=ft_0) mc.figures(z, name_) for contrast in [0.1, 0.25, 0.5, 0.75, 1.0, 2.0]: name_ = name + '-contrast-' + str(contrast).replace('.', '_') im = mc.rectif(mc.random_cloud(mc.envelope_color(fx, fy, ft)), contrast) mc.anim_save(im, os.path.join(mc.figpath, name_), display=False) for contrast in [0.1, 0.25, 0.5, 0.75, 1.0, 2.0]: name_ = name + '-energy_contrast-' + str(contrast).replace('.', '_') im = mc.rectif(mc.random_cloud(mc.envelope_color(fx, fy, ft)), contrast, method='energy') mc.anim_save(im, os.path.join(mc.figpath, name_), display=False) for seed in [123456 + step for step in range(7)]: name_ = name + '-seed-' + str(seed) mc.anim_save(mc.rectif(mc.random_cloud(mc.envelope_color(fx, fy, ft), seed=seed)), os.path.join(mc.figpath, name_), display=False) for size in range(5, 7): N_X, N_Y, N_frame = 2**size, 2**size, 2**size fx, fy, ft = mc.get_grids(N_X, N_Y, N_frame) ft_0 = N_X/float(N_frame)
colOdd = [150,1,1] # green colEven = [330,sat,1] # red is adjusted and is assigned to gratings in even frames # initiating the gratings if precompileMode: grtL = np.load(precompiledDir + os.sep + 'mc_' + '{0:.1f}'.format(vL) + '_sf' + str(sfL) + '_bsf' + str(BsfL) + '_bv' + str(BvL) + '_sz' + str(szL) + '.npy') grtR = np.load(precompiledDir + os.sep + 'mc_' + '{0:.1f}'.format(vR) + '_sf' + str(sfR) + '_bsf' + str(BsfR) + '_bv' + str(BvR) + '_sz' + str(szR) + '.npy') else: fx, fy, ft = mc.get_grids(szL, szL, nFrames) grtCol = mc.envelope_color(fx, fy, ft) grtL = 2*mc.rectif(mc.random_cloud(grtCol * mc.envelope_gabor(fx, fy, ft, sf_0=sfL, B_sf=BsfL, B_V=BvL, V_X=vL, B_theta=np.inf))) - 1 fx, fy, ft = mc.get_grids(szR, szR, nFrames) grtCol = mc.envelope_color(fx, fy, ft) grtR = 2*mc.rectif(mc.random_cloud(grtCol * mc.envelope_gabor(fx, fy, ft, sf_0=sfR, B_sf=BsfR, B_V=BvR, V_X=vR, B_theta=np.inf))) - 1 # Creating a mask, which is fixed for a given trial: curMask = combinedMask(fovGap, fovFade, periGap, periFade) # Using the mask to assign both the greyscale values and the mask for our color masks: colMaskL.tex = (curMask + 1)/2 colMaskL.mask = curMask colMaskR.tex = (curMask + 1)/2 colMaskR.mask = curMask
fy, ft, V_X=1., V_Y=0., B_V=.1, sf_0=.15, B_sf=.1, theta=np.pi / 3, B_theta=np.pi / 12, alpha=1.) # On génère le cloud # In[4]: movie = mc.random_cloud(envelope) movie = mc.rectif(movie) # Une image instantanée à t = 0 # In[5]: plt.figure(figsize=(8, 6)) plt.imshow(movie[:, :, 0], cmap=plt.cm.gray) # Et on sauvegarde le stimulus au format desiré (paramètre vext) # * Pour faire du .mp4, il faut installer ffmpeg (sudo apt install ffmpeg), c'est la faute a Linux, désolé ! # * Pour faire du .png, le chemin spécifié devient un fichier dans lequel seront organisé les images # In[15]:
hzn1 = mc.np.zeros((N_orient * N_X, N_orient * N_X, N_frame)) for i, x_i in enumerate(np.linspace(-1, 1., N_orient)): for j, x_j in enumerate(np.linspace(-1, 1., N_orient)): V_X = 2 * x_i / (1 + x_i**2) V_Y = 2 * x_j / (1 + x_j**2) # f_0 = ... # theta = np.arctan2(V_Y, V_X) env = mc.envelope_gabor(fx, fy, ft, V_X=V_X, V_Y=V_Y, B_theta=np.inf, B_sf=np.inf) speed2 = mc.random_cloud(env, seed=seed) hzn1[i * N_X:(i + 1) * N_X, j * N_Y:(j + 1) * N_Y, :] = speed2 # %% # since mc.rectif brings values in range 0 to 1, we need to multiply by 2 and # subtract 1 in order to get range -1 to 1, which psychopy needsZ z = 2 * mc.rectif(hzn1, contrast=1.0) - 1. # reverse z in third dimension z = z[:, :, ::-1] # scramble z in third dimension to generate the control scramble = np.random.permutation(z.shape[2]) z = z[:, :, scramble]
table += '||<width="33%">{{attachment:' + name_ + '.png||width=100%}}||<width="33%">{{attachment:' + name_ + '_cube.png||width=100%}}||<width="33%">{{attachment:' + name_ + '.gif||width=100%}}||\n' name_ = name + '_high' if mc.anim_exist(name_): mc2 = envelope_gabor_wave(fx, fy, ft, V_X=1., V_Y=0., B_v=B_v_high, B_V=B_V, theta=theta, B_theta=B_theta, sf_0=sf_0, B_sf=B_sf, alpha=alpha) mc.figures(mc2, name_, vext=vext, seed=seed) table += '||{{attachment:' + name_ + '.png||width=100%}}||{{attachment:' + name_ + '_cube.png||width=100%}}||{{attachment:' + name_ + '.gif||width=100%}}||\n' table += '||||||<align="justify"> This figure shows how one can create stimuli similar to !MotionCloud stimuli that have a dstribution according to the laws of gravitational waves (that is with temporal frequency proportional to the square root of spatial frequency for deep water conditions -- in the shallow water conditions, normal MCs are a good approximation). Note that phase speed (following a maximum) is twice faster than group speed (following a dot). The two lines correspond to different bandwitdhs for the spread around the physical law (width of the manifold). <<BR>> Columns represent isometric projections of a cube. The left column displays iso-surfaces of the spectral envelope by displaying enclosing volumes at 5 different energy values with respect to the peak amplitude of the Fourier spectrum. The middle column shows an isometric view of the faces of the movie cube. The first frame of the movie lies on the x-y plane, the x-t plane lies on the top face and motion direction is seen as diagonal lines on this face (vertical motion is similarly see in the y-t face). The third column displays the actual movie as an animation. ||\n' table += '\n\n' if True:#try: from enthought.mayavi import mlab downscale = 1 x, y = np.mgrid[(-mc.N_X//2):((mc.N_X-1)//2 + 1), (-mc.N_Y//2):((mc.N_Y-1)//2 + 1)] fig = mlab.figure(1, size=(1600/downscale, 1200/downscale), fgcolor=(1, 1, 1), bgcolor=(0.5, 0.5, 0.5)) z = mc.rectif(mc.random_cloud(mc1)) for frame in range(mc.N_frame): mlab.clf() #s = mlab.SurfRegular(mc1[:, :, frame]) #s = mlab.surf(mc1[:, :, frame]) # http://docs.enthought.com/mayavi/mayavi/auto/example_wigner.html surf_ = mlab.surf(x, y, z[:, :, frame], colormap='bone', warp_scale=15, vmin=-1., vmax=1.) mlab.outline(surf_, color=(.7, .7, .7)) #fig.add(s) view = mlab.view(azimuth=290., elevation=60, distance='auto', focalpoint='auto') mlab.savefig('_MC_%03d.png' % frame, magnification=0.5) import os os.system('ffmpeg -v 0 -y -sameq -loop_output 0 -i _MC_%03d.png MC_wave.mpg') os.system('convert _MC_%03d.png MC_wave.gif') #except: # print('TODO: visualise the free surface in 3D')
def create_stimulus(info, return_env=False): control(info) import numpy as np fx, fy, ft = mc.get_grids(info[height], info[width], info[frame]) env_color = 1 env_orientation = 1 env_radial = 1 env_speed = 1 if (info[color] == True): if (info[ft_0] == True): ft_0_color = np.inf else: ft_0_color = 1 env_color = mc.envelope_color(fx, fy, ft, alpha=info[alpha], ft_0=ft_0_color) if (info[orientation] == True): env_orientation = mc.envelope_orientation(fx, fy, ft, theta=info[theta], B_theta=info[B_theta]) if (info[radial] == True): if (info[ft_0b] == True): ft_0_radial = np.inf else: ft_0_radial = 1 env_radial = mc.envelope_radial(fx, fy, ft, sf_0=info[sf_0], B_sf=info[B_sf], ft_0=ft_0_radial, loggabor=info[loggabor]) if (info[speed] == True): env_speed = mc.envelope_speed(fx, fy, ft, V_X=info[V_X], V_Y=info[V_Y], B_V=info[B_V]) env = env_color * env_orientation * env_radial * env_speed if (info[random_cloud] == True): if (info[seed] == 'None'): seed_t = None else: seed_t = int(info[seed]) env = mc.random_cloud(env, seed=seed_t, impulse=info[impulse], do_amp=info[do_amp]) env = mc.rectif(env, contrast=1.) env = env * 255 if (return_env == True): return (env) stimulus = np.zeros([info[height], info[width], info[frame], 3]).astype(int) if (info[isoluminance] == True): stimulus[:, :, :, 0] = env stimulus[:, :, :, 1] = 255 - env stimulus[:, :, :, 2] = 127 else: for i in range(3): stimulus[:, :, :, i] = env[:, :, :] return (stimulus)
import libpy as lb import numpy as np import sys, os import MotionClouds as mc h = 400 w = 200 f = 64 fx, fy, ft = mc.get_grids(h, w, f) color = mc.envelope_color(fx, fy, ft) env = color * mc.envelope_speed(fx, fy, ft) env = mc.envelope_gabor(fx, fy, ft) env = mc.random_cloud(env) env = mc.rectif(env, contrast=1.) tomat = env env = env * 255 stimulus = np.zeros([h, w, f, 3]).astype(int) i = 0 while (i != f): if (i % 2 == 0): stimulus[:, :, i, 0] = env[:, :, i] stimulus[:, :, i, 1] = 0 # 128 #env[:, :, i] stimulus[:, :, i, 2] = 0 # 255 - env[:, :, i] else: #stimulus[:, :, i, 0] = 255 - env[:, :, i] stimulus[:, :, i, 1] = 255 - env[:, :, i] stimulus[:, :, i, 0] = 0 #128 #env[:, :, i] stimulus[:, :, i, 2] = 0 #env[:, :, i] # stimulus[:, :, i, :] = 255 - env[:, :, i, np.newaxis]
w, h = 2560, 1440 # width and height of the stimulus w_stim, h_stim = 1024, 1024 loops = 1 import MotionClouds as mc print 'started get_grids' fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame) print 'started color' color = mc.envelope_color(fx, fy, ft) print 'started enveope' env = color *(mc.envelope_gabor(fx, fy, ft, V_X=1.) + mc.envelope_gabor(fx, fy, ft, V_X=-1.)) print 'started rectif' z = 2*mc.rectif(mc.random_cloud(env), contrast=.5) -1. print 'ended motion clouds' #from pyglet.gl import gl_info from psychopy import visual, core, event, logging logging.console.setLevel(logging.DEBUG) print 'started stim' win = visual.Window([w, h], fullscr=True) stim = visual.GratingStim(win, size=(w_stim, h_stim), units='pix', interpolate=True, mask='gauss', autoLog=False)#this stim changes too much for autologging to be useful print 'ended stim'
def make_vague(impulse=False): name = "waves" import os import numpy as np import MotionClouds as mc mc.N_X, mc.N_Y, mc.N_frame = 128, 32, 512 fx, fy, ft = mc.get_grids(mc.N_X, mc.N_Y, mc.N_frame) theta, B_theta, B_wave = 0.0, np.pi / 8.0, 0.1 alpha, sf_0, B_sf, B_V = 2.0, 0.25, 0.3, 2.0 alpha, sf_0, B_sf, B_V = 1.0, 0.1, 0.3, 2.0 seed = 1234565 V_X, V_Y, g = 0.5, 0.0, 0.1 V_X, V_Y, g = 0.5, 0.0, 2 loggabor = True B_v = 0.025 def envelope_gravity(fx, fy, ft, B_wave, g=0.1): """ Gravitational envelope: selects the plane corresponding to the speed (V_X, V_Y) with some thickness B_V """ k = fx * V_X + fy * V_Y env = np.exp( -0.5 * ( ((ft / 0.5) ** 2 - g * np.sqrt(((k / 0.5) ** 2))) ** 2 / (B_wave * mc.frequency_radius(fx, fy, ft, ft_0=np.inf)) ** 2 ) ) env *= (ft * k) < 0 return env def envelope_gabor_wave( fx, fy, ft, B_wave, V_X=mc.V_X, V_Y=mc.V_Y, B_V=mc.B_V, B_v=1.0, sf_0=mc.sf_0, B_sf=mc.B_sf, loggabor=mc.loggabor, theta=mc.theta, B_theta=mc.B_theta, alpha=mc.alpha, ): """ Returns the Motion Cloud kernel """ envelope = mc.envelope_gabor( fx, fy, ft, V_X=V_X, V_Y=V_Y, B_V=B_V, sf_0=sf_0, B_sf=B_sf, loggabor=loggabor, theta=theta, B_theta=B_theta, alpha=alpha, ) envelope *= envelope_gravity(fx, fy, ft, B_wave=B_wave) return envelope B_v_low, B_v_high = 0.025, 0.1 mc_vague = envelope_gabor_wave( fx, fy, ft, V_X=1.0, V_Y=0.0, B_wave=B_v_low, B_V=B_V, theta=theta, B_theta=B_theta, sf_0=sf_0, B_sf=B_sf, alpha=alpha, ) return mc.rectif(mc.random_cloud(mc_vague, seed=seed, impulse=impulse))