Data from: Wind history shapes olfactory search response in free flying Drosophila melanogaster
Data files
Jul 23, 2026 version files 2.01 GB
-
CFDcasefiles.zip
32.29 MB
-
fly_trajectory_data_spatially_processed_with_cfd.zip
217.74 MB
-
fly_trajectory_data_spatially_processed.zip
275.74 MB
-
gust_streamlines1.avi
98.58 MB
-
gust_streamlines2.avi
91.54 MB
-
preprocessed_fly_trajectories.zip
981.42 MB
-
README.md
15.76 KB
-
windspeeds_cfd.csv
302.11 MB
-
windtunnel_winddata.csv
7.14 MB
Abstract
The ability of flying insects to locate distant food and mates by tracking odor plumes through turbulent and unsteady flow represents a remarkable feat of sensorimotor integration. Successful navigation requires not only extracting a reliable directional estimate from an intermittent olfactory signal, but also contending with the challenging dynamics of variable winds. While prior work has established that insects integrate the history of odor encounters to shape search decisions, whether they also retain a working memory of recently experienced wind conditions has remained unknown. Here, we use optogenetics combined with controlled wind perturbations in a free-flight wind tunnel to investigate how wind history modulates the olfactory search behavior of Drosophila melanogaster. By introducing lateral "gust'' flow via auxiliary fans and independently delivering olfactory stimuli, we show that the wind experienced during an olfactory stimulus shapes both the immediate surge response and the subsequent spatial search. Flies that received an olfactory stimulus while being displaced by a crosswind gust were significantly more likely to return to the gust zone during the post-stimulus search phase compared to flies that received the same odor cue in steady laminar flow. Meanwhile, surge responses and course directions exhibited during search indicate that moment-to-moment flight kinematics may be driven more by instantaneous flow. These results reveal that wind experience is tracked in addition to olfactory experience, and provide evidence that Drosophila maintain a short-term working memory of ambient wind conditions to guide olfactory navigation.
Description of the data and file structure
This repository contains fly-trajectory data and wind-field data from experiments studying how Drosophila melanogaster respond to localized wind gusts in a wind tunnel. Flies were tracked in three dimensions using the braid multi-camera tracking system while an optogenetic stimulus (red LED flash) was delivered coincident with a wind gust nozzle activation. Data were collected across two recording sessions (May 2023 and November 2023).
All analysis code is available at: https://github.com/JaleesaHoule/GustResponseOptoTracking
Files and variables
Preprocessed fly trajectory data (HDF5)
These two files are provided within the archive: preprocessed_fly_trajectories.zip
c1xwt_merged_new_may.hdf — trajectories from the May 2023 recording sessions
c1xwt_merged_new_nov.hdf — trajectories from the November 2023 recording sessions
Please note: the raw data for each night of experiments are not uploaded due to file size but can be made available upon reasonable request.
Each file is a pandas DataFrame stored in HDF5 format (read with pandas.read_hdf()). Each row is one time step (10 ms frame) of one fly trajectory.
| Column | Description |
|---|---|
obj_id |
Object ID assigned by braid for that trajectory within a single night's experiment. May not be unique across nights. |
obj_id_unique |
Globally unique trajectory identifier, formatted as {obj_id}_{YYYYMMDD}_{HHMMSS} (e.g. 93_20230507_184139). Use this column to group rows into individual trajectories. |
frame |
Frame number from the braid experiment. Recording is at 100 Hz (10 ms per frame). |
timestamp |
Unix epoch time (seconds) at the time of recording. |
millis |
Time elapsed since the start of the recording session (milliseconds). |
time stamp |
Time relative to the onset of the experimental stimulus for that trajectory (milliseconds). t=0 is the frame at which the flash/gust was triggered; negative values are pre-stimulus. Sampled at 10 ms intervals. |
x |
x position in the wind tunnel (meters). Positive x is upwind (toward the flow inlet). |
y |
y position in the wind tunnel (meters). Positive y is to the right when facing upwind. |
z |
Altitude in the wind tunnel (meters). |
xvel |
Ground velocity in the x direction (m/s). Positive means flying upwind. |
yvel |
Ground velocity in the y direction (m/s). Negative means flying to the left (as viewed from upwind). |
zvel |
Ground velocity in the z direction (m/s). Positive means gaining altitude. |
Flash_bool |
True if an optogenetic flash event was triggered at this frame. |
duration |
Stimulus intensity code at the triggering event. 100 = full-intensity flash (experimental), 50 = half-intensity flash (experimental), 0 = sham trial (no flash, control for naturalistic motion). |
left_gust |
1 if the wind gust nozzle on the left side of the tunnel was activated during this trial; 0 otherwise. NaN for frames with no associated trigger event. |
right_gust |
1 if the wind gust nozzle on the right side of the tunnel was activated during this trial; 0 otherwise. NaN for frames with no associated trigger event. |
last_flash |
Epoch time of the most recent preceding flash event (seconds). |
time_since_flash_millis |
Time elapsed since the most recent preceding flash event (milliseconds). |
time_since_flash_mins |
Time elapsed since the most recent preceding flash event (minutes). |
orientation |
Fly's flight orientation at the moment of the trigger event. 'u' = flying upwind (positive xvel at t=0); 'd' = flying downwind. |
heading |
Fly's instantaneous heading direction (radians), computed as arctan2(yvel, xvel). Upwind (positive x) = 0; ranges from −π to π. Raw, unsmoothed. |
ang vel |
Angular velocity of the trajectory (rad/s), computed from raw heading differences between consecutive frames. Unsmoothed. |
theta smooth |
Smoothed heading direction (radians). Produced by Savitzky–Golay differentiation via pynumdiff. |
theta dot smooth |
Smoothed angular velocity (rad/s). Derivative of theta smooth. |
P00–P55 |
Elements of the braid Kalman filter covariance matrix for position and velocity estimates. These are internal tracking uncertainty metrics and are not used in the published analysis. |
CFD-merged trajectory data (HDF5)
This file is provided within the archive: preprocessed_fly_trajectories.zip
merged_gust_df_with_cfd_wind.hdf — all fly trajectories (both sessions, flash + sham + no-gust, all positional groups) concatenated into a single DataFrame with CFD wind vectors appended. Read with pandas.read_hdf(path, key='i').
Columns are the same as the *_with_cfd.parquet files above (fly-kinematics columns plus xvel_wind1–zvel_wind5, x_wind1–z_wind5), covering all conditions in a single file.
Spatially processed fly trajectory data — fly kinematics only
These nine files are provided as a single archive: fly_trajectory_data_spatially_processed.zip
All files are pandas DataFrames in Parquet format (read with pandas.read_parquet()). They are produced by running Code/data_processing.py on the raw HDF files above (see GitHub repo).
Pre-processing applied to all files:
- Right-gust trajectories are mirrored (y, yvel, and heading multiplied by −1) so that all gusts appear to come from the left. This allows flash, sham, and no-gust conditions to be analyzed together.
- Trajectories are quality-filtered: z must remain between −0.1 and 0.5 m during the stimulus window (0–675 ms); trajectory must extend at least 1680 ms post-stimulus; velocity components must be < 2 m/s; trajectory must span > 2 cm in each of x, y, and z.
- Trajectories are assigned to one of three positional groups based on mean x-position during the gust window (0–675 ms):
- before (upstream of gust): mean x < −0.2 m
- during (in the gust zone): −0.2 m ≤ mean x < −0.1 m
- after (downstream, past the gust): mean x ≥ −0.1 m
Experimental conditions:
| File | Condition | Gust | Flash |
|---|---|---|---|
df_before_gust.parquet |
Flash + gust, fly was upstream | Yes | Yes (duration > 0) |
df_during_gust.parquet |
Flash + gust, fly was in gust zone | Yes | Yes (duration > 0) |
df_after_gust.parquet |
Flash + gust, fly was downstream | Yes | Yes (duration > 0) |
before_gust_sham.parquet |
Sham (gust, no flash), fly was upstream | Yes | No (duration = 0) |
during_gust_sham.parquet |
Sham (gust, no flash), fly was in gust zone | Yes | No (duration = 0) |
after_gust_sham.parquet |
Sham (gust, no flash), fly was downstream | Yes | No (duration = 0) |
flash_before_nogust.parquet |
Flash only (no gust), fly was upstream | No | Yes (duration > 0) |
flash_during_nogust.parquet |
Flash only (no gust), fly was in gust zone | No | Yes (duration > 0) |
flash_after_nogust.parquet |
Flash only (no gust), fly was downstream | No | Yes (duration > 0) |
All nine files share the same column structure. Columns include everything in the raw HDF files (except the columns P00–P55 are retained), plus the following derived columns:
| Column | Description |
|---|---|
ground speed |
Three-dimensional ground speed (m/s): sqrt(xvel² + yvel² + zvel²). |
course |
Instantaneous course direction (radians), arctan2(yvel, xvel). Unlike heading (orientation of the fly body), this is the direction of travel. |
course_smoothish |
Lightly smoothed course direction (radians), produced by Butterworth differentiation via pynumdiff. |
ang_vel_smoothish |
Angular velocity of the course direction (rad/s), from the same Butterworth differentiation. |
abs_ang_vel_smoothish |
Absolute value of ang_vel_smoothish (rad/s). |
Spatially processed fly trajectory data — with CFD wind vectors
These nine files are provided as a single archive:
- fly_trajectory_data_spatially_processed_with_cfd.zip
- df_before_gust_with_cfd.parquet
- df_during_gust_with_cfd.parquet
- df_after_gust_with_cfd.parquet
- before_gust_sham_with_cfd.parquet
- during_gust_sham_with_cfd.parquet
- after_gust_sham_with_cfd.parquet
- flash_before_nogust_with_cfd.parquet
- flash_during_nogust_with_cfd.parquet
- flash_after_nogust_with_cfd.parquet
These files contain the same nine positional/condition groups as above, but each fly's position has been matched to the local CFD-simulated wind vector at each time step. The CFD matching is performed five times using five different random time-offset windows into the 16-second CFD simulation, producing five independent wind-field replicates (suffixed 1–5). This accounts for the temporal variability of the unsteady simulated gust. Produced by running Code/MergeWindandFlyData.py (see GitHub repo).
These files contain a subset of the fly-kinematics columns (the full covariance matrix and braid-internal columns are dropped), plus the following CFD-derived columns for each replicate i ∈ {1, 2, 3, 4, 5}:
| Column | Description |
|---|---|
xvel_wind{i} |
CFD wind velocity at the fly's position in the x direction (m/s, replicate i). Positive = upwind direction. |
yvel_wind{i} |
CFD wind velocity in the y direction (m/s, replicate i). |
zvel_wind{i} |
CFD wind velocity in the z direction (m/s, replicate i). |
x_wind{i} |
x coordinate of the nearest CFD grid point matched to the fly (meters, replicate i). |
y_wind{i} |
y coordinate of the nearest CFD grid point matched to the fly (meters, replicate i). |
z_wind{i} |
z coordinate of the nearest CFD grid point matched to the fly (meters, replicate i). |
Wind tunnel characterization data (CSV)
windspeeds_cfd.csv
CFD-simulated wind velocity field used for wind tunnel characterization. Each row is one spatial measurement point at one time step from the OpenFOAM simulation.
| Column | Description |
|---|---|
TimeStep |
Integer index of the simulation time step. |
Time |
Simulation time (seconds). Range: 0.01–16.14 s, step = 0.01 s. |
Points:0 |
x position of the measurement point (meters, CFD coordinate frame; x=0 at flow inlet, increases downstream). |
Points:1 |
y position of the measurement point (meters, CFD coordinate frame). |
Points:2 |
z position of the measurement point (meters, CFD coordinate frame). |
U:0 |
x-component of wind velocity (m/s). |
U:1 |
y-component of wind velocity (m/s). |
U:2 |
z-component of wind velocity (m/s). |
Note: the CFD coordinate frame differs from the fly-tracking frame used in all trajectory files. In the trajectory data, x=0 and y=0 are at the center of the tunnel and positive x is upwind. The coordinate transformation is applied in Code/MergeWindandFlyData.py (see GitHub repo).
windtunnel_winddata.csv
Physical wind speed measurements collected with a Trisonica mini anemometer at 18 positions throughout the wind tunnel (6 downstream stations × 3 heights). Used for wind tunnel flow characterization (Fig. 1 of the paper).
| Column | Description |
|---|---|
master_time |
Time elapsed since the start of the recording session (seconds). Recorded at 10 Hz. |
mean_x |
x position of the anemometer in the wind tunnel (meters, fly-tracking coordinate frame). |
mean_y |
y position of the anemometer (meters). |
mean_z |
z (altitude) of the anemometer (meters). |
_trisonica_northsouth_y |
North–south wind component measured by the Trisonica (m/s). |
_trisonica_westeast_y |
West–east wind component measured by the Trisonica (m/s). |
_trisonica_updown_y |
Up–down (vertical) wind component measured by the Trisonica (m/s). |
_trisonica_speed2d_y |
Horizontal wind speed magnitude (m/s). |
_trisonica_direction_y |
Wind direction (degrees). |
level_0, index, new_index |
Internal index columns from data merging; not used in analysis. |
Wind tunnel visualization videos (CFD)
gust_streamlines1.avi — video visualization of CFD streamlines showing the wind gust flow field (view 1).
gust_streamlines2.avi — same CFD streamlines from a second camera angle (view 2).
CFD configuration files
CFDcasefiles.zip — OpenFOAM configuration files used to generate the CFD wind gust simulations. Includes the mesh definition, boundary conditions, solver settings, and turbulence model parameters. Example csv files are included with the 3D velocity output for 0.01 ≤ t ≤ 0.1 s. The full 3D velocity output of the simulation (~200 GB) is not included here but can be generated by running the case files, or can be made available from the authors upon reasonable request.
Recommended run order in using the complimentary GitHub Repository
If starting from the preprocessed HDF files and reproducing all figures:
- (Optional)
python Code/MergeWindandFlyData.py
Requires OpenFOAM velocity CSVs (setWIND_DIRin the script). Skip if using the pre-computedmerged_gust_df_with_cfd_wind.hdfand*_with_cfd.parquetfiles. python Code/data_processing.py
Produces the nine*.parquetfly-kinematics files from the raw HDF files.- Open and run any figure notebook in
FigureGeneration/Main/orFigureGeneration/Supplemental/.
