def concentration_array_demo(psr, dt=0.01, t_max=8, draw_iter_interval=50): """ Demonstration of setting up plume model and processing the outputted puff arrays with the ConcentrationArrayGenerator class, the resulting arrays being displayed with the matplotlib imshow function. """ # define simulation region wind_region = models.Rectangle(0., -2., 10., 2.) sim_region = models.Rectangle(0., -1., 2., 1.) # set up wind model wind_model = models.WindModel(wind_region, 21, 11, noise_gain=0, u_av=0.47, char_time=3.5, amplitude=0.02) # set up plume model plume_model = models.PlumeModel(sim_region, (0.1, 0., 0.), wind_model, centre_rel_diff_scale=0.6, puff_release_rate=50, puff_init_rad=0.001, puff_spread_rate=0.0001) # set up concentration array generator array_gen = processors.ConcentrationArrayGenerator(sim_region, 0.01, 500, 500, 1.) # set up figure fig = _set_up_figure('Concentration field array demo') # display initial concentration field as image conc_array = array_gen.generate_single_array(plume_model.puff_array) im_extents = (sim_region.x_min, sim_region.x_max, sim_region.y_min, sim_region.y_max) conc_im = plt.imshow(conc_array.T, extent=im_extents, vmin=0, vmax=3e4, cmap=cm.binary_r) conc_im.axes.set_xlabel('x') conc_im.axes.set_ylabel('y') # define update and draw functions def update_func(dt, t): wind_model.update(dt) plume_model.update(dt) draw_func = lambda: conc_im.set_data( array_gen.generate_single_array(plume_model.puff_array).T) # start simulation loop _simulation_loop(dt, t_max, draw_iter_interval, update_func, draw_func, psr) plt.close() return fig
def wind_model_demo(dt=0.01, t_max=20, draw_iter_interval=20): """ Demonstration of setting up wind model and displaying with matplotlib quiver plot function. """ # define simulation region wind_region = models.Rectangle(-8, -2, 8, 2) grid_spacing = 0.8 wind_nx = int(wind_region.w / grid_spacing) + 1 wind_ny = int(wind_region.h / grid_spacing) + 1 # set up wind model wind_model = models.WindModel(wind_region, wind_nx, wind_ny, noise_gain=10., noise_damp=0, noise_bandwidth=2., u_av=3) # generate figure and attach close event fig, time_text = _set_up_figure('Wind model demo') # create quiver plot of initial velocity field vf_plot = plt.quiver(wind_model.x_points, wind_model.y_points, wind_model.velocity_field[:, :, 0].T, wind_model.velocity_field[:, :, 1].T, width=0.003) # expand axis limits to make vectors at boundary of field visible plt.axis(plt.axis() + np.array([-0.5, 0.5, -0.5, 0.5])) # define update and draw functions update_func = lambda dt, t: wind_model.update(dt) draw_func = lambda: vf_plot.set_UVC(wind_model.velocity_field[:, :, 0].T, wind_model.velocity_field[:, :, 1].T) # start simulation loop _simulation_loop(dt, t_max, time_text, draw_iter_interval, update_func, draw_func) return fig
def wind_model_demo(dt=0.01, t_max=100, steps_per_frame=20, seed=DEFAULT_SEED): """Set up wind model and animate velocity field with quiver plot. Parameters ---------- dt : float Simulation timestep. t_max : float End time to simulate to. steps_per_frame: integer Number of simulation time steps to perform between animation frames. seed : integer Seed for random number generator. Returns ------- fig : Figure Matplotlib figure object. ax : AxesSubplot Matplotlib axis object. anim : FuncAnimation Matplotlib animation object. """ rng = np.random.RandomState(seed) # define simulation region wind_region = models.Rectangle(x_min=0., x_max=100., y_min=-25., y_max=25.) # set up wind model wind_model = models.WindModel(wind_region, 21, 11, rng=rng) # let simulation run for 10s to equilibrate wind model for t in np.arange(0, 10, dt): wind_model.update(dt) # generate figure and attach close event fig, ax, title = set_up_figure() # create quiver plot of initial velocity field vf_plot = ax.quiver(wind_model.x_points, wind_model.y_points, wind_model.velocity_field.T[0], wind_model.velocity_field.T[1], width=0.003) # expand axis limits to make vectors at boundary of field visible ax.axis(ax.axis() + np.array([-0.25, 0.25, -0.25, 0.25])) ax.set_xlabel('x-coordinate / m') ax.set_ylabel('y-coordinate / m') ax.set_aspect(1) fig.tight_layout() # define update function @update_decorator(dt, title, steps_per_frame, [wind_model]) def update(i): vf_plot.set_UVC(wind_model.velocity_field.T[0], wind_model.velocity_field.T[1]) return [vf_plot] # create animation object n_frame = int(t_max / (dt * steps_per_frame) + 0.5) anim = FuncAnimation(fig, update, n_frame, blit=True) return fig, ax, anim
def create_trajectory_data(job_file_name='job.json', data_file_name='data.json', titles_file_name='titles.json'): with open(job_file_name) as data_file: cd = json.load(data_file) #constants dictionary sim_region = models.Rectangle(0., -1., 4., 1.) #call the base navigator. the competing navigators in the simulation retain #any parameter of navigator1 that isn't changed navigator1 = mothpy_models.MothModular(sim_region, cd['x_start'], cd['y_start'], cd['nav_type'], 2, cd['wait_type']) navigator1.base_turn_angle = cd['base_turn_angle'] navigator1.threshold = cd['threshold'] navigator1.duration = cd['duration'] #set up a large number of navigators with different properties navigators = [] navigator_titles = [] def call_navigators(wait, cast, nav): for j in range(10): for i in range(20): new_navigator = copy.copy(navigator1) new_navigator.wait_type = wait new_navigator.cast_type = cast new_navigator.nav_type = nav new_navigator.y = 450 - i * 3 new_navigator.x = 499 - j title = \ ' cast - ' + str(new_navigator.cast_type) \ + '; nav - ' + str(new_navigator.nav_type) \ + str(len(navigators)) navigators.append(new_navigator) navigator_titles.append(title) call_navigators(1, 2, 'alex') #A? call_navigators(1, 3, 'alex') #B? call_navigators(1, 'carde2', 1) #C? call_navigators(1, 'carde1', 1) #D? #run the simulation - each navigator runs through the exact same conditions dict_list = moth_simulation(cd['num_it'], navigators, cd['t_max'], cd['char_time'], cd['amplitude'], cd['dt'], cd['puff_release_rate'], cd['puff_spread_rate'], 1, False) with open(data_file_name, 'w') as outfile: json.dump(dict_list, outfile) return navigator_titles
def plume_model_demo(dt=0.01, t_max=100, steps_per_frame=200, seed=DEFAULT_SEED): """Set up plume model and animate puffs overlayed over velocity field. Puff positions displayed using Matplotlib `scatter` plot function and velocity field displayed using `quiver` plot function. plot and quiver functions. Parameters ---------- dt : float Simulation timestep. t_max : float End time to simulate to. steps_per_frame: integer Number of simulation time steps to perform between animation frames. seed : integer Seed for random number generator. Returns ------- fig : Figure Matplotlib figure object. ax : AxesSubplot Matplotlib axis object. anim : FuncAnimation Matplotlib animation object. """ rng = np.random.RandomState(seed) # define simulation region sim_region = models.Rectangle(x_min=0., x_max=100, y_min=-25., y_max=25.) # set up wind model wind_model = models.WindModel(sim_region, 21, 11, rng=rng) # let simulation run for 10s to equilibrate wind model for t in np.arange(0, 10, dt): wind_model.update(dt) # set up plume model plume_model = models.PlumeModel(sim_region, (5., 0., 0.), wind_model, rng=rng) # set up figure window fig, ax, title = set_up_figure() # create quiver plot of initial velocity field # quiver expects first array dimension (rows) to correspond to y-axis # therefore need to transpose vf_plot = plt.quiver(wind_model.x_points, wind_model.y_points, wind_model.velocity_field.T[0], wind_model.velocity_field.T[1], width=0.003) # expand axis limits to make vectors at boundary of field visible ax.axis(ax.axis() + np.array([-0.25, 0.25, -0.25, 0.25])) # draw initial puff positions with scatter plot radius_mult = 200 pp_plot = plt.scatter(plume_model.puff_array[:, 0], plume_model.puff_array[:, 1], radius_mult * plume_model.puff_array[:, 3]**0.5, c='r', edgecolors='none') ax.set_xlabel('x-coordinate / m') ax.set_ylabel('y-coordinate / m') ax.set_aspect(1) fig.tight_layout() # define update function @update_decorator(dt, title, steps_per_frame, [wind_model, plume_model]) def update(i): # update velocity field quiver plot data vf_plot.set_UVC(wind_model.velocity_field[:, :, 0].T, wind_model.velocity_field[:, :, 1].T) # update puff position scatter plot positions and sizes pp_plot.set_offsets(plume_model.puff_array[:, :2]) pp_plot._sizes = radius_mult * plume_model.puff_array[:, 3]**0.5 return [vf_plot, pp_plot] # create animation object n_frame = int(t_max / (dt * steps_per_frame) + 0.5) anim = FuncAnimation(fig, update, frames=n_frame, blit=True) return fig, ax, anim
'lower': 0.9, # detection probability/sec of exposure 'upper': 0.5, # detection probability/sec of exposure }, 'schmitt_trigger':True, 'low_pass_filter_length':3, #seconds 'dt_plot': capture_interval*dt, 't_stop':simulation_time } swarm = swarm_models.BasicSwarmOfFlies(wind_field,traps,param=swarm_param, start_type='fh',track_plume_bouts=False,track_arena_exits=False) #Plotting concentration xlim = (-15., 15.) ylim = (0., 40.) sim_region_tuple = xlim[0], xlim[1], ylim[0], ylim[1] sim_region = models.Rectangle(*sim_region_tuple) im_extents = sim_region_tuple xmin,xmax,ymin,ymax = im_extents # Set up figure plt.ion() fig = plt.figure(figsize=(7.5, 9)) ax = fig.add_subplot(111) #Initial concentration plotting conc_samples = suttonPlumes.conc_im(im_extents) cmap = matplotlib.colors.ListedColormap(['white', 'orange']) conc_im = plt.imshow(conc_samples,cmap = cmap,extent=im_extents,origin='lower')
def main(wind_mag,i):#np.arange(0.4,3.8,0.2): random_state = np.random.RandomState(i) file_name = 'test_lazy_plumes_single_plume_wind_mag_'+str(wind_mag) output_file = file_name+'.pkl' dt = 0.25 frame_rate = 20 times_real_time = 20 # seconds of simulation / sec in video capture_interval = int(scipy.ceil(times_real_time*(1./frame_rate)/dt)) simulation_time = 50.*60. #seconds release_delay = 0.*60#/(wind_mag) t_start = 0.0 t = 0. - release_delay # Set up figure fig = plt.figure(figsize=(11, 11)) ax = fig.add_subplot(111) # #Video FFMpegWriter = animate.writers['ffmpeg'] metadata = {'title':file_name,} writer = FFMpegWriter(fps=frame_rate, metadata=metadata) writer.setup(fig, file_name+'.mp4', 500) wind_angle = 0. wind_param = { 'speed': wind_mag, 'angle': wind_angle, 'evolving': False, 'wind_dt': None, 'dt': dt } wind_field_noiseless = wind_models.WindField(param=wind_param) #traps source_locations = [(0.,0.),] source_pos = scipy.array([scipy.array(tup) for tup in source_locations]).T trap_param = { 'source_locations' : [source_pos], 'source_strengths' : [1.], 'epsilon' : 0.01, 'trap_radius' : 1., 'source_radius' : 1000. } traps = trap_models.TrapModel(trap_param) #Odor arena xlim = (0., 1800.) ylim = (-500., 500.) sim_region = models.Rectangle(xlim[0], ylim[0], xlim[1], ylim[1]) wind_region = models.Rectangle(xlim[0]*2,ylim[0]*2, xlim[1]*2,ylim[1]*2) im_extents = xlim[0], xlim[1], ylim[0], ylim[1] #lazy plume parameters puff_mol_amount = 1. r_sq_max=20;epsilon=0.00001;N=1e6 lazyPompyPlumes = models.OnlinePlume(sim_region, source_pos, wind_field_noiseless, simulation_time,dt,r_sq_max,epsilon,puff_mol_amount,N) # Concentration plotting # conc_d = lazyPompyPlumes.conc_im(im_extents) # # cmap = matplotlib.colors.ListedColormap(['white', 'orange']) # cmap = 'YlOrBr' # # conc_im = plt.imshow(conc_d,extent=im_extents, # interpolation='none',cmap = cmap,origin='lower') # # plt.colorbar() # # # # # #traps # for x,y in traps.param['source_locations']: # # #Black x # plt.scatter(x,y,marker='x',s=50,c='k') # # plt.ion() # plt.show() while t<simulation_time: for k in range(capture_interval): #update flies print('t: {0:1.2f}'.format(t)) x_locs,y_locs = np.linspace(0., 1800.,1000),np.random.uniform(-500., 500.,1000) lazyPompyPlumes.value(x_locs,y_locs) raw_input() t+= dt # time.sleep(0.001) # Update live display # Update time display release_delay = release_delay/60. text ='{0} min {1} sec'.format( int(scipy.floor(abs(t/60.))),int(scipy.floor(abs(t)%60.))) timer.set_text(text) # '''plot the flies''' fly_dots.set_offsets(scipy.c_[swarm.x_position,swarm.y_position]) fly_edgecolors = [edgecolor_dict[mode] for mode in swarm.mode] fly_facecolors = [facecolor_dict[mode] for mode in swarm.mode] # fly_dots.set_edgecolor(fly_edgecolors) fly_dots.set_facecolor(fly_facecolors) plt.pause(0.0001) writer.grab_frame() trap_list = [] for trap_num, trap_loc in enumerate(traps.param['source_locations']): mask_trap = swarm.trap_num == trap_num trap_cnt = mask_trap.sum() trap_list.append(trap_cnt) total_cnt = sum(trap_list) # writer.finish() with open(output_file, 'w') as f: pickle.dump((wind_field,swarm),f)
from pompy import models, processors import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation # Seed random number generator seed = 20180517 rng = np.random.RandomState(seed) # Define wind model parameters wind_model_params = { 'sim_region': models.Rectangle(0., -50., 100., 50.), 'nx': 21, 'ny': 21, 'u_av': 1., 'v_av': 0., 'Kx': 2., 'Ky': 2., 'noise_gain': 20., 'noise_damp': 0.1, 'noise_bandwidth': 0.2, } # Create wind model object wind_model = models.WindModel(noise_rand=rng, **wind_model_params) # Define plume simulation region # This is a subset of the wind simulation region to minimise boundary effects sim_region = models.Rectangle(0., -12.5, 50., 12.5) # Define plume model parameters
def make_time_averaged_plume(wind_mag): dt = 0.25 simulation_time = 100 * 60. #seconds collection_begins = 75 * 60. #to let the plume fill the space #traps source_locations = [ (0., 0.), ] #Odor arena xlim = (0., 1200.) ylim = (-150., 150.) sim_region = models.Rectangle(xlim[0], ylim[0], xlim[1], ylim[1]) wxlim = (-1500., 1500.) wylim = (-1500., 1500.) wind_region = models.Rectangle(wxlim[0] * 1.2, wylim[0] * 1.2, wxlim[1] * 1.2, wylim[1] * 1.2) source_pos = scipy.array([scipy.array(tup) for tup in source_locations]).T #wind model setup diff_eq = False constant_wind_angle = 0. #directly positive x wind direction aspect_ratio = (wxlim[1] - wxlim[0]) / (wylim[1] - wylim[0]) noise_gain = 3. noise_damp = 0.071 noise_bandwidth = 0.71 wind_grid_density = 200 Kx = Ky = 10000 #highest value observed to not cause explosion: 10000 wind_field = models.WindModel(wind_region, int(wind_grid_density * aspect_ratio), wind_grid_density, noise_gain=noise_gain, noise_damp=noise_damp, noise_bandwidth=noise_bandwidth, Kx=Kx, Ky=Ky, diff_eq=diff_eq, angle=constant_wind_angle, mag=wind_mag) #detection_threshold detection_threshold = 0.05 # Set up plume model plume_width_factor = 4. centre_rel_diff_scale = 2. * plume_width_factor puff_release_rate = 10 puff_spread_rate = 0.005 puff_init_rad = 0.01 max_num_puffs = int(2e5) plume_model = models.PlumeModel( sim_region, source_pos, wind_field, simulation_time, dt, centre_rel_diff_scale=centre_rel_diff_scale, puff_release_rate=puff_release_rate, puff_init_rad=puff_init_rad, puff_spread_rate=puff_spread_rate, max_num_puffs=max_num_puffs) # Create a concentration array generator array_z = 0.01 array_dim_y = 400 array_dim_x = 5000 puff_mol_amount = 1. array_gen = processors.ConcentrationArrayGenerator(sim_region, array_z, array_dim_x, array_dim_y, puff_mol_amount) conc_locs_x, conc_locs_y = np.meshgrid( np.linspace(xlim[0], xlim[1], array_dim_x), np.linspace(ylim[0], ylim[1], array_dim_y)) fig = plt.figure(figsize=(4 * 8, 8)) #Compute initial concentration field and display as image ax = plt.subplot(211) buffr = 1 ax.set_xlim((xlim[0] - buffr, xlim[1] + buffr)) ax.set_ylim((ylim[0] - buffr, ylim[1] + buffr)) # ax.set_xlim((200,250)) # ax.set_ylim((-10,10)) conc_array = array_gen.generate_single_array(plume_model.puffs) xmin = sim_region.x_min xmax = sim_region.x_max ymin = sim_region.y_min ymax = sim_region.y_max im_extents = (xmin, xmax, ymin, ymax) vmin, vmax = 0., 1. conc_im = ax.imshow(conc_array.T[::-1], extent=im_extents, vmin=vmin, vmax=vmax, cmap='Reds', aspect='auto') ax.set_aspect('equal') #Accumulated concentration field as image ax1 = plt.subplot(212) buffr = 1 ax1.set_xlim((xlim[0] - buffr, xlim[1] + buffr)) ax1.set_ylim((ylim[0] - buffr, ylim[1] + buffr)) accum_threshold_crosses = np.zeros_like(conc_array) accum_threshold_crosses += (conc_array >= detection_threshold).astype(float) vmin, vmax = 0., 50. conc_im1 = ax1.imshow(conc_array.T[::-1], extent=im_extents, vmin=vmin, vmax=vmax, cmap='Reds', aspect='auto') #Display initial wind vector field -- subsampled from total velocity_field = wind_field.velocity_field u, v = velocity_field[:, :, 0], velocity_field[:, :, 1] full_size = scipy.shape(u)[0] shrink_factor = 10 x_origins, y_origins = wind_field.x_points, wind_field.y_points coords = scipy.array(list(itertools.product(x_origins, y_origins))) x_coords, y_coords = coords[:, 0], coords[:, 1] vector_field = ax.quiver(x_coords, y_coords, u, v) # # plt.ion() # plt.show() # t = 0. capture_interval = 25 # while t < simulation_time: for k in range(capture_interval): wind_field.update(dt) plume_model.update(dt, verbose=True) t += dt print(t) if t > collection_begins: conc_array = array_gen.generate_single_array(plume_model.puffs) accum_threshold_crosses += (conc_array >= detection_threshold).astype(float) # if t>collection_begins: # conc_im.set_data((conc_array>=detection_threshold).astype(float).T[::-1]) # conc_im1.set_data(accum_threshold_crosses.T[::-1]) # plt.pause(.0001) threshold_cross_prob = accum_threshold_crosses / ( (t - collection_begins) / dt) # conc_array_accum_avg = conc_array_accum/((simulation_time-collection_begins)*dt) output_file = 'accum_threshold_prob_' + str( detection_threshold) + '_plume_width_factor_' + str( plume_width_factor) + '_wind_speed_' + str(wind_mag) + str( simulation_time) + 's.pkl' # output_file = 'accum_threshold_prob_'+str( # detection_threshold)+'_plume_width_factor_'+str( # plume_width_factor)+str(simulation_time)+'s.pkl' with open(output_file, 'w') as f: pickle.dump(threshold_cross_prob, f) output_file = 'accum_threshold_prob_' + str( detection_threshold) + '_plume_width_factor_' + str( plume_width_factor) + '_wind_speed_' + str(wind_mag) + str( simulation_time) + 's.pkl' #----Start here to load saved data with open(output_file, 'r') as f: threshold_cross_prob = pickle.load(f) #Check that the largest value in threshold_cross_prob is 1 print(np.max(threshold_cross_prob)) plt.close() plt.figure(1) plt.imshow(threshold_cross_prob.T[::-1]) plt.figure(2) x_crosses = np.arange(9, 4951, 10) sigmas = [] mus = [] mags = [] def gaussian(x, a, mu, sigma): return (a / np.sqrt(2 * np.pi * sigma**2)) * np.exp(-((x - mu)**2) / (2 * sigma**2)) def gaussian_chopped(x, a, mu, sigma): output = (a / np.sqrt(2 * np.pi * sigma**2)) * np.exp(-((x - mu)**2) / (2 * sigma**2)) output[output > 1.] = 1. return output def power_fun(x, a, k): return a * x**k # # plt.ion() # plt.show() for x_cross in x_crosses: plt.figure(2) plt.plot(conc_locs_y[:,x_cross],threshold_cross_prob[x_cross,:], \ label=str(conc_locs_x[0,x_cross])[0:5]) popt, _ = curve_fit(gaussian, conc_locs_y[:, x_cross], threshold_cross_prob[x_cross, :], bounds=([0, -np.inf, 0], [np.inf, np.inf, np.inf])) a, mu, sigma = popt # plt.figure(100) # plt.clf() # plt.plot(conc_locs_y[:,x_cross],threshold_cross_prob[x_cross,:],label='real') # plt.plot(conc_locs_y[:,x_cross],gaussian(conc_locs_y[:,x_cross],*popt),label='fit') # plt.xlim([-10,10]) # plt.legend # raw_input() sigmas.append(sigma) mus.append(mu) mags.append(a) # plt.figure(3) # plt.plot(conc_locs_x[0,x_crosses], # np.sum(threshold_cross_prob[x_crosses,:],axis=1),'o') # plt.legend() plt.figure(4) # plt.plot(conc_locs_x[0,x_crosses],mus,'o',label='Means') plt.plot(conc_locs_x[0, x_crosses], sigmas, 'o', label='Variances') # plt.ylim([0,2]) popt, _ = curve_fit(power_fun, conc_locs_x[0, x_crosses], sigmas, bounds=([0, 0], [np.inf, 1])) sigma_a, sigma_k = popt plt.plot(conc_locs_x[0, x_crosses], power_fun(conc_locs_x[0, x_crosses], *popt), label='fit') plt.legend(bbox_to_anchor=(1, 0.5)) plt.figure(5) plt.plot(conc_locs_x[0, x_crosses], mags / (np.sqrt(2 * np.pi * np.array(sigmas)**2)), 'o', label='Magnitudes') plt.plot(conc_locs_x[0, x_crosses], mags, 'o', label='Magnitudes') popt, _ = curve_fit(power_fun, conc_locs_x[0, x_crosses], mags, bounds=([0, -np.inf], [np.inf, 0])) a_a, a_k = popt plt.plot(conc_locs_x[0, x_crosses], power_fun(conc_locs_x[0, x_crosses], *popt), label='fit') plt.legend(bbox_to_anchor=(1, 0.5)) # plt.show() # raw_input print('sigma_a: ' + str(sigma_a) + ', sigma_k: ' + str(sigma_k)) print('a_a: ' + str(a_a) + ', a_k: ' + str(a_k)) # param_dict = { # 'sigma_a':sigma_a, # 'sigma_k':sigma_k, # 'a_a':a_a, # 'a_k':a_k # } #Hacky version before I figure what function to fit: just save all the #sigmas and as, and the delta x # mags = np.concatenate((mags,np.linspace(mags[-1],0,int(len(mags)/10)))) # sigmas = np.concatenate((sigmas,2.*np.ones(int(len(mags)/10)))) param_dict = { 'sigmas': sigmas, 'as': mags, 'dx': conc_locs_x[0, x_crosses[1]] - conc_locs_x[0, x_crosses[0]] } param_file_name = 'fit_gaussian_plume_params_odor_threshold_' + str( detection_threshold) + '_plume_width_factor_' + str( plume_width_factor) + '_wind_speed_' + str(wind_mag) + '.pkl' with open(param_file_name, 'w') as f: pickle.dump(param_dict, f)
from pompy import models, processors import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation # Define simulation region wind_region = models.Rectangle(0., -2., 10., 2.) sim_region = models.Rectangle(0., -0.5, 2., 0.5) # Set up wind model wind_grid_dim_x = 21 wind_grid_dim_y = 11 wind_vel_x_av = 2. wind_vel_y_av = 0. wind_model = models.WindModel(wind_region, wind_grid_dim_x, wind_grid_dim_y, wind_vel_x_av, wind_vel_y_av) # Set up plume model source_pos = (0.1, 0., 0.) centre_rel_diff_scale = 1.5 puff_release_rate = 500 puff_init_rad = 0.001 plume_model = models.PlumeModel(sim_region, source_pos, wind_model, centre_rel_diff_scale=centre_rel_diff_scale, puff_release_rate=puff_release_rate, puff_init_rad=puff_init_rad) # Create a concentration array generator array_z = 0.01
def moth_simulation(num_it=10, navigators=(), t_max=1, char_time=3.5, amplitude=0.1, dt=0.01, puff_release_rate=10, puff_spread_rate=0.001, draw_iter_interval=1, prep_plume=False): """ a copy of the concetration_array_demo with the moth actions integrated """ #define simulation region wind_region = models.Rectangle(0., -2., 10., 2.) sim_region = models.Rectangle(0., -1., 4., 1.) #establish the dictionaries and lists that will be used navigator_dict = {} del_list = [ ] # a list of the moth indices (i,j) that finished the track and were deleted for j in range(len(navigators)): moth_dict = {} list_dict = {} for i in range(num_it): moth_dict["moth{0}".format(i)] = navigators[j] list_dict["moth_trajectory_list{0}".format(i)] = [] navigator_dict["tup{0}".format(j)] = (moth_dict, list_dict) # set up wind model wind_model = mothpy_models.WindModel(wind_region, 21, 11, 1, char_time, amplitude) # set up plume model pfr = puff_release_rate psr = puff_spread_rate plume_model = models.PlumeModel(sim_region, (0.1, 0., 0.), wind_model, centre_rel_diff_scale=0.75, puff_release_rate=pfr, puff_init_rad=0.001, puff_spread_rate=psr) #set concetration array generator array_gen = processors.ConcentrationArrayGenerator(sim_region, 0.01, 500, 1000, 1.) #run the wind and plume models for 4 seconds before navigators are started if prep_plume: for i in range(int(4 / dt)): wind_model.update(dt) plume_model.update(dt) # define update and draw functions def update_func(dt, t): wind_model.update(dt) plume_model.update(dt) conc_array = array_gen.generate_single_array(plume_model.puff_array) for j in range(len(navigators)): #update each individual moth for i in range(num_it): if (i, j) not in del_list: vel_at_pos = wind_model.velocity_at_pos( navigator_dict["tup{0}".format(j)][0]["moth{0}".format( i)].x, navigator_dict["tup{0}".format(j)][0][ "moth{0}".format(i)].y) navigator_dict["tup{0}".format(j)][0]["moth{0}".format( i)].update(conc_array, vel_at_pos, dt) #each of the moth lists appends the new position given by it's corresponding moth def draw_func(): for j in range(len(navigators)): for i in range(num_it): if (i, j) not in del_list: moth_dict = navigator_dict["tup{0}".format(j)][0] moth_i = moth_dict["moth{0}".format(i)] (x, y, T, odor, gamma, state, success) = (moth_i.x, moth_i.y, moth_i.T, moth_i.odor, moth_i.gamma, moth_i.state, False) if np.sqrt((x - 25)**2 + ((y - 500)**2)) < 15: success = True del moth_dict["moth{0}".format(i)] del_list.append((i, j)) #navigators that had reached the simulation's borders are deleted if moth_i.y < 0 or moth_i.y > 999 or moth_i.x < 0 or moth_i.x > 499: del moth_dict["moth{0}".format(i)] del_list.append((i, j)) navigator_dict["tup{0}".format(j)][1][ "moth_trajectory_list{0}".format(i)].append( (x, y, T, odor, gamma, state, success)) #navigator_dict["tup{0}".format(j)] = (moth_dict,list_dict) # start simulation loop demos._simulation_loop(dt, t_max, 0, draw_iter_interval, update_func, draw_func) """ after the simulation is done, list_dict is reedited to form diff_list_dict. difference list dictionary is a dictionary containing lists, each list represents a diffrent moth and each item in the list is a tuple of the form (x,y,T,odor found/odor lost/none, is turning/isn't turning) """ diff_dict_lst = [] #this shamefuly large tree transcribes the lists to the lists accounting for the moments of finding and losing odor #as well as counting when and where the moth decided to turn. for k in range(len(navigators)): diff_dict = {} for i in range(num_it): currentlist = navigator_dict["tup{0}".format(k)][1][ "moth_trajectory_list{0}".format(i)] diff_list = [] for j in range(len(currentlist)): (x, y, T, odor, gamma, state, success) = currentlist[j] #odor and gamma will be rewritten if j < 1: #first object on the list, nothing happens odor = None turning = False else: #describe the conditions for odor and turning documantation separately if currentlist[j][3] == currentlist[j - 1][3]: odor = None elif currentlist[j][3] == True and currentlist[ j - 1][3] == False: odor = 'odor found' else: #odor changed from True to false odor = 'odor lost' if currentlist[j][4] != currentlist[j - 1][ 4] or currentlist[j][5] != currentlist[j - 1][5]: turning = True else: turning = False diff_list.append((x, y, T, odor, turning, state, success)) diff_dict["diff_list{0}".format(i)] = diff_list diff_dict_lst.append(diff_dict) return diff_dict_lst
def main(plume_width_factor): file_name = 'plume_width_testing' output_file = file_name+'.pkl' file_name = file_name +'plume_width_factor'+str(plume_width_factor) dt = 0.25 plume_dt = 0.25 frame_rate = 20 times_real_time = 20 # seconds of simulation / sec in video capture_interval = int(scipy.ceil(times_real_time*(1./frame_rate)/dt)) simulation_time = 2.*60. #seconds release_delay = 30.*60#/(wind_mag) t_start = 0.0 t = 0. - release_delay # Set up figure fig = plt.figure(figsize=(11, 11)) ax = fig.add_subplot(111) wind_mag = 1.8 wind_angle = 13*scipy.pi/8. wind_param = { 'speed': wind_mag, 'angle': wind_angle, 'evolving': False, 'wind_dt': None, 'dt': dt } wind_field_noiseless = wind_models.WindField(param=wind_param) #traps number_sources = 8 radius_sources = 1000.0 trap_radius = 0.5 location_list, strength_list = utility.create_circle_of_sources(number_sources, radius_sources,None) trap_param = { 'source_locations' : location_list, 'source_strengths' : strength_list, 'epsilon' : 0.01, 'trap_radius' : trap_radius, 'source_radius' : radius_sources } traps = trap_models.TrapModel(trap_param) #Wind and plume objects #Odor arena xlim = (-1500., 1500.) ylim = (-1500., 1500.) sim_region = models.Rectangle(xlim[0], ylim[0], xlim[1], ylim[1]) wind_region = models.Rectangle(xlim[0]*1.2,ylim[0]*1.2, xlim[1]*1.2,ylim[1]*1.2) source_pos = scipy.array([scipy.array(tup) for tup in traps.param['source_locations']]).T #wind model setup diff_eq = False constant_wind_angle = wind_angle aspect_ratio= (xlim[1]-xlim[0])/(ylim[1]-ylim[0]) noise_gain=3. noise_damp=0.071 noise_bandwidth=0.71 wind_grid_density = 200 Kx = Ky = 10000 #highest value observed to not cause explosion: 10000 wind_field = models.WindModel(wind_region,int(wind_grid_density*aspect_ratio), wind_grid_density,noise_gain=noise_gain,noise_damp=noise_damp, noise_bandwidth=noise_bandwidth,Kx=Kx,Ky=Ky, diff_eq=diff_eq,angle=constant_wind_angle,mag=wind_mag) #Initial wind plotting -- subsampled velocity_field = wind_field.velocity_field u,v = velocity_field[:,:,0],velocity_field[:,:,1] x_origins,y_origins = wind_field._x_points,wind_field._y_points full_size = scipy.shape(u)[0] print(full_size) shrink_factor = 10 u,v = u[0:full_size-1:shrink_factor,0:full_size-1:shrink_factor],\ v[0:full_size-1:shrink_factor,0:full_size-1:shrink_factor] # x_origins,y_origins = x_origins[0:-1:full_size-1],\ # y_origins[0:-1:full_size-1] x_origins,y_origins = x_origins[0:full_size-1:shrink_factor],\ y_origins[0:full_size-1:shrink_factor] coords = scipy.array(list(itertools.product(x_origins, y_origins))) x_coords,y_coords = coords[:,0],coords[:,1] vector_field = ax.quiver(x_coords,y_coords,u,v) # plt.show() # Set up plume model centre_rel_diff_scale = plume_width_factor*2. # puff_release_rate = 0.001 puff_release_rate = 10 puff_spread_rate=0.005 puff_init_rad = 0.01 max_num_puffs=int(2e5) # max_num_puffs=100 plume_model = models.PlumeModel( sim_region, source_pos, wind_field,simulation_time+release_delay,plume_dt, centre_rel_diff_scale=centre_rel_diff_scale, puff_release_rate=puff_release_rate, puff_init_rad=puff_init_rad,puff_spread_rate=puff_spread_rate, max_num_puffs=max_num_puffs) # Create a concentration array generator array_z = 0.01 array_dim_x = 1000 array_dim_y = array_dim_x puff_mol_amount = 1. array_gen = processors.ConcentrationArrayGenerator( sim_region, array_z, array_dim_x, array_dim_y, puff_mol_amount) #Setup fly swarm wind_slippage = (0.,1.) swarm_size=2000 use_empirical_release_data = False #Grab wind info to determine heading mean wind_x,wind_y = wind_mag*scipy.cos(wind_angle),wind_mag*scipy.sin(wind_angle) beta = 1. release_times = scipy.random.exponential(beta,(swarm_size,)) kappa = 2. heading_data=None # xmin,xmax,ymin,ymax = -1000,1000,-1000,1000 #Initial concentration plotting conc_array = array_gen.generate_single_array(plume_model.puffs) xmin = sim_region.x_min; xmax = sim_region.x_max ymin = sim_region.y_min; ymax = sim_region.y_max im_extents = (xmin,xmax,ymin,ymax) vmin,vmax = 0.,50. cmap = matplotlib.colors.ListedColormap(['white', 'orange']) conc_im = ax.imshow(conc_array.T[::-1], extent=im_extents, vmin=vmin, vmax=vmax, cmap=cmap) xmin,xmax,ymin,ymax = -1000,1000,-1000,1000 buffr = 100 ax.set_xlim((xmin-buffr,xmax+buffr)) ax.set_ylim((ymin-buffr,ymax+buffr)) #Conc array gen to be used for the flies sim_region_tuple = plume_model.sim_region.as_tuple() box_min,box_max = sim_region_tuple[1],sim_region_tuple[2] #Put the time in the corner (xmin,xmax) = ax.get_xlim();(ymin,ymax) = ax.get_ylim() # text = '0 min 0 sec' # timer= ax.text(xmax,ymax,text,color='r',horizontalalignment='right') # ax.text(1.,1.02,'time since release:',color='r',transform=ax.transAxes, # horizontalalignment='right') # #traps for x,y in traps.param['source_locations']: #Black x plt.scatter(x,y,marker='x',s=50,c='orange') # Red circles # p = matplotlib.patches.Circle((x, y), 15,color='red') # ax.add_patch(p) # #Remove plot edges and add scale bar fig.patch.set_facecolor('white') # plt.plot([-900,-800],[900,900],color='k')#,transform=ax.transData,color='k') # ax.text(-900,820,'100 m') plt.axis('off') # plt.ion() # plt.show() # raw_input() while t<simulation_time: for k in range(capture_interval): #update flies print('t: {0:1.2f}'.format(t)) #update the swarm for j in range(int(dt/plume_dt)): wind_field.update(plume_dt) plume_model.update(plume_dt,verbose=True) t+= dt # plt.show() # Update live display if t>-30.*60.: # if t>-10.*60.: velocity_field = wind_field.velocity_field u,v = velocity_field[:,:,0],velocity_field[:,:,1] u,v = u[0:full_size-1:shrink_factor,0:full_size-1:shrink_factor],\ v[0:full_size-1:shrink_factor,0:full_size-1:shrink_factor] vector_field.set_UVC(u,v) # conc_array = array_gen.generate_single_array(plume_model.puffs) # conc_im.set_data(conc_array.T[::-1]) # # log_im = scipy.log(conc_array.T[::-1]) # cutoff_l = scipy.percentile(log_im[~scipy.isinf(log_im)],10) # cutoff_u = scipy.percentile(log_im[~scipy.isinf(log_im)],99) # # conc_im.set_data(log_im) # n = matplotlib.colors.Normalize(vmin=cutoff_l,vmax=cutoff_u) # conc_im.set_norm(n) plt.savefig(file_name+'.png',format='png') plt.show() t = simulation_time
def f(detection_threshold): # def f(cast_timeout): # def f(cast_delay): # def f(cast_interval): no_repeat_tracking = True #Comment these out depending on which parameter we're iterating through # detection_threshold = 0.05 cast_timeout = 20. cast_interval = [1, 3] cast_delay = 3. #Wind angle wind_angle = 5 * np.pi / 4 wind_mag = 1.6 #arena size arena_size = 1000. #file info file_name = '1m_uniform_release_times_' file_name = file_name + 'detection_threshold_' + str(detection_threshold) # file_name = file_name +'cast_timeout_'+str(cast_timeout) # file_name = file_name +'cast_interval_'+str(cast_interval) # file_name = file_name +'cast_delay_'+str(cast_delay) # file_name = file_name +'errorless_surging_cast_delay_'+str(cast_delay) # file_name='for_viewing_purposes' # file_name='debugging_zero_peak_3' output_file = file_name + '.pkl' #Timing dt = 0.25 plume_dt = 0.25 frame_rate = 20 times_real_time = 30 # seconds of simulation / sec in video capture_interval = int(np.ceil(times_real_time * (1. / frame_rate) / dt)) # simulation_time = 20.*60. #seconds simulation_time = 12. * 60. #seconds release_delay = 25. * 60 #/(wind_mag) t_start = 0.0 t = 0. - release_delay # Set up figure fig = plt.figure(figsize=(11, 11)) ax = fig.add_subplot(111) wind_param = { 'speed': wind_mag, 'angle': wind_angle, 'evolving': False, 'wind_dt': None, 'dt': dt } wind_field_noiseless = wind_models.WindField(param=wind_param) #Setup ONE plume #traps trap_radius = 0.5 location_list = [(0, 100)] strength_list = [1] trap_param = { 'source_locations': location_list, 'source_strengths': strength_list, 'epsilon': 0.01, 'trap_radius': trap_radius, 'source_radius': 100 } traps = trap_models.TrapModel(trap_param) #Wind and plume objects #Odor arena xlim = (-arena_size, arena_size) ylim = (-arena_size, arena_size) sim_region = models.Rectangle(xlim[0], ylim[0], xlim[1], ylim[1]) wind_region = models.Rectangle(xlim[0] * 1.2, ylim[0] * 1.2, xlim[1] * 1.2, ylim[1] * 1.2) source_pos = np.array( [np.array(tup) for tup in traps.param['source_locations']]).T #wind model setup diff_eq = False constant_wind_angle = wind_angle aspect_ratio = (xlim[1] - xlim[0]) / (ylim[1] - ylim[0]) noise_gain = 3. noise_damp = 0.071 noise_bandwidth = 0.71 wind_grid_density = 200 Kx = Ky = 10000 #highest value observed to not cause explosion: 10000 wind_field = models.WindModel(wind_region, int(wind_grid_density * aspect_ratio), wind_grid_density, noise_gain=noise_gain, noise_damp=noise_damp, noise_bandwidth=noise_bandwidth, Kx=Kx, Ky=Ky, diff_eq=diff_eq, angle=constant_wind_angle, mag=wind_mag) # Set up plume model centre_rel_diff_scale = 2. puff_release_rate = 10 puff_spread_rate = 0.005 puff_init_rad = 0.01 max_num_puffs = int(2e5) # max_num_puffs=100 plume_model = models.PlumeModel( sim_region, source_pos, wind_field, simulation_time + release_delay, plume_dt, plume_cutoff_radius=1500, centre_rel_diff_scale=centre_rel_diff_scale, puff_release_rate=puff_release_rate, puff_init_rad=puff_init_rad, puff_spread_rate=puff_spread_rate, max_num_puffs=max_num_puffs, max_distance_from_trap=5000) # Create a concentration array generator array_z = 0.01 array_dim_x = 1000 array_dim_y = array_dim_x puff_mol_amount = 1. array_gen = processors.ConcentrationArrayGenerator(sim_region, array_z, array_dim_x, array_dim_y, puff_mol_amount) #Start a bunch of flies with uniformly random headings at (0,0) wind_slippage = (0., 0.) # swarm_size=20000 # swarm_size=200000 swarm_size = 1000000 # swarm_size=2000 release_times = scipy.random.uniform(0, simulation_time / 2, size=swarm_size) swarm_param = { 'swarm_size': swarm_size, 'heading_data': None, 'initial_heading': np.radians(np.random.uniform(45.0, 225.0, (swarm_size, ))), 'x_start_position': np.linspace(-arena_size, 50, swarm_size), 'y_start_position': np.linspace(-arena_size, 50, swarm_size), 'flight_speed': np.full((swarm_size, ), 1.5), 'release_time': release_times, 'release_delay': release_delay, 'cast_interval': cast_interval, 'wind_slippage': wind_slippage, 'odor_thresholds': { 'lower': 0.0005, 'upper': detection_threshold }, 'schmitt_trigger': False, 'low_pass_filter_length': cast_delay, #seconds 'dt_plot': capture_interval * dt, 't_stop': simulation_time, 'cast_timeout': cast_timeout, 'surging_error_std': scipy.radians(1e-10), 'airspeed_saturation': False } swarm = swarm_models.BasicSwarmOfFlies(wind_field_noiseless, traps, param=swarm_param, start_type='fh', track_plume_bouts=False, track_arena_exits=False) #Set up collector object #Check that source_pos is the right size collector = TrackBoutCollector(swarm_size, wind_angle, source_pos, repeats=False) #Conc array gen to be used for the flies sim_region_tuple = plume_model.sim_region.as_tuple() box_min, box_max = sim_region_tuple[1], sim_region_tuple[2] #for the plume distance cutoff version, make sure this is at least 2x radius box_min, box_max = -arena_size, arena_size r_sq_max = 20 epsilon = 0.00001 N = 1e6 array_gen_flies = processors.ConcentrationValueFastCalculator( box_min, box_max, r_sq_max, epsilon, puff_mol_amount, N) Mode_StartMode = 0 Mode_FlyUpWind = 1 Mode_CastForOdor = 2 Mode_Trapped = 3 #Start time loop while t < simulation_time: for k in range(capture_interval): #update flies print('t: {0:1.2f}'.format(t)) #update the swarm for j in range(int(dt / plume_dt)): wind_field.update(plume_dt) plume_model.update(plume_dt, verbose=True) if t > 0.: dispersing_last_step = (swarm.mode == Mode_StartMode) casting_last_step = (swarm.mode == Mode_CastForOdor) not_trapped_last_step = (swarm.mode != Mode_Trapped) ever_tracked_last_step = swarm.ever_tracked swarm.update(t, dt, wind_field_noiseless, array_gen_flies, traps, plumes=plume_model, pre_stored=False) #Update the collector object newly_surging = dispersing_last_step & (swarm.mode == Mode_FlyUpWind) newly_dispersing = casting_last_step & (swarm.mode == Mode_StartMode) newly_trapped = not_trapped_last_step & (swarm.mode == Mode_Trapped) dispersal_mode_flies = (swarm.mode == Mode_StartMode) collector.update_for_trapped(newly_trapped) collector.update_for_loss(newly_dispersing, swarm.x_position[newly_dispersing], swarm.y_position[newly_dispersing]) if no_repeat_tracking: newly_surging = newly_surging & (~ever_tracked_last_step) collector.update_for_detection(newly_surging, swarm.x_position[newly_surging], swarm.y_position[newly_surging]) collector.update_for_missed_detection(swarm.x_position, swarm.y_position, dispersal_mode_flies, ever_tracked_last_step) t += dt #Save the collector object with pickle with open(output_file, 'w') as f: swarm_param.update({'simulation_duration': t}) pickle.dump((swarm_param, collector), f)
def f(wind_angle, i): random_state = np.random.RandomState(i) wind_mag = 1.2 file_name = 'trap_arrival_by_wind_live_coarse_dt' file_name = file_name + '_wind_mag_' + str( wind_mag) + '_wind_angle_' + str(wind_angle)[0:4] + '_iter_' + str(i) output_file = file_name + '.pkl' dt = 0.25 plume_dt = 0.25 frame_rate = 20 times_real_time = 20 # seconds of simulation / sec in video capture_interval = int(scipy.ceil(times_real_time * (1. / frame_rate) / dt)) simulation_time = 50. * 60. #seconds release_delay = 30. * 60 #/(wind_mag) t_start = 0.0 t = 0. - release_delay wind_param = { 'speed': wind_mag, 'angle': wind_angle, 'evolving': False, 'wind_dt': None, 'dt': dt } wind_field_noiseless = wind_models.WindField(param=wind_param) #traps number_sources = 8 radius_sources = 1000.0 trap_radius = 0.5 location_list, strength_list = utility.create_circle_of_sources( number_sources, radius_sources, None) trap_param = { 'source_locations': location_list, 'source_strengths': strength_list, 'epsilon': 0.01, 'trap_radius': trap_radius, 'source_radius': radius_sources } traps = trap_models.TrapModel(trap_param) #Wind and plume objects #Odor arena xlim = (-1500., 1500.) ylim = (-1500., 1500.) sim_region = models.Rectangle(xlim[0], ylim[0], xlim[1], ylim[1]) wind_region = models.Rectangle(xlim[0] * 1.2, ylim[0] * 1.2, xlim[1] * 1.2, ylim[1] * 1.2) source_pos = scipy.array( [scipy.array(tup) for tup in traps.param['source_locations']]).T #wind model setup diff_eq = False constant_wind_angle = wind_angle aspect_ratio = (xlim[1] - xlim[0]) / (ylim[1] - ylim[0]) noise_gain = 3. noise_damp = 0.071 noise_bandwidth = 0.71 wind_grid_density = 200 Kx = Ky = 10000 #highest value observed to not cause explosion: 10000 wind_field = models.WindModel(wind_region, int(wind_grid_density * aspect_ratio), wind_grid_density, noise_gain=noise_gain, noise_damp=noise_damp, noise_bandwidth=noise_bandwidth, Kx=Kx, Ky=Ky, noise_rand=random_state, diff_eq=diff_eq, angle=constant_wind_angle, mag=wind_mag) # Set up plume model centre_rel_diff_scale = 2. # puff_release_rate = 0.001 puff_release_rate = 10 puff_spread_rate = 0.005 puff_init_rad = 0.01 max_num_puffs = int(2e5) # max_num_puffs=100 plume_model = models.PlumeModel( sim_region, source_pos, wind_field, simulation_time + release_delay, plume_dt, plume_cutoff_radius=1500, centre_rel_diff_scale=centre_rel_diff_scale, puff_release_rate=puff_release_rate, puff_init_rad=puff_init_rad, puff_spread_rate=puff_spread_rate, max_num_puffs=max_num_puffs, prng=random_state) puff_mol_amount = 1. #Setup fly swarm wind_slippage = (0., 1.) swarm_size = 2000 use_empirical_release_data = False #Grab wind info to determine heading mean wind_x, wind_y = wind_mag * scipy.cos(wind_angle), wind_mag * scipy.sin( wind_angle) beta = 1. release_times = scipy.random.exponential(beta, (swarm_size, )) kappa = 2. heading_data = None swarm_param = { 'swarm_size': swarm_size, 'heading_data': heading_data, 'initial_heading': scipy.radians(scipy.random.uniform(0.0, 360.0, (swarm_size, ))), 'x_start_position': scipy.zeros(swarm_size), 'y_start_position': scipy.zeros(swarm_size), 'flight_speed': scipy.full((swarm_size, ), 1.5), 'release_time': release_times, 'release_delay': release_delay, 'cast_interval': [1, 3], 'wind_slippage': wind_slippage, 'odor_thresholds': { 'lower': 0.0005, 'upper': 0.05 }, 'schmitt_trigger': False, 'low_pass_filter_length': 3, #seconds 'dt_plot': capture_interval * dt, 't_stop': 3000., 'cast_timeout': 20, 'airspeed_saturation': True } swarm = swarm_models.BasicSwarmOfFlies(wind_field_noiseless, traps, param=swarm_param, start_type='fh', track_plume_bouts=False, track_arena_exits=False) # xmin,xmax,ymin,ymax = -1000,1000,-1000,1000 #Conc array gen to be used for the flies sim_region_tuple = plume_model.sim_region.as_tuple() #for the plume distance cutoff version, make sure this is at least 2x radius box_min, box_max = -3000., 3000. r_sq_max = 20 epsilon = 0.00001 N = 1e6 array_gen_flies = processors.ConcentrationValueFastCalculator( box_min, box_max, r_sq_max, epsilon, puff_mol_amount, N) while t < simulation_time: for k in range(capture_interval): #update flies print('t: {0:1.2f}'.format(t)) #update the swarm for j in range(int(dt / plume_dt)): wind_field.update(plume_dt) plume_model.update(plume_dt, verbose=True) if t > 0.: swarm.update(t, dt, wind_field_noiseless, array_gen_flies, traps, plumes=plume_model, pre_stored=False) t += dt with open(output_file, 'w') as f: pickle.dump((wind_field_noiseless, swarm), f)
def main(puff_spread_rate_factor): file_name = 'puff_spread_rate_testing' output_file = file_name + '.pkl' file_name = file_name + '_puff_spread_rate' + str(puff_spread_rate_factor) dt = 0.25 plume_dt = 0.25 frame_rate = 20 times_real_time = 20 # seconds of simulation / sec in video capture_interval = int(scipy.ceil(times_real_time * (1. / frame_rate) / dt)) simulation_time = 50. * 60. #seconds release_delay = 30. * 60 #/(wind_mag) t_start = 0.0 t = 0. - release_delay # Set up figure fig = plt.figure(figsize=(11, 11)) ax = fig.add_subplot(111) wind_mag = 1.8 wind_angle = 13 * scipy.pi / 8. wind_param = { 'speed': wind_mag, 'angle': wind_angle, 'evolving': False, 'wind_dt': None, 'dt': dt } wind_field_noiseless = wind_models.WindField(param=wind_param) #traps number_sources = 8 radius_sources = 1000.0 trap_radius = 0.5 location_list, strength_list = utility.create_circle_of_sources( number_sources, radius_sources, None) trap_param = { 'source_locations': location_list, 'source_strengths': strength_list, 'epsilon': 0.01, 'trap_radius': trap_radius, 'source_radius': radius_sources } traps = trap_models.TrapModel(trap_param) #Wind and plume objects #Odor arena xlim = (-1500., 1500.) ylim = (-1500., 1500.) sim_region = models.Rectangle(xlim[0], ylim[0], xlim[1], ylim[1]) wind_region = models.Rectangle(xlim[0] * 1.2, ylim[0] * 1.2, xlim[1] * 1.2, ylim[1] * 1.2) source_pos = scipy.array( [scipy.array(tup) for tup in traps.param['source_locations']]).T #wind model setup diff_eq = False constant_wind_angle = wind_angle aspect_ratio = (xlim[1] - xlim[0]) / (ylim[1] - ylim[0]) noise_gain = 3. noise_damp = 0.071 noise_bandwidth = 0.71 wind_grid_density = 200 Kx = Ky = 10000 #highest value observed to not cause explosion: 10000 wind_field = models.WindModel(wind_region, int(wind_grid_density * aspect_ratio), wind_grid_density, noise_gain=noise_gain, noise_damp=noise_damp, noise_bandwidth=noise_bandwidth, Kx=Kx, Ky=Ky, diff_eq=diff_eq, angle=constant_wind_angle, mag=wind_mag) # Set up plume model plume_width_factor = 1. puff_mol_amount = 1. centre_rel_diff_scale = 2. * plume_width_factor # puff_release_rate = 0.001 puff_release_rate = 10 puff_spread_rate = 0.005 * puff_spread_rate_factor puff_init_rad = 0.01 max_num_puffs = int(2e5) # max_num_puffs=100 plume_model = models.PlumeModel( sim_region, source_pos, wind_field, simulation_time + release_delay, plume_dt, centre_rel_diff_scale=centre_rel_diff_scale, puff_release_rate=puff_release_rate, puff_init_rad=puff_init_rad, puff_spread_rate=puff_spread_rate, max_num_puffs=max_num_puffs) #Setup fly swarm wind_slippage = (0., 1.) swarm_size = 2000 use_empirical_release_data = False #Grab wind info to determine heading mean wind_x, wind_y = wind_mag * scipy.cos(wind_angle), wind_mag * scipy.sin( wind_angle) beta = 1. release_times = scipy.random.exponential(beta, (swarm_size, )) kappa = 2. heading_data = None swarm_param = { 'swarm_size': swarm_size, 'heading_data': heading_data, 'initial_heading': scipy.radians(scipy.random.uniform(0.0, 360.0, (swarm_size, ))), 'x_start_position': scipy.zeros(swarm_size), 'y_start_position': scipy.zeros(swarm_size), 'flight_speed': scipy.full((swarm_size, ), 1.5), 'release_time': release_times, 'release_delay': release_delay, 'cast_interval': [1, 3], 'wind_slippage': wind_slippage, 'odor_thresholds': { 'lower': 0.0005, 'upper': 0.05 }, 'schmitt_trigger': False, 'low_pass_filter_length': 3, #seconds 'dt_plot': capture_interval * dt, 't_stop': 3000., 'cast_timeout': 20, 'airspeed_saturation': True } swarm = swarm_models.BasicSwarmOfFlies(wind_field_noiseless, traps, param=swarm_param, start_type='fh', track_plume_bouts=False, track_arena_exits=False) # xmin,xmax,ymin,ymax = -1000,1000,-1000,1000 #Conc array gen to be used for the flies sim_region_tuple = plume_model.sim_region.as_tuple() #for the plume distance cutoff version, make sure this is at least 2x radius box_min, box_max = -3000., 3000. r_sq_max = 20 epsilon = 0.00001 N = 1e6 array_gen_flies = processors.ConcentrationValueFastCalculator( box_min, box_max, r_sq_max, epsilon, puff_mol_amount, N) while t < simulation_time: for k in range(capture_interval): #update flies print('t: {0:1.2f}'.format(t)) #update the swarm for j in range(int(dt / plume_dt)): wind_field.update(plume_dt) plume_model.update(plume_dt, verbose=True) if t > 0.: swarm.update(t, dt, wind_field_noiseless, array_gen_flies, traps, plumes=plume_model, pre_stored=False) t += dt with open(output_file, 'w') as f: pickle.dump((wind_field_noiseless, swarm), f) #Trap arrival plot trap_locs = (2 * scipy.pi / swarm.num_traps) * scipy.array( swarm.list_all_traps()) sim_trap_counts = swarm.get_trap_counts() #Set 0s to 1 for plotting purposes sim_trap_counts[sim_trap_counts == 0] = .5 radius_scale = 0.3 plot_size = 1.5 plt.figure(200 + int(10 * wind_mag)) ax = plt.subplot(aspect=1) trap_locs_2d = [(scipy.cos(trap_loc), scipy.sin(trap_loc)) for trap_loc in trap_locs] patches = [ plt.Circle(center, size) for center, size in zip( trap_locs_2d, radius_scale * sim_trap_counts / max(sim_trap_counts)) ] coll = matplotlib.collections.PatchCollection(patches, facecolors='blue', edgecolors='blue') ax.add_collection(coll) ax.set_ylim([-plot_size, plot_size]) ax.set_xlim([-plot_size, plot_size]) ax.set_xticks([]) ax.set_xticklabels('') ax.set_yticks([]) ax.set_yticklabels('') #Wind arrow plt.arrow(0.5, 0.5, 0.1 * scipy.cos(wind_angle), 0.1 * scipy.sin(wind_angle), transform=ax.transAxes, color='b', width=0.001) # ax.text(0.55, 0.5,'Wind',transform=ax.transAxes,color='b') ax.text(0, 1.5, 'N', horizontalalignment='center', verticalalignment='center', fontsize=25) ax.text(0, -1.5, 'S', horizontalalignment='center', verticalalignment='center', fontsize=25) ax.text(1.5, 0, 'E', horizontalalignment='center', verticalalignment='center', fontsize=25) ax.text(-1.5, 0, 'W', horizontalalignment='center', verticalalignment='center', fontsize=25) # plt.title('Simulated') fig.patch.set_facecolor('white') plt.axis('off') ax.text(0, 1.7, 'Trap Counts' + ' (Spread Rate Factor: ' + str(puff_spread_rate_factor) + ')', horizontalalignment='center', verticalalignment='center', fontsize=20) plt.savefig(file_name + '.png', format='png')
import dill as pickle dt = 0.01 frame_rate = 20 times_real_time = 5 # seconds of simulation / sec in video capture_interval = int(scipy.ceil(times_real_time*((1./frame_rate)/dt))) simulation_time = 1.5*60 #seconds t_start = -10.#-5*60. #time before fly release #Odor arena xlim = (-15., 15.) ylim = (0., 40.) sim_region_tuple = xlim[0], ylim[0], xlim[1], ylim[1] sim_region = models.Rectangle(*sim_region_tuple) wind_region = models.Rectangle(xlim[0]*1.2,ylim[0]*1.2, xlim[1]*1.2,ylim[1]*1.2) source_pos = scipy.array([(7.5,25)]).T #wind setup diff_eq = True #this is the parameter that affects whether a PDE is solved #to determine the wind field or if it's just the empirical value centre_rel_diff_scale=centre_rel_diff_scale, puff_release_rate=puff_release_rate, puff_init_rad=puff_init_rad,puff_spread_rate=puff_spread_rate, max_num_puffs=max_num_puffs) # Create a concentration array generator array_z = 0.01 array_dim_x = 1000
simulation_time = 1. * 60. #seconds release_delay = 30. * 60 / (wind_mag) t_start = 0.0 t = 0. - release_delay #traps source_locations = [ (0., 0.), ] #Wind arena as big as wind arena for desert simulation xlim = (-1500., 1500.) ylim = (-1500., 1500.) wind_region = models.Rectangle(xlim[0] * 1.2, ylim[0] * 1.2, xlim[1] * 1.2, ylim[1] * 1.2) #Odor arena just directly surrounding the single plume xlim_odor = (-100., 1500.) ylim_odor = (-300., 300.) sim_region = models.Rectangle(xlim_odor[0], ylim_odor[0], xlim_odor[1], ylim_odor[1]) source_pos = scipy.array([scipy.array(tup) for tup in source_locations]).T #wind model setup diff_eq = True constant_wind_angle = 0. #directly positive x wind direction aspect_ratio = (xlim[1] - xlim[0]) / (ylim[1] - ylim[0]) noise_gain = 3. noise_damp = 0.071
def main(wind_angle): # for wind_mag in np.arange(0.4,3.8,0.2): # wind_mag = float(sys.argv[1]) # wind_angle = 13*scipy.pi/8. wind_mag = 1.4 file_name = 'trap_arrival_by_wind_live_coarse_dt' file_name = file_name + '_wind_mag_' + str( wind_mag) + '_wind_angle_' + str(wind_angle)[0:4] output_file = file_name + '.pkl' dt = 0.25 plume_dt = 0.25 frame_rate = 20 times_real_time = 60 # seconds of simulation / sec in video capture_interval = int(scipy.ceil(times_real_time * (1. / frame_rate) / dt)) simulation_time = 50. * 60. #seconds release_delay = 30. * 60 #/(wind_mag) t_start = 0.0 t = 0. - release_delay # Set up figure fig = plt.figure(figsize=(11, 11)) ax = fig.add_subplot(111) #Video FFMpegWriter = animate.writers['ffmpeg'] metadata = { 'title': file_name, } writer = FFMpegWriter(fps=frame_rate, metadata=metadata) writer.setup(fig, file_name + '.mp4', 500) wind_param = { 'speed': wind_mag, 'angle': wind_angle, 'evolving': False, 'wind_dt': None, 'dt': dt } wind_field_noiseless = wind_models.WindField(param=wind_param) #traps number_sources = 8 radius_sources = 1000.0 trap_radius = 0.5 location_list, strength_list = utility.create_circle_of_sources( number_sources, radius_sources, None) trap_param = { 'source_locations': location_list, 'source_strengths': strength_list, 'epsilon': 0.01, 'trap_radius': trap_radius, 'source_radius': radius_sources } traps = trap_models.TrapModel(trap_param) #Wind and plume objects #Odor arena xlim = (-1500., 1500.) ylim = (-1500., 1500.) sim_region = models.Rectangle(xlim[0], ylim[0], xlim[1], ylim[1]) wind_region = models.Rectangle(xlim[0] * 2, ylim[0] * 2, xlim[1] * 2, ylim[1] * 2) source_pos = scipy.array( [scipy.array(tup) for tup in traps.param['source_locations']]).T #wind model setup diff_eq = False constant_wind_angle = wind_angle aspect_ratio = (xlim[1] - xlim[0]) / (ylim[1] - ylim[0]) noise_gain = 3. noise_damp = 0.071 noise_bandwidth = 0.71 wind_grid_density = 200 Kx = Ky = 10000 #highest value observed to not cause explosion: 10000 wind_field = models.WindModel(wind_region, int(wind_grid_density * aspect_ratio), wind_grid_density, noise_gain=noise_gain, noise_damp=noise_damp, noise_bandwidth=noise_bandwidth, Kx=Kx, Ky=Ky, diff_eq=diff_eq, angle=constant_wind_angle, mag=wind_mag) # Set up plume model plume_width_factor = 1. centre_rel_diff_scale = 2. * plume_width_factor # puff_release_rate = 0.001 puff_release_rate = 10 puff_spread_rate = 0.005 puff_init_rad = 0.01 max_num_puffs = int(2e5) # max_num_puffs=100 plume_model = models.PlumeModel( sim_region, source_pos, wind_field, simulation_time + release_delay, plume_dt, plume_cutoff_radius=1500, centre_rel_diff_scale=centre_rel_diff_scale, puff_release_rate=puff_release_rate, puff_init_rad=puff_init_rad, puff_spread_rate=puff_spread_rate, max_num_puffs=max_num_puffs) # Create a concentration array generator array_z = 0.01 array_dim_x = 1000 array_dim_y = array_dim_x puff_mol_amount = 1. array_gen = processors.ConcentrationArrayGenerator(sim_region, array_z, array_dim_x, array_dim_y, puff_mol_amount) #Setup fly swarm wind_slippage = (0., 1.) swarm_size = 2000 use_empirical_release_data = False #Grab wind info to determine heading mean wind_x, wind_y = wind_mag * scipy.cos(wind_angle), wind_mag * scipy.sin( wind_angle) beta = 1. release_times = scipy.random.exponential(beta, (swarm_size, )) kappa = 2. heading_data = None swarm_param = { 'swarm_size': swarm_size, 'heading_data': heading_data, 'initial_heading': scipy.radians(scipy.random.uniform(0.0, 360.0, (swarm_size, ))), 'x_start_position': scipy.zeros(swarm_size), 'y_start_position': scipy.zeros(swarm_size), 'flight_speed': scipy.full((swarm_size, ), 1.5), 'release_time': release_times, 'release_delay': release_delay, 'cast_interval': [1, 3], 'wind_slippage': wind_slippage, 'odor_thresholds': { 'lower': 0.0005, 'upper': 0.05 }, 'schmitt_trigger': False, 'low_pass_filter_length': 3, #seconds 'dt_plot': capture_interval * dt, 't_stop': 3000., 'cast_timeout': 20, 'airspeed_saturation': True } swarm = swarm_models.BasicSwarmOfFlies(wind_field_noiseless, traps, param=swarm_param, start_type='fh', track_plume_bouts=False, track_arena_exits=False) # xmin,xmax,ymin,ymax = -1000,1000,-1000,1000 #Initial concentration plotting conc_array = array_gen.generate_single_array(plume_model.puffs) xmin = sim_region.x_min xmax = sim_region.x_max ymin = sim_region.y_min ymax = sim_region.y_max im_extents = (xmin, xmax, ymin, ymax) vmin, vmax = 0., 50. cmap = matplotlib.colors.ListedColormap(['white', 'orange']) conc_im = ax.imshow(conc_array.T[::-1], extent=im_extents, vmin=vmin, vmax=vmax, cmap=cmap) xmin, xmax, ymin, ymax = -1000, 1000, -1000, 1000 #For looking at the distace-bound plumes xmin, xmax, ymin, ymax = -3000, 3000, -3000, 3000 buffr = 100 ax.set_xlim((xmin - buffr, xmax + buffr)) ax.set_ylim((ymin - buffr, ymax + buffr)) #Conc array gen to be used for the flies sim_region_tuple = plume_model.sim_region.as_tuple() box_min, box_max = sim_region_tuple[1], sim_region_tuple[2] #for the plume distance cutoff version, make sure this is at least 2x radius box_min, box_max = -3000., 3000. r_sq_max = 20 epsilon = 0.00001 N = 1e6 array_gen_flies = processors.ConcentrationValueFastCalculator( box_min, box_max, r_sq_max, epsilon, puff_mol_amount, N) #Initial fly plotting #Sub-dictionary for color codes for the fly modes Mode_StartMode = 0 Mode_FlyUpWind = 1 Mode_CastForOdor = 2 Mode_Trapped = 3 edgecolor_dict = { Mode_StartMode: 'blue', Mode_FlyUpWind: 'red', Mode_CastForOdor: 'red', Mode_Trapped: 'black' } facecolor_dict = { Mode_StartMode: 'blue', Mode_FlyUpWind: 'red', Mode_CastForOdor: 'white', Mode_Trapped: 'black' } fly_edgecolors = [edgecolor_dict[mode] for mode in swarm.mode] fly_facecolors = [facecolor_dict[mode] for mode in swarm.mode] fly_dots = plt.scatter(swarm.x_position, swarm.y_position, edgecolor=fly_edgecolors, facecolor=fly_facecolors, alpha=0.9) #Put the time in the corner (xmin, xmax) = ax.get_xlim() (ymin, ymax) = ax.get_ylim() text = '0 min 0 sec' timer = ax.text(xmax, ymax, text, color='r', horizontalalignment='right') ax.text(1., 1.02, 'time since release:', color='r', transform=ax.transAxes, horizontalalignment='right') #Wind arrow plt.arrow(0.5, 0.5, 0.07, -0.07, transform=ax.transAxes, color='b', width=0.001) ax.text(0.75, 0.9, 'Wind', transform=ax.transAxes, color='b') # #traps for x, y in traps.param['source_locations']: #Black x plt.scatter(x, y, marker='x', s=50, c='k') # Red circles # p = matplotlib.patches.Circle((x, y), 15,color='red') # ax.add_patch(p) #Remove plot edges and add scale bar fig.patch.set_facecolor('white') plt.plot([-900, -800], [900, 900], color='k') #,transform=ax.transData,color='k') ax.text(-900, 820, '100 m') plt.axis('off') #Fly behavior color legend for mode, fly_facecolor, fly_edgecolor, a in zip( ['Dispersing', 'Surging', 'Casting', 'Trapped'], facecolor_dict.values(), edgecolor_dict.values(), [0, 50, 100, 150]): plt.scatter([1000], [-600 - a], edgecolor=fly_edgecolor, facecolor=fly_facecolor, s=20) plt.text(1050, -600 - a, mode, verticalalignment='center') # plt.ion() # plt.show() # raw_input() while t < simulation_time: for k in range(capture_interval): #update flies print('t: {0:1.2f}'.format(t)) #update the swarm for j in range(int(dt / plume_dt)): wind_field.update(plume_dt) plume_model.update(plume_dt, verbose=True) # velocity_field = wind_field.velocity_field # u,v = velocity_field[:,:,0],velocity_field[:,:,1] # u,v = u[0:full_size-1:shrink_factor,0:full_size-1:shrink_factor],\ # v[0:full_size-1:shrink_factor,0:full_size-1:shrink_factor] # vector_field.set_UVC(u,v) if t > 0.: swarm.update(t, dt, wind_field_noiseless, array_gen_flies, traps, plumes=plume_model, pre_stored=False) t += dt # time.sleep(0.001) # Update live display # '''plot the flies''' if t > 0: # Update time display release_delay = release_delay / 60. text = '{0} min {1} sec'.format(int(scipy.floor(abs(t / 60.))), int(scipy.floor(abs(t) % 60.))) timer.set_text(text) fly_dots.set_offsets(scipy.c_[swarm.x_position, swarm.y_position]) fly_edgecolors = [edgecolor_dict[mode] for mode in swarm.mode] fly_facecolors = [facecolor_dict[mode] for mode in swarm.mode] # fly_dots.set_edgecolor(fly_edgecolors) fly_dots.set_facecolor(fly_facecolors) trap_list = [] for trap_num, trap_loc in enumerate( traps.param['source_locations']): mask_trap = swarm.trap_num == trap_num trap_cnt = mask_trap.sum() trap_list.append(trap_cnt) total_cnt = sum(trap_list) conc_array = array_gen.generate_single_array(plume_model.puffs) # non_inf_log = log_im = scipy.log(conc_array.T[::-1]) cutoff_l = scipy.percentile(log_im[~scipy.isinf(log_im)], 10) cutoff_u = scipy.percentile(log_im[~scipy.isinf(log_im)], 99) # im = (log_im>cutoff_l) & (log_im<0.1) # n = matplotlib.colors.Normalize(vmin=0,vmax=1) # image.set_data(im) # image.set_norm(n) conc_im.set_data(log_im) n = matplotlib.colors.Normalize(vmin=cutoff_l, vmax=cutoff_u) conc_im.set_norm(n) # plt.pause(0.0001) writer.grab_frame() writer.finish() with open(output_file, 'w') as f: pickle.dump((wind_field_noiseless, swarm), f) #Trap arrival plot trap_locs = (2 * scipy.pi / swarm.num_traps) * scipy.array( swarm.list_all_traps()) sim_trap_counts = swarm.get_trap_counts() #Set 0s to 1 for plotting purposes sim_trap_counts[sim_trap_counts == 0] = .5 radius_scale = 0.3 plot_size = 1.5 plt.figure(200 + int(10 * wind_mag)) ax = plt.subplot(aspect=1) trap_locs_2d = [(scipy.cos(trap_loc), scipy.sin(trap_loc)) for trap_loc in trap_locs] patches = [ plt.Circle(center, size) for center, size in zip( trap_locs_2d, radius_scale * sim_trap_counts / max(sim_trap_counts)) ] coll = matplotlib.collections.PatchCollection(patches, facecolors='blue', edgecolors='blue') ax.add_collection(coll) ax.set_ylim([-plot_size, plot_size]) ax.set_xlim([-plot_size, plot_size]) ax.set_xticks([]) ax.set_xticklabels('') ax.set_yticks([]) ax.set_yticklabels('') #Wind arrow plt.arrow(0.5, 0.5, 0.1 * scipy.cos(wind_angle), 0.1 * scipy.sin(wind_angle), transform=ax.transAxes, color='b', width=0.001) # ax.text(0.55, 0.5,'Wind',transform=ax.transAxes,color='b') ax.text(0, 1.5, 'N', horizontalalignment='center', verticalalignment='center', fontsize=25) ax.text(0, -1.5, 'S', horizontalalignment='center', verticalalignment='center', fontsize=25) ax.text(1.5, 0, 'E', horizontalalignment='center', verticalalignment='center', fontsize=25) ax.text(-1.5, 0, 'W', horizontalalignment='center', verticalalignment='center', fontsize=25) # plt.title('Simulated') fig.patch.set_facecolor('white') plt.axis('off') ax.text(0, 1.7, 'Trap Counts' + ' (Wind Mag: ' + str(wind_mag)[0:3] + ')', horizontalalignment='center', verticalalignment='center', fontsize=20) plt.savefig(file_name + '.png', format='png')
def conc_point_val_demo(dt=0.01, t_max=5, steps_per_frame=1, x=10., y=0.0, seed=DEFAULT_SEED): """Set up plume model and animate concentration at a point as time series. Demonstration of setting up plume model and processing the outputted puff arrays with the ConcentrationPointValueCalculator class, the resulting concentration time course at a point in the odour plume being displayed with the Matplotlib `plot` function. Parameters ---------- dt : float Simulation timestep. t_max : float End time to simulate to. steps_per_frame: integer Number of simulation time steps to perform between animation frames. x : float x-coordinate of point to measure concentration at. y : float y-coordinate of point to measure concentration at. seed : integer Seed for random number generator. Returns ------- fig : Figure Matplotlib figure object. ax : AxesSubplot Matplotlib axis object. anim : FuncAnimation Matplotlib animation object. """ rng = np.random.RandomState(seed) # define simulation region sim_region = models.Rectangle(x_min=0., x_max=100, y_min=-25., y_max=25.) # set up wind model wind_model = models.WindModel(sim_region, 21, 11, rng=rng) # set up plume model plume_model = models.PlumeModel(sim_region, (5., 0., 0.), wind_model, rng=rng) # let simulation run for 10s to initialise models for t in np.arange(0, 10, dt): wind_model.update(dt) plume_model.update(dt) # set up concentration point value calculator val_calc = processors.ConcentrationValueCalculator(1.) conc_vals = [] conc_vals.append(val_calc.calc_conc_point(plume_model.puff_array, x, y)) ts = [0.] # set up figure fig, ax, title = set_up_figure() # display initial concentration field as image conc_line, = plt.plot(ts, conc_vals) ax.set_xlim(0., t_max) ax.set_ylim(0., 150.) ax.set_xlabel('Time / s') ax.set_ylabel('Normalised concentration') ax.grid(True) fig.tight_layout() # define update function @update_decorator(dt, title, steps_per_frame, [wind_model, plume_model]) def update(i): ts.append(dt * i * steps_per_frame) conc_vals.append(val_calc.calc_conc_point(plume_model.puff_array, x, y)) conc_line.set_data(ts, conc_vals) return [conc_line] # create animation object n_frame = int(t_max / (dt * steps_per_frame) + 0.5) anim = FuncAnimation(fig, update, frames=n_frame, blit=True) return fig, ax, anim
def main(detection_threshold): # for wind_mag in np.arange(0.4,3.8,0.2): # wind_mag = float(sys.argv[1]) wind_angle = 9*scipy.pi/8. wind_mag = 1.6 file_name = 'trap_arrival_by_wind_live_coarse_dt' file_name = file_name +'_wind_mag_'+str(wind_mag)#+'_wind_angle_'+str(wind_angle)[0:4] file_name = file_name +'_detection_threshold_'+str(detection_threshold) output_file = file_name+'.pkl' dt = 0.25 plume_dt = 0.25 frame_rate = 20 times_real_time = 60 # seconds of simulation / sec in video capture_interval = int(scipy.ceil(times_real_time*(1./frame_rate)/dt)) simulation_time = 50.*60. #seconds release_delay = 30.*60#/(wind_mag) t_start = 0.0 t = 0. - release_delay # Set up figure fig = plt.figure(figsize=(11, 11)) ax = fig.add_subplot(111) #Video FFMpegWriter = animate.writers['ffmpeg'] metadata = {'title':file_name,} writer = FFMpegWriter(fps=frame_rate, metadata=metadata) writer.setup(fig, file_name+'.mp4', 500) wind_param = { 'speed': wind_mag, 'angle': wind_angle, 'evolving': False, 'wind_dt': None, 'dt': dt } wind_field_noiseless = wind_models.WindField(param=wind_param) #traps number_sources = 8 radius_sources = 1000.0 trap_radius = 0.5 location_list, strength_list = utility.create_circle_of_sources(number_sources, radius_sources,None) trap_param = { 'source_locations' : location_list, 'source_strengths' : strength_list, 'epsilon' : 0.01, 'trap_radius' : trap_radius, 'source_radius' : radius_sources } traps = trap_models.TrapModel(trap_param) #Wind and plume objects #Odor arena xlim = (-1500., 1500.) ylim = (-1500., 1500.) sim_region = models.Rectangle(xlim[0], ylim[0], xlim[1], ylim[1]) wind_region = models.Rectangle(xlim[0]*1.2,ylim[0]*1.2, xlim[1]*1.2,ylim[1]*1.2) source_pos = scipy.array([scipy.array(tup) for tup in traps.param['source_locations']]).T #wind model setup diff_eq = False constant_wind_angle = wind_angle aspect_ratio= (xlim[1]-xlim[0])/(ylim[1]-ylim[0]) noise_gain=3. noise_damp=0.071 noise_bandwidth=0.71 wind_grid_density = 200 Kx = Ky = 10000 #highest value observed to not cause explosion: 10000 wind_field = models.WindModel(wind_region,int(wind_grid_density*aspect_ratio), wind_grid_density,noise_gain=noise_gain,noise_damp=noise_damp, noise_bandwidth=noise_bandwidth,Kx=Kx,Ky=Ky, diff_eq=diff_eq,angle=constant_wind_angle,mag=wind_mag) # Set up plume model centre_rel_diff_scale = 2. # puff_release_rate = 0.001 puff_release_rate = 10 puff_spread_rate=0.005 puff_init_rad = 0.01 max_num_puffs=int(2e5) # max_num_puffs=100 plume_model = models.PlumeModel( sim_region, source_pos, wind_field,simulation_time+release_delay, plume_dt,plume_cutoff_radius=1500, centre_rel_diff_scale=centre_rel_diff_scale, puff_release_rate=puff_release_rate, puff_init_rad=puff_init_rad,puff_spread_rate=puff_spread_rate, max_num_puffs=max_num_puffs) # Create a concentration array generator array_z = 0.01 array_dim_x = 1000 array_dim_y = array_dim_x puff_mol_amount = 1. array_gen = processors.ConcentrationArrayGenerator( sim_region, array_z, array_dim_x, array_dim_y, puff_mol_amount) #Setup fly swarm wind_slippage = (0.,1.) swarm_size=8000 use_empirical_release_data = False #Grab wind info to determine heading mean wind_x,wind_y = wind_mag*scipy.cos(wind_angle),wind_mag*scipy.sin(wind_angle) beta = 1. release_times = scipy.random.exponential(beta,(swarm_size,)) kappa = 2. heading_data=None swarm_param = { 'swarm_size' : swarm_size, 'heading_data' : heading_data, 'initial_heading' : scipy.radians(scipy.random.uniform(0.0,360.0,(swarm_size,))), 'x_start_position' : scipy.zeros(swarm_size), 'y_start_position' : scipy.zeros(swarm_size), 'flight_speed' : scipy.full((swarm_size,), 1.5), 'release_time' : release_times, 'release_delay' : release_delay, 'cast_interval' : [1, 3], 'wind_slippage' : wind_slippage, 'odor_thresholds' : { 'lower': 0.0005, 'upper': detection_threshold }, 'schmitt_trigger':False, 'low_pass_filter_length':3, #seconds 'dt_plot': capture_interval*dt, 't_stop':3000., 'cast_timeout':20, 'airspeed_saturation':True } swarm = swarm_models.BasicSwarmOfFlies(wind_field_noiseless,traps,param=swarm_param, start_type='fh',track_plume_bouts=False,track_arena_exits=False) # xmin,xmax,ymin,ymax = -1000,1000,-1000,1000 #Initial concentration plotting conc_array = array_gen.generate_single_array(plume_model.puffs) xmin = sim_region.x_min; xmax = sim_region.x_max ymin = sim_region.y_min; ymax = sim_region.y_max im_extents = (xmin,xmax,ymin,ymax) vmin,vmax = 0.,50. cmap = matplotlib.colors.ListedColormap(['white', 'orange']) conc_im = ax.imshow(conc_array.T[::-1], extent=im_extents, vmin=vmin, vmax=vmax, cmap=cmap) xmin,xmax,ymin,ymax = -1000,1000,-1000,1000 #For looking at the distace-bound plumes xmin,xmax,ymin,ymax = -3000,3000,-3000,3000 buffr = 100 ax.set_xlim((xmin-buffr,xmax+buffr)) ax.set_ylim((ymin-buffr,ymax+buffr)) #Conc array gen to be used for the flies sim_region_tuple = plume_model.sim_region.as_tuple() box_min,box_max = sim_region_tuple[1],sim_region_tuple[2] #for the plume distance cutoff version, make sure this is at least 2x radius box_min,box_max = -3000.,3000. r_sq_max=20;epsilon=0.00001;N=1e6 array_gen_flies = processors.ConcentrationValueFastCalculator( box_min,box_max,r_sq_max,epsilon,puff_mol_amount,N) # plt.ion() # plt.show() # raw_input() while t<simulation_time: for k in range(capture_interval): #update flies print('t: {0:1.2f}'.format(t)) #update the swarm for j in range(int(dt/plume_dt)): wind_field.update(plume_dt) plume_model.update(plume_dt,verbose=True) # velocity_field = wind_field.velocity_field # u,v = velocity_field[:,:,0],velocity_field[:,:,1] # u,v = u[0:full_size-1:shrink_factor,0:full_size-1:shrink_factor],\ # v[0:full_size-1:shrink_factor,0:full_size-1:shrink_factor] # vector_field.set_UVC(u,v) if t>0.: swarm.update(t,dt,wind_field_noiseless,array_gen_flies,traps,plumes=plume_model, pre_stored=False) t+= dt with open(output_file, 'w') as f: pickle.dump((wind_field_noiseless,swarm),f)
def concentration_array_demo(dt=0.01, t_max=100, steps_per_frame=50, seed=DEFAULT_SEED): """Set up plume model and animate concentration fields. Demonstration of setting up plume model and processing the outputted puff arrays with the `ConcentrationArrayGenerator` class, the resulting arrays being displayed with the Matplotlib `imshow` function. Parameters ---------- dt : float Simulation timestep. t_max : float End time to simulate to. steps_per_frame: integer Number of simulation time steps to perform between animation frames. seed : integer Seed for random number generator. Returns ------- fig : Figure Matplotlib figure object. ax : AxesSubplot Matplotlib axis object. anim : FuncAnimation Matplotlib animation object. """ rng = np.random.RandomState(seed) # define simulation region sim_region = models.Rectangle(x_min=0., x_max=100, y_min=-25., y_max=25.) # set up wind model wind_model = models.WindModel(sim_region, 21, 11, rng=rng) # set up plume model plume_model = models.PlumeModel(sim_region, (5., 0., 0.), wind_model, rng=rng) # let simulation run for 10s to initialise models for t in np.arange(0, 10, dt): wind_model.update(dt) plume_model.update(dt) # set up concentration array generator array_gen = processors.ConcentrationArrayGenerator(sim_region, 0.01, 500, 250, 1.) # set up figure fig, ax, title = set_up_figure() # display initial concentration field as image conc_array = array_gen.generate_single_array(plume_model.puff_array) conc_im = plt.imshow(conc_array.T, extent=sim_region, cmap='Reds', vmin=0., vmax=1.) ax.set_xlabel('x-coordinate / m') ax.set_ylabel('y-coordinate / m') ax.set_aspect(1) fig.tight_layout() # define update function @update_decorator(dt, title, steps_per_frame, [wind_model, plume_model]) def update(i): conc_im.set_data( array_gen.generate_single_array(plume_model.puff_array).T) return [conc_im] # create animation object n_frame = int(t_max / (dt * steps_per_frame) + 0.5) anim = FuncAnimation(fig, update, frames=n_frame, blit=True) return fig, ax, anim
import json source_locations = [ (0., 0.), ] source_pos = scipy.array([scipy.array(tup) for tup in source_locations]) #don't transpose for the Gaussian plumes constant_wind_angle = 0. #directly positive x wind direction wind_mag = 1.6 gaussianfitPlumes = models.GaussianFitPlume(source_pos, constant_wind_angle, wind_mag) xlim = (0., 1200.) ylim = (-50., 50.) sim_region = models.Rectangle(xlim[0], ylim[0], xlim[1], ylim[1]) xmin = sim_region.x_min xmax = sim_region.x_max ymin = sim_region.y_min ymax = sim_region.y_max im_extents = (xmin, xmax, ymin, ymax) conc_d = gaussianfitPlumes.conc_im(im_extents) # conc_d[conc_d>.9]=0. # conc_d[conc_d<.01]=0. cmap = 'YlOrBr' ax = plt.subplot(211) conc_im1 = plt.imshow(conc_d, extent=im_extents,
def make_time_averaged_plume(wind_mag): dt = 0.25 simulation_time = 35 * 60. #seconds collection_begins = 25 * 60. #to let the plume fill the space #traps source_locations = [ (0., 0.), ] #Odor arena xlim = (0., 1200.) ylim = (-50., 50.) sim_region = models.Rectangle(xlim[0], ylim[0], xlim[1], ylim[1]) wxlim = (-1500., 1500.) wylim = (-1500., 1500.) wind_region = models.Rectangle(wxlim[0] * 1.2, wylim[0] * 1.2, wxlim[1] * 1.2, wylim[1] * 1.2) source_pos = scipy.array([scipy.array(tup) for tup in source_locations]).T #wind model setup diff_eq = False constant_wind_angle = 0. #directly positive x wind direction aspect_ratio = (wxlim[1] - wxlim[0]) / (wylim[1] - wylim[0]) noise_gain = 3. noise_damp = 0.071 noise_bandwidth = 0.71 wind_grid_density = 200 Kx = Ky = 10000 #highest value observed to not cause explosion: 10000 wind_field = models.WindModel(wind_region, int(wind_grid_density * aspect_ratio), wind_grid_density, noise_gain=noise_gain, noise_damp=noise_damp, noise_bandwidth=noise_bandwidth, Kx=Kx, Ky=Ky, diff_eq=diff_eq, angle=constant_wind_angle, mag=wind_mag) #detection_threshold detection_threshold = 0.05 # Set up plume model plume_width_factor = 1. centre_rel_diff_scale = 2. * plume_width_factor puff_release_rate = 10 puff_spread_rate = 0.005 puff_init_rad = 0.01 max_num_puffs = int(2e5) plume_model = models.PlumeModel( sim_region, source_pos, wind_field, simulation_time, dt, centre_rel_diff_scale=centre_rel_diff_scale, puff_release_rate=puff_release_rate, puff_init_rad=puff_init_rad, puff_spread_rate=puff_spread_rate, max_num_puffs=max_num_puffs) #Setup second plume model (Gaussian approximation) source_pos = scipy.array([scipy.array(tup) for tup in source_locations]) gaussianfitPlumes = models.AdjustedGaussianFitPlume( source_pos, constant_wind_angle, wind_mag) source_pos = scipy.array([scipy.array(tup) for tup in source_locations]).T # Create a concentration array generator array_z = 0.01 array_dim_y = 400 array_dim_x = 5000 puff_mol_amount = 1. array_gen = processors.ConcentrationArrayGenerator(sim_region, array_z, array_dim_x, array_dim_y, puff_mol_amount) conc_locs_x, conc_locs_y = np.meshgrid( np.linspace(xlim[0], xlim[1], array_dim_x), np.linspace(ylim[0], ylim[1], array_dim_y)) fig = plt.figure(figsize=(4 * 4, 4)) #Video collection file_name = 'adjusted_gaussian_test_comparison_wind_mag' + str(wind_mag) output_file = file_name + '.pkl' frame_rate = 20 times_real_time = 1 # seconds of simulation / sec in video capture_interval = int(scipy.ceil(times_real_time * (1. / frame_rate) / dt)) FFMpegWriter = animate.writers['ffmpeg'] metadata = { 'title': file_name, } writer = FFMpegWriter(fps=frame_rate, metadata=metadata) writer.setup(fig, file_name + '.mp4', 500) #Setup basic flies num_flies = 1000 fly_x_0, fly_y_0 = np.linspace(xlim[0], xlim[1], num_flies), 20. * np.ones(num_flies) fly_velocity = np.array([0., -1.6]) detection_threshold = 0.05 # # flies = basic_fly_models.Flies(fly_x_0,fly_y_0,fly_velocity,False, # puff_mol_amount / (8 * np.pi**3)**0.5,plume_model.puffs, # detection_threshold,utility.compute_Gaussian,use_grid=False) #Setup swarm flies trap_param = { 'source_locations': [source_pos], 'source_strengths': [1.], 'epsilon': 0.01, 'trap_radius': 1., 'source_radius': 1000. } traps = trap_models.TrapModel(trap_param) wind_param = { 'speed': wind_mag, 'angle': 2 * np.pi, 'evolving': False, 'wind_dt': None, 'dt': dt } wind_field_noiseless = wind_models.WindField(param=wind_param) swarm_param = { 'swarm_size': num_flies, 'initial_heading': scipy.radians(270 * np.ones(num_flies)), 'x_start_position': np.copy(fly_x_0), 'y_start_position': np.copy(fly_y_0), 'flight_speed': scipy.full((num_flies, ), 1.6), 'release_time': np.zeros(num_flies), 'release_delay': 0., 'cast_interval': [1, 3], 'wind_slippage': [0., 0.], 'heading_data': None, 'odor_thresholds': { 'lower': 0.0005, 'upper': detection_threshold }, 'schmitt_trigger': False, 'low_pass_filter_length': 3, #seconds 't_stop': 3000., 'dt_plot': dt, 'cast_timeout': 20, 'airspeed_saturation': True } swarm1 = swarm_models.BasicSwarmOfFlies(wind_field_noiseless, traps, param=swarm_param, start_type='fh', track_plume_bouts=False, track_arena_exits=False) swarm_param.update({ 'x_start_position': np.copy(fly_x_0), 'y_start_position': np.copy(fly_y_0) }) swarm2 = swarm_models.BasicSwarmOfFlies(wind_field_noiseless, traps, param=swarm_param, start_type='fh', track_plume_bouts=False, track_arena_exits=False) #concentration computer for flies box_min, box_max = -100., 1200. r_sq_max = 20 epsilon = 0.00001 N = 1e6 array_gen_flies = processors.ConcentrationValueFastCalculator( box_min, box_max, r_sq_max, epsilon, puff_mol_amount, N) #Compute initial concentration field and display as image ax = plt.subplot(211) buffr = 20 ax.set_xlim((xlim[0] - buffr, xlim[1] + buffr)) ax.set_ylim((ylim[0] - buffr, ylim[1] + buffr)) # zoom_x_min,zoom_x_max = 900,950 # ax.set_xlim((zoom_x_min,zoom_x_max)) # ax.set_ylim((-10,10)) conc_array = array_gen.generate_single_array(plume_model.puffs) xmin = sim_region.x_min xmax = sim_region.x_max ymin = sim_region.y_min ymax = sim_region.y_max im_extents = (xmin, xmax, ymin, ymax) # vmin,vmax = 0.,1. vmin, vmax = 0., .05 conc_im = ax.imshow(conc_array.T[::-1], extent=im_extents, vmin=vmin, vmax=vmax, cmap='Reds', aspect='auto') plt.colorbar(conc_im, ax=ax) # ax.set_aspect('equal') #Puff center scatter plot puffs_reshaped = plume_model.puffs.reshape(-1, plume_model.puffs.shape[-1]) px, py, _, r_sq = puffs_reshaped.T # puff_dots = plt.scatter(px,py,s=r_sq,alpha=0.5,color='k') #Plot flies edgecolor_dict1 = {0: 'red', 1: 'white'} facecolor_dict1 = {0: 'red', 1: 'white'} # fly_edgecolors = [edgecolor_dict1[mode] for mode in flies.mask_caught] # fly_facecolors = [facecolor_dict1[mode] for mode in flies.mask_caught] # fly_dots1 = plt.scatter(flies.x, flies.y, # edgecolor=fly_edgecolors,facecolor = fly_facecolors,alpha=0.9) #Plot swarm Mode_StartMode = 0 Mode_FlyUpWind = 1 Mode_CastForOdor = 2 Mode_Trapped = 3 edgecolor_dict2 = { Mode_StartMode: 'blue', Mode_FlyUpWind: 'yellow', Mode_CastForOdor: 'red', Mode_Trapped: 'black' } facecolor_dict2 = { Mode_StartMode: 'blue', Mode_FlyUpWind: 'yellow', Mode_CastForOdor: 'white', Mode_Trapped: 'black' } fly_edgecolors = [edgecolor_dict2[mode] for mode in swarm1.mode] fly_facecolors = [facecolor_dict2[mode] for mode in swarm1.mode] fly_dots2 = plt.scatter(swarm1.x_position, swarm1.x_position, edgecolor=fly_edgecolors, facecolor=fly_facecolors, alpha=0.9) axtext = ax.text(-0.1, 0.5, '', transform=ax.transAxes, verticalalignment='center', horizontalalignment='center') #Second image: Gaussian fit plume ax1 = plt.subplot(212) buffr = 20 ax1.set_xlim((xlim[0] - buffr, xlim[1] + buffr)) ax1.set_ylim((ylim[0] - buffr, ylim[1] + buffr)) conc_d = gaussianfitPlumes.conc_im(im_extents) #Perform adjustments to the probability plume cmap = 'YlOrBr' conc_im1 = plt.imshow(conc_d, extent=im_extents, interpolation='none', cmap=cmap, origin='lower', aspect='auto') plt.colorbar(conc_im1, ax=ax1) fly_dots3 = plt.scatter(swarm2.x_position, swarm2.x_position, edgecolor=fly_edgecolors, facecolor=fly_facecolors, alpha=0.9) ax1text = ax1.text(-0.1, 0.5, '', transform=ax1.transAxes, verticalalignment='center', horizontalalignment='center') #Display initial wind vector field -- subsampled from total velocity_field = wind_field.velocity_field u, v = velocity_field[:, :, 0], velocity_field[:, :, 1] full_size = scipy.shape(u)[0] shrink_factor = 10 x_origins, y_origins = wind_field.x_points, wind_field.y_points coords = scipy.array(list(itertools.product(x_origins, y_origins))) x_coords, y_coords = coords[:, 0], coords[:, 1] vector_field = ax.quiver(x_coords, y_coords, u, v) # # plt.ion() # plt.show() # t = 0. capture_interval = 25 # while t < simulation_time: for k in range(capture_interval): wind_field.update(dt) plume_model.update(dt, verbose=True) t += dt print(t) if t > collection_begins: # accum_threshold_crosses += (conc_array>=detection_threshold).astype(float) # flies.update(dt,t,plume_model.puffs) swarm1.update(t, dt, wind_field_noiseless, array_gen_flies, traps, plumes=plume_model, pre_stored=False) swarm2.update(t, dt, wind_field_noiseless, gaussianfitPlumes, traps) conc_array = array_gen.generate_single_array(plume_model.puffs) # conc_im.set_data((conc_array>=detection_threshold).astype(float).T)#[::-1]) # conc_im.set_data((conc_array>=0.01).astype(float).T[::-1]) conc_im.set_data(conc_array.T[::-1]) # conc_im1.set_data(accum_threshold_crosses.T[::-1]) # fly_dots1.set_offsets(np.c_[flies.x,flies.y]) # fly_edgecolors = [edgecolor_dict1[mode] for mode in flies.mask_caught] # fly_facecolors = [facecolor_dict1[mode] for mode in flies.mask_caught] # fly_dots1.set_edgecolor(fly_edgecolors) # fly_dots1.set_facecolor(fly_facecolors) fly_dots2.set_offsets(np.c_[swarm1.x_position, swarm1.y_position]) fly_edgecolors = [ edgecolor_dict2[mode] for mode in swarm1.mode ] fly_facecolors = [ facecolor_dict2[mode] for mode in swarm1.mode ] fly_dots2.set_edgecolor(fly_edgecolors) fly_dots2.set_facecolor(fly_facecolors) axtext.set_text( "Start Mode: {0:.3f} \n Surging: {1:.3f} \n Casting: {2:.3f} \n Trapped: {3:.3f} \n" .format( np.sum(swarm1.mode == Mode_StartMode).astype(float) / len(swarm1.mode), np.sum(swarm1.mode == Mode_FlyUpWind).astype(float) / len(swarm1.mode), np.sum(swarm1.mode == Mode_CastForOdor).astype(float) / len(swarm1.mode), np.sum(swarm1.mode == Mode_Trapped).astype(float) / len(swarm1.mode))) fly_dots3.set_offsets(np.c_[swarm2.x_position, swarm2.y_position]) fly_edgecolors = [ edgecolor_dict2[mode] for mode in swarm2.mode ] fly_facecolors = [ facecolor_dict2[mode] for mode in swarm2.mode ] fly_dots3.set_edgecolor(fly_edgecolors) fly_dots3.set_facecolor(fly_facecolors) ax1text.set_text( "Start Mode: {0:.3f} \n Surging: {1:.3f} \n Casting: {2:.3f} \n Trapped: {3:.3f} \n" .format( np.sum(swarm2.mode == Mode_StartMode).astype(float) / len(swarm1.mode), np.sum(swarm2.mode == Mode_FlyUpWind).astype(float) / len(swarm1.mode), np.sum(swarm2.mode == Mode_CastForOdor).astype(float) / len(swarm1.mode), np.sum(swarm2.mode == Mode_Trapped).astype(float) / len(swarm1.mode))) puffs_reshaped = plume_model.puffs.reshape( -1, plume_model.puffs.shape[-1]) px, py, _, r_sq = puffs_reshaped.T # puff_dots.set_offsets(np.c_[px,py]) # print(np.unique(r_sq[(px>zoom_x_min)&(px<zoom_x_max)])) # puff_dots.set_sizes(10*r_sq) # plt.pause(.0001) writer.grab_frame()
location_list, strength_list = utility.create_circle_of_sources(number_sources, radius_sources,None) trap_param = { 'source_locations' : location_list, 'source_strengths' : strength_list, 'epsilon' : 0.01, 'trap_radius' : trap_radius, 'source_radius' : radius_sources } traps = trap_models.TrapModel(trap_param) #Odor arena xlim = (-1500., 1500.) ylim = (-1500., 1500.) sim_region = models.Rectangle(xlim[0], ylim[0], xlim[1], ylim[1]) wind_region = models.Rectangle(xlim[0]*2,ylim[0]*2, xlim[1]*2,ylim[1]*2) im_extents = xlim[0], xlim[1], ylim[0], ylim[1] source_pos = scipy.array([scipy.array(tup) for tup in traps.param['source_locations']]).T #lazy plume parameters puff_mol_amount = 1. r_sq_max=20;epsilon=0.00001;N=1e6 lazyPompyPlumes = models.OnlinePlume(sim_region, source_pos, wind_field_noiseless, simulation_time,dt,r_sq_max,epsilon,puff_mol_amount,N)
def main(wind_mag, i): #np.arange(0.4,3.8,0.2): random_state = np.random.RandomState(i) file_name = 'test_lazy_plumes_wind_mag_' + str(wind_mag) output_file = file_name + '.pkl' dt = 0.25 frame_rate = 20 times_real_time = 20 # seconds of simulation / sec in video capture_interval = int(scipy.ceil(times_real_time * (1. / frame_rate) / dt)) simulation_time = 50. * 60. #seconds release_delay = 0. * 60 #/(wind_mag) t_start = 0.25 t = 0.25 - release_delay # Set up figure # fig = plt.figure(figsize=(11, 11)) fig = plt.figure(figsize=(7, 7)) ax = fig.add_subplot(111) # #Video FFMpegWriter = animate.writers['ffmpeg'] metadata = { 'title': file_name, } writer = FFMpegWriter(fps=frame_rate, metadata=metadata) writer.setup(fig, file_name + '.mp4', 500) wind_angle = 7 * scipy.pi / 8. # wind_angle = 7*scipy.pi/4. wind_param = { 'speed': wind_mag, 'angle': wind_angle, 'evolving': False, 'wind_dt': None, 'dt': dt } wind_field_noiseless = wind_models.WindField(param=wind_param) #traps number_sources = 8 radius_sources = 1000.0 trap_radius = 0.5 location_list, strength_list = utility.create_circle_of_sources( number_sources, radius_sources, None) trap_param = { 'source_locations': location_list, 'source_strengths': strength_list, 'epsilon': 0.01, 'trap_radius': trap_radius, 'source_radius': radius_sources } traps = trap_models.TrapModel(trap_param) #Wind and plume objects #Odor arena xlim = (-1500., 1500.) ylim = (-1500., 1500.) sim_region = models.Rectangle(xlim[0], ylim[0], xlim[1], ylim[1]) wind_region = models.Rectangle(xlim[0] * 2, ylim[0] * 2, xlim[1] * 2, ylim[1] * 2) im_extents = xlim[0], xlim[1], ylim[0], ylim[1] source_pos = scipy.array( [scipy.array(tup) for tup in traps.param['source_locations']]).T #wind model setup # diff_eq = False # constant_wind_angle = wind_angle # aspect_ratio= (xlim[1]-xlim[0])/(ylim[1]-ylim[0]) # noise_gain=3. # noise_damp=0.071 # noise_bandwidth=0.71 # wind_grid_density = 200 # Kx = Ky = 10000 #highest value observed to not cause explosion: 10000 # wind_field = models.WindModel(wind_region,int(wind_grid_density*aspect_ratio), # wind_grid_density,noise_gain=noise_gain,noise_damp=noise_damp, # noise_bandwidth=noise_bandwidth,Kx=Kx,Ky=Ky,noise_rand=random_state, # diff_eq=diff_eq,angle=constant_wind_angle,mag=wind_mag) # source_pos = scipy.array([scipy.array(tup) for tup in traps.param['source_locations']]) #lazy plume parameters puff_mol_amount = 1. r_sq_max = 20 epsilon = 0.00001 N = 1e6 centre_rel_diff_scale = 2. puff_release_rate = 10 puff_spread_rate = 0.005 puff_init_rad = 0.01 max_num_puffs = int(2e5) lazyPompyPlumes = models.OnlinePlume( sim_region, source_pos, wind_field_noiseless, simulation_time, dt, r_sq_max, epsilon, puff_mol_amount, N, centre_rel_diff_scale=centre_rel_diff_scale, puff_release_rate=puff_release_rate, puff_spread_rate=puff_spread_rate, puff_init_rad=puff_init_rad) #Setup fly swarm wind_slippage = (0., 1.) swarm_size = 500 # swarm_size=10 use_empirical_release_data = False #Grab wind info to determine heading mean wind_x, wind_y = wind_mag * scipy.cos(wind_angle), wind_mag * scipy.sin( wind_angle) beta = 1. # release_times = scipy.random.exponential(beta,(swarm_size,)) release_times = np.zeros((swarm_size, )) kappa = 2. heading_data = None #Flies also use parameters (for schmitt_trigger, detection probabilities) # determined in #fly_behavior_sim/near_plume_simulation_sutton.py swarm_param = { 'swarm_size': swarm_size, 'heading_data': heading_data, 'initial_heading': scipy.radians(scipy.random.uniform(0.0, 360.0, (swarm_size, ))), 'x_start_position': scipy.zeros(swarm_size), # 'x_start_position' : np.random.uniform(900,1100,swarm_size), # 'y_start_position' : np.random.uniform(0,100,swarm_size), 'y_start_position': scipy.zeros(swarm_size), # 'x_start_position' : (-990/np.sqrt(2.))*scipy.ones(swarm_size), # 'y_start_position' : (990./np.sqrt(2.))*scipy.ones(swarm_size), 'flight_speed': scipy.full((swarm_size, ), 1.5), 'release_time': release_times, 'release_delay': release_delay, 'cast_interval': [1, 3], 'wind_slippage': wind_slippage, 'odor_thresholds': { 'lower': 0.0005, 'upper': 0.05 }, 'schmitt_trigger': False, 'low_pass_filter_length': 3, #seconds 'dt_plot': capture_interval * dt, 't_stop': 3000., 'cast_timeout': 20, 'airspeed_saturation': True } swarm = swarm_models.BasicSwarmOfFlies(wind_field_noiseless, traps, param=swarm_param, start_type='fh', track_plume_bouts=False, track_arena_exits=False) # xmin,xmax,ymin,ymax = -1000,1000,-1000,1000 # Concentration plotting # conc_d = lazyPompyPlumes.conc_im(im_extents) # # cmap = matplotlib.colors.ListedColormap(['white', 'orange']) # cmap = 'YlOrBr' # # conc_im = plt.imshow(conc_d,extent=im_extents, # interpolation='none',cmap = cmap,origin='lower') # # plt.colorbar() xmin, xmax, ymin, ymax = -1000, 1000, -1000, 1000 buffr = 100 ax.set_xlim((xmin - buffr, xmax + buffr)) ax.set_ylim((ymin - buffr, ymax + buffr)) #Initial fly plotting #Sub-dictionary for color codes for the fly modes Mode_StartMode = 0 Mode_FlyUpWind = 1 Mode_CastForOdor = 2 Mode_Trapped = 3 edgecolor_dict = { Mode_StartMode: 'blue', Mode_FlyUpWind: 'red', Mode_CastForOdor: 'red', Mode_Trapped: 'black' } facecolor_dict = { Mode_StartMode: 'blue', Mode_FlyUpWind: 'red', Mode_CastForOdor: 'white', Mode_Trapped: 'black' } fly_edgecolors = [edgecolor_dict[mode] for mode in swarm.mode] fly_facecolors = [facecolor_dict[mode] for mode in swarm.mode] fly_dots = plt.scatter(swarm.x_position, swarm.y_position, edgecolor=fly_edgecolors, facecolor=fly_facecolors, alpha=0.9) #Put the time in the corner (xmin, xmax) = ax.get_xlim() (ymin, ymax) = ax.get_ylim() text = '0 min 0 sec' timer = ax.text(xmax, ymax, text, color='r', horizontalalignment='right') ax.text(1., 1.02, 'time since release:', color='r', transform=ax.transAxes, horizontalalignment='right') # #traps for x, y in traps.param['source_locations']: #Black x plt.scatter(x, y, marker='x', s=50, c='k') # Red circles # p = matplotlib.patches.Circle((x, y), 15,color='red') # ax.add_patch(p) #Remove plot edges and add scale bar fig.patch.set_facecolor('white') plt.plot([-900, -800], [900, 900], color='k') #,transform=ax.transData,color='k') ax.text(-900, 820, '100 m') plt.axis('off') #Wind arrow arrow_size = 0.1 # arrowstyle=matplotlib.patches.ArrowStyle.Fancy(head_length=2, head_width=2, tail_width=.4) wind_arrow = matplotlib.patches.FancyArrowPatch( (0.9, 0.9), (0.9 + arrow_size * np.cos(wind_angle), 0.9 + arrow_size * np.sin(wind_angle)), transform=ax.transAxes, color='orange', mutation_scale=10) #,arrowstyle=arrowstyle) ax.add_patch(wind_arrow) #Fly behavior color legend for mode, fly_facecolor, fly_edgecolor, a in zip( ['Dispersing', 'Surging', 'Casting', 'Trapped'], facecolor_dict.values(), edgecolor_dict.values(), [0, 50, 100, 150]): plt.scatter([1000], [-600 - a], edgecolor=fly_edgecolor, facecolor=fly_facecolor, s=20) plt.text(1050, -600 - a, mode, verticalalignment='center') plt.ion() plt.show() # raw_input() while t < simulation_time: for k in range(capture_interval): #update flies print('t: {0:1.2f}'.format(t)) swarm.update(t, dt, wind_field_noiseless, lazyPompyPlumes, traps) t += dt # time.sleep(0.001) # Update live display # Update time display release_delay = release_delay / 60. text = '{0} min {1} sec'.format(int(scipy.floor(abs(t / 60.))), int(scipy.floor(abs(t) % 60.))) timer.set_text(text) # '''plot the flies''' fly_dots.set_offsets(scipy.c_[swarm.x_position, swarm.y_position]) fly_edgecolors = [edgecolor_dict[mode] for mode in swarm.mode] fly_facecolors = [facecolor_dict[mode] for mode in swarm.mode] # fly_dots.set_edgecolor(fly_edgecolors) fly_dots.set_facecolor(fly_facecolors) plt.pause(0.0001) # writer.grab_frame() trap_list = [] for trap_num, trap_loc in enumerate(traps.param['source_locations']): mask_trap = swarm.trap_num == trap_num trap_cnt = mask_trap.sum() trap_list.append(trap_cnt) total_cnt = sum(trap_list) # writer.finish() with open(output_file, 'w') as f: pickle.dump((wind_field, swarm), f)