Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
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')
Esempio n. 7
0
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)
Esempio n. 8
0
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)
Esempio n. 10
0
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
Esempio n. 11
0
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
Esempio n. 12
0
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
Esempio n. 13
0
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)
Esempio n. 14
0
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)
Esempio n. 15
0
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')
Esempio n. 16
0
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
Esempio n. 18
0
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')
Esempio n. 19
0
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
Esempio n. 20
0
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)
Esempio n. 21
0
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)