Recurrent synapses between CO2-sensitive olfactory sensory neurons enable robust CO2 detection in Aedes aegypti mosquitoes.
The 4 matches
- [1] § Methods › Analysis of D. melanogaster neurons in Flywire ↔ retrieve data/retrieve_neuron_data.ipynb, lines 325–414 · score 0.59 · root_id, DM1, hemibrain, VC3, VC5, VM6
- [2] § Methods › Network model ↔ model/ReciprocalOSN-model.ipynb, lines 152–169 · score 0.56 · odor responses, background odors, root, model, OSN
- [3] § Methods › Quantification and statistical analysis ↔ fig_s7_s8/cld_lettering.py, lines 20–103 · score 0.53 · pairwise comparisons, Piepho, algorithm, median, S8, S7
- [4] § Methods › Gene expression of Acetylcholine and GABA in olfactory sensory neurons ↔ fig_s6/fig_s6b_gaba_gene_expression.ipynb, lines 115–119 · score 0.52 · gene expression, GABA, raw, antennae, Cell, neurons
Paper
Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
Jupyter notebook · 725 lines · 33 KB · GPL-3.0 · 1 match
- # %%
- import pandas as pd
- import matplotlib.pyplot as plt
- from fafbseg import flywire
- import pymaid
- import navis as nv
- import numpy as np
- import seaborn as sns
- import scipy.stats as stats
- import statsmodels
- import scikit_posthocs as sp
- import sys
- import scipy
- import random
- import string
- from sklearn import metrics
- from sklearn.cluster import KMeans
- from sklearn.preprocessing import StandardScaler
- from sklearn.cluster import DBSCAN
- import matplotlib.colors as colors
- flywire.get_materialization_versions(dataset="production")
- # %%
- #check available flywire versions
- flywire.get_materialization_versions(dataset="production")
- #connect your catmaid instance
- catmaid_token = ""
- instance=pymaid.CatmaidInstance('https://radagast.hms.harvard.edu/catmaidaedes', catmaid_token)
- # %%
- def get_cable_overlap(OSNs, PN = None, volume = None):
- neurons = flywire.skeletonize_neuron(OSNs)
- if volume:
- neurons = nv.in_volume(neurons, volume)
- if PN == None:
- cable_overlap = nv.cable_overlap(neurons, neurons, dist= "2 microns")
- return cable_overlap
- else:
- PN = flywire.skeletonize_neuron(PN)
- PN_cable_overlap = nv.cable_overlap(neurons, PN, dist= "2 microns")
- return PN_cable_overlap
- def get_cable_length(OSNs,volume = None):
- neurons = flywire.skeletonize_neuron(OSNs)
- if volume:
- neurons = nv.in_volume(neurons, volume)
- return neurons.cable_length
- def get_total_synapses(OSNs, volume = None):
- neurons = flywire.skeletonize_neuron(OSNs)
- if volume:
- neurons = nv.in_volume(neurons, volume)
- return flywire.get_synapses(neurons, pre=True, post=False, attach=True, dataset='production', min_score=65,progress=False)
- def get_num_connectors(neuron1, neuron2, volume = None):
- if volume:
- neuron1 = nv.in_volume(neuron1, volume)
- neuron2 = nv.in_volume(neuron2, volume)
- df = flywire.synapses.get_adjacency(neuron1, targets=neuron2, dataset='production', min_score=65, progress=True)
- return df.values[0][0]
- def synapses_per_micron(cable_overlap_df, PN = None):
- cable_overlap_synapse_density = []
- for rowIndex, row in cable_overlap_df.iterrows(): #iterate over rows
- synapse_count = []
- cable_overlap_length = []
- for columnIndex, value in row.items():
- if value != 0:
- synapse_count.append(get_num_connectors(rowIndex, columnIndex))
- cable_overlap_length.append(value)
- cable_overlap_synapse_density.append(np.nanmean(np.array(synapse_count) / np.array(cable_overlap_length)) * 1000)
- return pd.DataFrame(cable_overlap_synapse_density,columns=['overlap_density'], index=cable_overlap_df.index)
- def get_neurons_without_overlap(cable_overlap_df):
- cable_overlap_df = cable_overlap_df.sum(axis=1)
- no_PN_overlap_neurons = [cable_overlap_df.index[index] for index, neuron in enumerate(cable_overlap_df) if neuron == 0.0]
- return no_PN_overlap_neurons
- # %% [markdown]
- # ## Projection Neuron IDs for glomeruli
- # |Glomerulus|Right Hemisphere|Left Hemisphere|
- # |:---------|:------------:|-----------:|
- # |DA4l |720575940608970197 |720575940649045369|
- # |DC1| 720575940637056887| 720575940621529435|
- # |DL4 |720575940627708688 | 720575940617343316|
- # |DL5 |720575940617207185 | 720575940639080765|
- # |DM3| 720575940614727903 | 720575940630549370|
- # |DM4 |720575940623528925 | 720575940615366055|
- # |DP1m |720575940618308825 | 720575940622726271|
- # |VA2| 720575940611079236 | 720575940609460491|
- # |VA4| 720575940617668747 | 720575940642086389|
- # |VA6 |720575940636873791 | 720575940637594334|
- # |VA7l | 720575940625784153 | 720575940618277184|
- # |VC1 |720575940637526190 | 720575940633190847|
- # |VC2 |720575940628739560 | 720575940630097103|
- # |VL2a |720575940618295454 | 720575940603464672|
- # |VL2p |720575940628467611 | 720575940618865112|
- # |VM4 |720575940640971995|
- # |DA4m |720575940631930828|
- # |VM6 |720575940624057853|
- #
- # ## Glomeruli with more than one uPN projection neurons
- # |Glomerulus|Right Hemisphere|
- # |:---------|------------:|
- # |D |720575940603985952 720575940633804212 720575940627844734|
- # |DA1 |720575940614309535 720575940637208718 720575940613345442 720575940626034819 720575940619385765 720575940605102694 720575940603231916 720575940621185050|
- # |DA2 |720575940622364184 720575940611849187 720575940626937617 720575940622734835|
- # |DC2 |720575940627160322 720575940616824588|
- # |DC3| 720575940630131663 720575940613419695 720575940634939327 720575940634715743|
- # |DL1 |720575940616079035 720575940622368792 720575940613809554|
- # |DL2d |720575940628316047 720575940630928715 720575940620103590 720575940642046453|
- # |DL3 |720575940630778428 720575940621926669 720575940627353426 720575940630778428 720575940620638335|
- # |DM2 |720575940638633535 720575940630024566|
- # |DM5 |720575940644258327 720575940629926159 720575940640032896|
- # |DM6 |720575940631328104 720575940622785062 720575940620437339|
- # |DP1l |720575940648650884 720575940606762686|
- # |VA1d |720575940622811430 720575940640804853 720575940619620852|
- # |VA1v |720575940629097922 720575940620199962 720575940628283560 720575940629733626 720575940632720026 720575940634229615|
- # |VA3 |720575940656090017 720575940629009513 720575940604431584|
- # |VA5 |720575940619838912 720575940637009636 720575940637231593|
- # |VA7m |720575940620068518 720575940640398477 720575940639680957|
- # |VC3m |720575940608845525 720575940608199748 720575940624515571|
- # |VL1 |720575940624863015 720575940637712243 720575940620595053|
- # |VM1 |720575940628077568 720575940623444715|
- # |VM2 |720575940640697808 720575940617179451|
- # |VM3 |720575940627480586 720575940610048981|
- # |VM7d |720575940628524292 720575940613167007|
- # |VM7v |720575940619337536 720575940621256212|
- # |VM5d |720575940611372714 720575940644961588 720575940635082871 720575940627035388|
- # %%
- DA4l_pn = 720575940608970197
- DC1_pn = 720575940637056887
- DL4_pn = 720575940627708688
- DL5_pn = [720575940617207185, 720575940630432815]
- DM3_pn = 720575940614727903
- DM4_pn = [720575940623528925 , 720575940628323919, 720575940606767806]
- DP1m_pn = 720575940618308825
- VA2_pn = 720575940611079236
- VA4_pn = 720575940617668747
- VA6_pn = 720575940636873791
- VA7l_pn = 720575940625784153
- VC1_pn = 720575940637526190
- VC2_pn = 720575940628739560
- VL2a_pn = 720575940618295454
- VL2p_pn = 720575940628467611
- VM4_pn = 720575940640971995
- DM1_pn = 720575940630770042
- V_bilateral_rightsoma_pn=720575940626143806
- V_bilateral_leftsoma_pn=720575940630546540
- V_unilateral_pn=720575940637910106
- V_pn = [720575940626143806,720575940630546540,720575940637910106]
- D_pn = [720575940603985952, 720575940633804212, 720575940627844734]
- DA1_pn = [720575940614309535, 720575940637208718, 720575940613345442, 720575940626034819, 720575940619385765, 720575940605102694, 720575940603231916, 720575940621185050,720575940646122804]
- DA2_pn = [720575940622364184, 720575940611849187, 720575940626937617, 720575940638719104,720575940622734835]
- DA4m_pn = 720575940631930828
- DC2_pn = [720575940627160322, 720575940616824588]
- DC3_pn = [720575940630131663, 720575940613419695, 720575940634939327]
- DL1_pn = [720575940616079035, 720575940622368792]
- DL2d_pn = [720575940628316047, 720575940630928715, 720575940620103590, 720575940642046453,720575940605421442, 720575940613706866, 720575940623922869]
- DL3_pn = [720575940630778428, 720575940621926669, 720575940627353426, 720575940630778428, 720575940620638335]
- DM2_pn = [720575940638633535, 720575940630024566]
- DM5_pn = [720575940644258327, 720575940629926159, 720575940640032896]
- DM6_pn = [720575940631328104, 720575940622785062, 720575940620437339]
- DP1l_pn = [720575940648650884, 720575940606762686]
- VA1d_pn = [720575940622811430, 720575940640804853, 720575940619620852]
- VA1v_pn = [720575940629097922, 720575940620199962, 720575940628283560, 720575940629733626, 720575940632720026, 720575940634229615]
- VA3_pn = [720575940656090017, 720575940604431584]
- VA5_pn = [720575940619838912, 720575940637009636, 720575940637231593]
- VA7m_pn = [720575940620068518, 720575940640398477, 720575940639680957]
- VC5_pn = [720575940608845525, 720575940608199748, 720575940624515571] #VC3m PNs due to naming changing VC3m -> VC5
- VL1_pn = [720575940624863015, 720575940620595053]
- VM1_pn = [720575940628077568, 720575940623444715]
- VM2_pn = [720575940640697808, 720575940617179451]
- VM3_pn = [720575940627480586, 720575940610048981]
- VM6_pn = 720575940624057853
- VM7d_pn = [720575940628524292, 720575940613167007]
- VM7v_pn = [720575940619337536, 720575940621256212]
- VM5d_pn = [720575940611372714, 720575940644961588, 720575940635082871, 720575940627035388]
- # added from 2020 Current Biology
- DA3_pn = [720575940625924618, 720575940659400577]
- DC4_pn = 720575940613579943
- DL2v_pn = [720575940620467438,720575940611022515,720575940628181520 ,720575940627772009]
- VC3_pn = [720575940615394719,720575940619902598 ,720575940619928429 ,720575940620465904]
- VC4_pn = [720575940624001321,720575940635933119,720575940609454603]
- VM5v_pn = [720575940610505170 ,720575940620189790 ,720575940625431866 ]
- # %%
- #load .ply files
- dm1_l=nv.read_mesh("../glom_meshes/DM1_R.ply", output='volume') # DM1
- v_l=nv.read_mesh("../glom_meshes/V_R.ply", output='volume') # V
- gloms = ["DA4l", "DC1", "DL4", "DL5", "DM3","DM4", "DP1m",
- "VA2", "VA4", "VA6", "VA7l", "VC1", "VC2", "VL2a",
- "VL2p", "VM4","DM1","V",
- "D",
- "DA1",
- "DA2",
- "DA4m",
- "DC2",
- "DC3",
- "DL1",
- "DL2d",
- "DL3",
- "DM2",
- "DM5",
- "DM6",
- "DP1l",
- "VA1d",
- "VA1v",
- "VA3",
- "VA5",
- "VA7m",
- "VL1",
- "VM1",
- "VM2",
- "VM3",
- "VM7d",
- "VM7v",
- "VM5d",
- "DA3",
- "DC4",
- "DL2v",
- "VC3",
- 'VC5',
- 'VM6',
- "VC4",
- "VM5v",
- ]
- for glom in gloms:
- print(glom)
- exec(glom +"_mesh = nv.read_mesh(" + "'../glom_meshes/" + glom + "_R.ply' , output='volume')")
- # %%
- #retrieve neuron_ids
- glomeruli_list = ["ORN_DA4l",
- "ORN_DC1",
- "ORN_DL4",
- "ORN_DL5",
- "ORN_DM3",
- "ORN_DM4",
- "ORN_DP1m",
- "ORN_VA2",
- "ORN_VA4",
- "ORN_VA6",
- "ORN_VA7l",
- "ORN_VC1",
- "ORN_VC2",
- "ORN_VL2a",
- "ORN_VL2p",
- "ORN_VM4",
- "ORN_DM1",
- "ORN_V",
- "ORN_D",
- "ORN_DA1",
- "ORN_DA2",
- "ORN_DA4m",
- "ORN_DC2",
- "ORN_DC3",
- "ORN_DL1",
- "ORN_DL2d",
- "ORN_DL3",
- "ORN_DM2",
- "ORN_DM5",
- "ORN_DM6",
- "ORN_DP1l",
- "ORN_VA1d",
- "ORN_VA1v",
- "ORN_VA3",
- "ORN_VA5",
- "ORN_VA7m",
- "ORN_VC3",
- 'ORN_VC5',
- 'ORN_VM6',
- "ORN_VL1",
- "ORN_VM1",
- "ORN_VM2",
- "ORN_VM3",
- "ORN_VM7d",
- "ORN_VM7v",
- "ORN_VM5d",
- "ORN_DA3",
- "ORN_DC4",
- "ORN_DL2v",
- "ORN_VC3l",
- "ORN_VC4",
- "ORN_VM5v",
- ]
- glomeruli_OSNs = pd.DataFrame()
- for glomeruli in glomeruli_list:
- if glomeruli in ['ORN_VC3','ORN_VC5','ORN_VM6']:
- annotation_search = flywire.search_annotations(flywire.NeuronCriteria(cell_type=glomeruli, side='left', annotation_version="v2.0.0"))
- else:
- print(glomeruli)
- annotation_search = flywire.search_annotations(flywire.NeuronCriteria(hemibrain_type=glomeruli, side='left', annotation_version="v2.0.0"))
- print(f' for {glomeruli} {annotation_search.shape[0]} neurons were found')
- glomeruli_OSNs = pd.concat([glomeruli_OSNs, annotation_search])
- glomeruli_OSNs = glomeruli_OSNs[['root_id','hemibrain_type','cell_type']] #keep just the root_id and the glomeruli
- # %%
- #the following neurons have no synapses with projection neurons in their glomerulus, so they were excluded from all analysis
- neurons_to_exclude = [720575940642936520, 720575940623359466, 720575940633033133, 720575940621862605,
- 720575940605724081, 720575940604876977, 720575940630971434, 720575940632824531,
- 720575940611791834, 720575940614890642, 720575940611437973, 720575940619969329,
- 720575940614019112, 720575940615639199, 720575940639118653, 720575940615629173,
- 720575940621082138, 720575940608615363, 720575940630679749, 720575940628398791,
- 720575940639089571, 720575940634883179, 720575940638202852, 720575940614006934,
- 720575940603870688, 720575940632033875, 720575940632391736, 720575940623750852,
- 720575940622248709, 720575940631930415, 720575940613885506, 720575940627787343,
- 720575940624671490, 720575940631393823, 720575940619029589, 720575940623655605,
- 720575940630462572,
- ]
- # %%
- glomeruli_OSNs = glomeruli_OSNs[~glomeruli_OSNs['root_id'].isin(neurons_to_exclude)]
- # %%
- glom_list = ["D",
- "DA1",
- "DA2",
- "DA3",
- "DA4l",
- "DA4m",
- "DC1",
- "DC2",
- "DC3",
- "DC4",
- "DL1",
- "DL2d",
- "DL2v",
- "DL3",
- "DL4",
- "DL5",
- "DM1",
- "DM2",
- "DM3",
- "DM4",
- "DM5",
- "DM6",
- "DP1l",
- "DP1m",
- "V",
- "VA1d",
- "VA1v",
- "VA2",
- "VA3",
- "VA4",
- "VA5",
- "VA6",
- "VA7l",
- "VA7m",
- "VC1",
- "VC2",
- "VC3",
- "VC4",
- "VC5",
- "VL1",
- "VL2a",
- "VL2p",
- "VM1",
- "VM2",
- "VM3",
- "VM4",
- "VM5d"
- "VM5v",
- "VM6",
- "VM7d",
- "VM7v"]
- for glom in glom_list:
- retries = 5
- for retry in range(retries):
- try:
- print(glom)
- if glom in ['VM6']:
- exec(f"{glom}_feedforward_synapses = flywire.get_adjacency(glomeruli_OSNs[(glomeruli_OSNs['cell_type']=='ORN_{glom}v') | (glomeruli_OSNs['cell_type']=='ORN_{glom}l') | (glomeruli_OSNs['cell_type']=='ORN_{glom}m')]['root_id'], {glom}_pn, min_score=65, dataset='production')")#.sum(axis=1)")
- exec(f"{glom}_recurrent_synapses = flywire.get_adjacency(glomeruli_OSNs[(glomeruli_OSNs['cell_type']=='ORN_{glom}v') | (glomeruli_OSNs['cell_type']=='ORN_{glom}l') | (glomeruli_OSNs['cell_type']=='ORN_{glom}m')]['root_id'], min_score=65, dataset='production')")#.sum(axis=1)")
- exec(f"{glom}_total_synapses = get_total_synapses(glomeruli_OSNs[(glomeruli_OSNs['cell_type']=='ORN_{glom}v') | (glomeruli_OSNs['cell_type']=='ORN_{glom}l') | (glomeruli_OSNs['cell_type']=='ORN_{glom}m')]['root_id'], volume = {glom}_mesh)")
- exec(f"{glom}_feedforward = get_cable_overlap(glomeruli_OSNs[(glomeruli_OSNs['cell_type']=='ORN_{glom}v') | (glomeruli_OSNs['cell_type']=='ORN_{glom}l') | (glomeruli_OSNs['cell_type']=='ORN_{glom}m')]['root_id'],PN={glom}_pn, volume={glom}_mesh)")
- exec(f"{glom}_recurrent = get_cable_overlap(glomeruli_OSNs[(glomeruli_OSNs['cell_type']=='ORN_{glom}v') | (glomeruli_OSNs['cell_type']=='ORN_{glom}l') | (glomeruli_OSNs['cell_type']=='ORN_{glom}m')]['root_id'],volume={glom}_mesh)")
- exec(f"{glom}_cable_length = get_cable_length(glomeruli_OSNs[(glomeruli_OSNs['cell_type']=='ORN_{glom}v') | (glomeruli_OSNs['cell_type']=='ORN_{glom}l') | (glomeruli_OSNs['cell_type']=='ORN_{glom}m')]['root_id'], volume={glom}_mesh)")
- elif glom in ['VC3','VC5']:
- exec(f"{glom}_feedforward_synapses = flywire.get_adjacency(glomeruli_OSNs[glomeruli_OSNs['cell_type']=='ORN_{glom}']['root_id'], {glom}_pn, min_score=65, dataset='production')")#.sum(axis=1)")
- exec(f"{glom}_recurrent_synapses = flywire.get_adjacency(glomeruli_OSNs[glomeruli_OSNs['cell_type']=='ORN_{glom}']['root_id'], min_score=65, dataset='production')")#.sum(axis=1)")
- exec(f"{glom}_total_synapses = get_total_synapses(glomeruli_OSNs[glomeruli_OSNs['cell_type']=='ORN_{glom}']['root_id'], volume = {glom}_mesh)")
- exec(f"{glom}_feedforward = get_cable_overlap(glomeruli_OSNs[glomeruli_OSNs['cell_type']=='ORN_{glom}']['root_id'],PN={glom}_pn, volume={glom}_mesh)")
- exec(f"{glom}_recurrent = get_cable_overlap(glomeruli_OSNs[glomeruli_OSNs['cell_type']=='ORN_{glom}']['root_id'],volume={glom}_mesh)")
- exec(f"{glom}_cable_length = get_cable_length(glomeruli_OSNs[glomeruli_OSNs['cell_type']=='ORN_{glom}']['root_id'], volume={glom}_mesh)")
- else:
- exec(f"{glom}_feedforward_synapses = flywire.get_adjacency(glomeruli_OSNs[glomeruli_OSNs['hemibrain_type']=='ORN_{glom}']['root_id'], {glom}_pn, min_score=65, dataset='production')")#.sum(axis=1)")
- exec(f"{glom}_recurrent_synapses = flywire.get_adjacency(glomeruli_OSNs[glomeruli_OSNs['hemibrain_type']=='ORN_{glom}']['root_id'], min_score=65, dataset='production')")#.sum(axis=1)")
- exec(f"{glom}_total_synapses = get_total_synapses(glomeruli_OSNs[glomeruli_OSNs['hemibrain_type']=='ORN_{glom}']['root_id'], volume = {glom}_mesh)")
- exec(f"{glom}_feedforward = get_cable_overlap(glomeruli_OSNs[glomeruli_OSNs['hemibrain_type']=='ORN_{glom}']['root_id'],PN={glom}_pn, volume={glom}_mesh)")
- exec(f"{glom}_recurrent = get_cable_overlap(glomeruli_OSNs[glomeruli_OSNs['hemibrain_type']=='ORN_{glom}']['root_id'],volume={glom}_mesh)")
- exec(f"{glom}_cable_length = get_cable_length(glomeruli_OSNs[glomeruli_OSNs['hemibrain_type']=='ORN_{glom}']['root_id'], volume={glom}_mesh)")
- exec(f"{glom}_feedforward_synapses_per_micron = synapses_per_micron({glom}_feedforward,PN={glom}_pn)")
- exec(f"{glom}_recurrent_synapses_per_micron = synapses_per_micron({glom}_recurrent)")
- except:
- if retry < retries - 1:
- print(f'number of retries left = {retries-retry}')
- continue
- else:
- raise
- break
- # %% [markdown]
- # retrieve mosquito data from catmaid
- # %%
- #MD1
- MD1OSNs = pymaid.get_skids_by_annotation(['innervates MD1', 'left palp nerve', 'sensory neuron', 'PSPs done'], allow_partial = False, intersect = True)
- MD1OSNsALL = pymaid.get_skids_by_annotation(['innervates MD1', 'left palp nerve', 'sensory neuron'], allow_partial = False, intersect = True)
- MD1volume = pymaid.get_volume('MD1 04/06/21')
- MD1neurons = pymaid.get_neuron(MD1OSNs)
- MD1neurons = pymaid.CatmaidNeuron.prune_by_volume(MD1neurons,v=MD1volume,mode='IN',prevent_fragments=True)
- MD1neuronsALL = pymaid.get_neuron(MD1OSNsALL)
- # %%
- #MD2
- MD2OSNs = pymaid.get_skids_by_annotation(['innervates MD2', 'left palp nerve', 'sensory neuron', 'PSPs done'], allow_partial = False, intersect = True)
- MD2OSNsALL = pymaid.get_skids_by_annotation(['innervates MD2', 'left palp nerve', 'sensory neuron'], allow_partial = False, intersect = True)
- MD2volume = pymaid.get_volume('MD2 2022')
- MD2neurons = pymaid.get_neuron(MD2OSNs)
- MD2neurons = pymaid.CatmaidNeuron.prune_by_volume(MD2neurons,v=MD2volume,mode='IN',prevent_fragments=True)
- MD2neuronsALL = pymaid.get_neuron(MD2OSNsALL)
- # %%
- #MD3
- MD3OSNs = pymaid.get_skids_by_annotation(['innervates MD3', 'left palp nerve', 'sensory neuron', 'PSPs done'], allow_partial = False, intersect = True)
- MD3OSNsALL = pymaid.get_skids_by_annotation(['innervates MD3', 'left palp nerve', 'sensory neuron'], allow_partial = False, intersect = True)
- MD3volume = pymaid.get_volume('MD3 2022')
- MD3neurons = pymaid.get_neuron(MD3OSNs)
- MD3neurons = pymaid.CatmaidNeuron.prune_by_volume(MD3neurons,v=MD3volume,mode='IN',prevent_fragments=True)
- MD3neuronsALL = pymaid.get_neuron(MD3OSNsALL)
- # %%
- #initialize empty dataframe
- flyneurons=pd.DataFrame(columns=['id', 'total cable length', 'cable length in glom', 'unilateral feedforward', 'bilateral left feedforward', 'bilateral right feedforward', 'recurrent connections', 'glomerulus'])
- md1_synapse_count = []
- md1_synapse_count_in_volume = []
- md1_total_synapses = []
- md1_total_synapses_restricted = []
- md1_synapse_count_feedforward = []
- md1_synapse_count_feedforward_unrestricted = []
- md1_cable_overlap = []
- md1_feedforward_density = []
- md1_feedforward_density_unrestricted = []
- md1_recurrent_density = []
- md1_recurrent_density_unrestricted = []
- md1_cable_length = []
- md1_cable_overlap_percentage = []
- md1_feedforward_fraction = []
- md1_recurrent_fraction = []
- md1_recurrent_fraction_restricted = []
- md1_recurrent_synapses = []
- md1_recurrent_synapses_restricted = []
- for n in MD1neurons:
- skeletonid=n.skeleton_id
- skelid=int(skeletonid)
- print(skelid)
- labels = pymaid.get_label_list()
- neuronlabels=labels[labels.skeleton_id==skelid]
- branchpoint=neuronlabels[neuronlabels.tag=='first branch point']
- if len(branchpoint) !=1:
- print('error, neuron skelid=%i does not have exactly 1 branchpoint tag'% skelid)
- else: bpnode=branchpoint.node_id.values[0]
- PN = pymaid.get_neuron('295')
- cable_overlap_length = nv.cable_overlap(n, PN, dist= "2 microns")
- connections = pymaid.get_partners(n).set_index('skeleton_id')
- connections = connections[connections['relation'] == 'downstream']
- total_synapses = pd.DataFrame(connections['total']).transpose()
- total_synapses.columns.names = ['targets']
- total_synapses.index = [n.id]
- total_synapses.index.names = ['sources']
- total_synapses_restricted = pymaid.filter_connectivity(total_synapses, restrict_to='MD1 04/06/21')
- #feedforward connections
- feedforward = pymaid.adjacency_matrix(n, targets=295)
- glom_connectivity=pymaid.filter_connectivity(feedforward, restrict_to='MD1 04/06/21')
- feedforward_value=int(glom_connectivity.iloc[0])
- #recurrent connections
- recurrent = pymaid.adjacency_matrix(n, targets=MD1neuronsALL)
- recurrent_glom_connectivity=pymaid.filter_connectivity(recurrent, restrict_to='MD1 04/06/21')
- print(recurrent_glom_connectivity)
- cable_overlap = nv.cable_overlap(n,MD1neuronsALL,dist= "2 microns")
- synapse_density_unrestricted = recurrent / (cable_overlap.values / 1000)
- synapse_density = recurrent_glom_connectivity / (cable_overlap.values / 1000)
- md1_total_synapses.append(sum(total_synapses.iloc[0]))
- md1_total_synapses_restricted.append(sum(total_synapses_restricted.iloc[0]))
- md1_synapse_count.append(recurrent.values)
- md1_synapse_count_feedforward.append(feedforward_value)
- md1_synapse_count_feedforward_unrestricted.append(int(feedforward.iloc[0]))
- md1_cable_overlap.append(cable_overlap.values)
- md1_feedforward_density.append((glom_connectivity/(cable_overlap_length/1000)).iloc[0].values[0])
- md1_feedforward_density_unrestricted.append((int(feedforward.iloc[0])/(cable_overlap_length/1000)).iloc[0].values[0])
- md1_recurrent_density.append(synapse_density.mean(axis=1).iloc[0])
- md1_recurrent_density_unrestricted.append(synapse_density_unrestricted.mean(axis=1).iloc[0])
- md1_cable_length.append(n.cable_length/1000)
- md1_cable_overlap_percentage.append(((cable_overlap.values /1000)/(n.cable_length/1000)).mean())
- sum_recurrent=recurrent.iloc[0].sum()
- md1_feedforward_fraction.append(feedforward_value / total_synapses_restricted.sum(axis=1)[0])
- md1_recurrent_synapses.append(recurrent.iloc[0].sum())
- md1_recurrent_synapses_restricted.append(recurrent_glom_connectivity.sum(axis=1)[0])
- md1_recurrent_fraction.append(sum_recurrent / total_synapses)
- md1_recurrent_fraction_restricted.append(recurrent_glom_connectivity.sum(axis=1)[0]/sum(total_synapses_restricted.iloc[0]))
- #append to dataframe
- flyneurons= pd.concat([flyneurons,
- pd.DataFrame({'id':n,
- 'total cable length':n.cable_length,
- 'cable length in glom': cable_overlap_length.values[0][0], #dlength,
- 'unilateral feedforward':feedforward_value,
- 'recurrent connections': sum_recurrent,
- 'glomerulus':'Glomerulus 1'}, index = [0])
- ],
- ignore_index=True)
- # %%
- #initialize empty dataframe
- flyneurons=pd.DataFrame(columns=['id', 'total cable length', 'cable length in glom', 'unilateral feedforward', 'bilateral left feedforward', 'bilateral right feedforward', 'recurrent connections', 'glomerulus'])
- md2_synapse_count = []
- md2_synapse_count_in_volume = []
- md2_total_synapses = []
- md2_total_synapses_restricted = []
- md2_synapse_count_feedforward = []
- md2_synapse_count_feedforward_unrestricted = []
- md2_cable_overlap = []
- md2_feedforward_density = []
- md2_feedforward_density_unrestricted = []
- md2_recurrent_density = []
- md2_recurrent_density_unrestricted = []
- md2_cable_length = []
- md2_cable_overlap_percentage = []
- md2_feedforward_fraction = []
- md2_recurrent_fraction = []
- md2_recurrent_fraction_restricted = []
- md2_recurrent_synapses = []
- md2_recurrent_synapses_restricted = []
- for n in MD2neurons:
- skeletonid=n.skeleton_id
- skelid=int(skeletonid)
- print(skelid)
- labels = pymaid.get_label_list()
- neuronlabels=labels[labels.skeleton_id==skelid]
- branchpoint=neuronlabels[neuronlabels.tag=='first branch point']
- if len(branchpoint) !=1:
- print('error, neuron skelid=%i does not have exactly 1 branchpoint tag'% skelid)
- else: bpnode=branchpoint.node_id.values[0]
- PN = pymaid.get_neuron('690')
- cable_overlap_length = nv.cable_overlap(n, PN, dist= "2 microns")
- connections = pymaid.get_partners(n).set_index('skeleton_id')
- connections = connections[connections['relation'] == 'downstream']
- total_synapses = pd.DataFrame(connections['total']).transpose()
- total_synapses.columns.names = ['targets']
- total_synapses.index = [n.id]
- total_synapses.index.names = ['sources']
- total_synapses_restricted = pymaid.filter_connectivity(total_synapses, restrict_to='MD2 2022')
- #feedforward connections
- feedforward = pymaid.adjacency_matrix(n, targets=690)
- glom_connectivity=pymaid.filter_connectivity(feedforward, restrict_to='MD2 2022')
- feedforward_value=int(glom_connectivity.iloc[0])
- #recurrent connections
- recurrent = pymaid.adjacency_matrix(n, targets=MD2neuronsALL)
- recurrent_glom_connectivity=pymaid.filter_connectivity(recurrent, restrict_to='MD2 2022')
- print(recurrent_glom_connectivity)
- cable_overlap = nv.cable_overlap(n,MD2neuronsALL,dist= "2 microns")
- synapse_density_unrestricted = recurrent / (cable_overlap.values / 1000)
- synapse_density = recurrent_glom_connectivity / (cable_overlap.values / 1000)
- md2_total_synapses.append(sum(total_synapses.iloc[0]))
- md2_total_synapses_restricted.append(sum(total_synapses_restricted.iloc[0]))
- md2_synapse_count.append(recurrent.values)
- md2_synapse_count_feedforward.append(feedforward_value)
- md2_synapse_count_feedforward_unrestricted.append(int(feedforward.iloc[0]))
- md2_cable_overlap.append(cable_overlap.values)
- md2_feedforward_density.append((glom_connectivity/(cable_overlap_length/1000)).iloc[0].values[0])
- md2_feedforward_density_unrestricted.append((int(feedforward.iloc[0])/(cable_overlap_length/1000)).iloc[0].values[0])
- md2_recurrent_density.append(synapse_density.mean(axis=1).iloc[0])
- md2_recurrent_density_unrestricted.append(synapse_density_unrestricted.mean(axis=1).iloc[0])
- md2_cable_length.append(n.cable_length/1000)
- md2_cable_overlap_percentage.append(((cable_overlap.values /1000)/(n.cable_length/1000)).mean())
- sum_recurrent=recurrent.iloc[0].sum()
- md2_feedforward_fraction.append(feedforward_value / total_synapses_restricted.sum(axis=1)[0])
- md2_recurrent_synapses.append(recurrent.iloc[0].sum())
- md2_recurrent_synapses_restricted.append(recurrent_glom_connectivity.sum(axis=1)[0])
- md2_recurrent_fraction.append(sum_recurrent / total_synapses)
- md2_recurrent_fraction_restricted.append(recurrent_glom_connectivity.sum(axis=1)[0]/sum(total_synapses_restricted.iloc[0]))
- #append to dataframe
- flyneurons= pd.concat([flyneurons,
- pd.DataFrame({'id':n,
- 'total cable length':n.cable_length,
- 'cable length in glom': cable_overlap_length.values[0][0], #dlength,
- 'unilateral feedforward':feedforward_value,
- 'recurrent connections': sum_recurrent,
- 'glomerulus':'Glomerulus 1'}, index = [0])
- ],
- ignore_index=True)
- # %%
- #initialize empty dataframe
- flyneurons=pd.DataFrame(columns=['id', 'total cable length', 'cable length in glom', 'unilateral feedforward', 'bilateral left feedforward', 'bilateral right feedforward', 'recurrent connections', 'glomerulus'])
- md3_synapse_count = []
- md3_synapse_count_in_volume = []
- md3_total_synapses = []
- md3_total_synapses_restricted = []
- md3_synapse_count_feedforward = []
- md3_synapse_count_feedforward_unrestricted = []
- md3_cable_overlap = []
- md3_feedforward_density = []
- md3_feedforward_density_unrestricted = []
- md3_recurrent_density = []
- md3_recurrent_density_unrestricted = []
- md3_cable_length = []
- md3_cable_overlap_percentage = []
- md3_feedforward_fraction = []
- md3_recurrent_fraction = []
- md3_recurrent_fraction_restricted = []
- md3_recurrent_synapses = []
- md3_recurrent_synapses_restricted = []
- for n in MD3neurons:
- skeletonid=n.skeleton_id
- skelid=int(skeletonid)
- print(skelid)
- labels = pymaid.get_label_list()
- neuronlabels=labels[labels.skeleton_id==skelid]
- branchpoint=neuronlabels[neuronlabels.tag=='first branch point']
- if len(branchpoint) !=1:
- print('error, neuron skelid=%i does not have exactly 1 branchpoint tag'% skelid)
- else: bpnode=branchpoint.node_id.values[0]
- PN = pymaid.get_neuron('11126')
- cable_overlap_length = nv.cable_overlap(n, PN, dist= "2 microns")
- connections = pymaid.get_partners(n).set_index('skeleton_id')
- connections = connections[connections['relation'] == 'downstream']
- total_synapses = pd.DataFrame(connections['total']).transpose()
- total_synapses.columns.names = ['targets']
- total_synapses.index = [n.id]
- total_synapses.index.names = ['sources']
- total_synapses_restricted = pymaid.filter_connectivity(total_synapses, restrict_to='MD3 2022')
- #feedforward connections
- feedforward = pymaid.adjacency_matrix(n, targets=11126)
- glom_connectivity=pymaid.filter_connectivity(feedforward, restrict_to='MD3 2022')
- feedforward_value=int(glom_connectivity.iloc[0])
- #recurrent connections
- recurrent = pymaid.adjacency_matrix(n, targets=MD3neuronsALL)
- recurrent_glom_connectivity=pymaid.filter_connectivity(recurrent, restrict_to='MD3 2022')
- print(recurrent_glom_connectivity)
- cable_overlap = nv.cable_overlap(n,MD3neuronsALL,dist= "2 microns")
- synapse_density_unrestricted = recurrent / (cable_overlap.values / 1000)
- synapse_density = recurrent_glom_connectivity / (cable_overlap.values / 1000)
- md3_total_synapses.append(sum(total_synapses.iloc[0]))
- md3_total_synapses_restricted.append(sum(total_synapses_restricted.iloc[0]))
- md3_synapse_count.append(recurrent.values)
- md3_synapse_count_feedforward.append(feedforward_value)
- md3_synapse_count_feedforward_unrestricted.append(int(feedforward.iloc[0]))
- md3_cable_overlap.append(cable_overlap.values)
- md3_feedforward_density.append((glom_connectivity/(cable_overlap_length/1000)).iloc[0].values[0])
- md3_feedforward_density_unrestricted.append((int(feedforward.iloc[0])/(cable_overlap_length/1000)).iloc[0].values[0])
- md3_recurrent_density.append(synapse_density.mean(axis=1).iloc[0])
- md3_recurrent_density_unrestricted.append(synapse_density_unrestricted.mean(axis=1).iloc[0])
- md3_cable_length.append(n.cable_length/1000)
- md3_cable_overlap_percentage.append(((cable_overlap.values /1000)/(n.cable_length/1000)).mean())
- sum_recurrent=recurrent.iloc[0].sum()
- md3_feedforward_fraction.append(feedforward_value / total_synapses_restricted.sum(axis=1)[0])
- md3_recurrent_synapses.append(recurrent.iloc[0].sum())
- md3_recurrent_synapses_restricted.append(recurrent_glom_connectivity.sum(axis=1)[0])
- md3_recurrent_fraction.append(sum_recurrent / total_synapses)
- md3_recurrent_fraction_restricted.append(recurrent_glom_connectivity.sum(axis=1)[0]/sum(total_synapses_restricted.iloc[0]))
- #append to dataframe
- flyneurons= pd.concat([flyneurons,
- pd.DataFrame({'id':n,
- 'total cable length':n.cable_length,
- 'cable length in glom': cable_overlap_length.values[0][0], #dlength,
- 'unilateral feedforward':feedforward_value,
- 'recurrent connections': sum_recurrent,
- 'glomerulus':'Glomerulus 1'}, index = [0])
- ],
- ignore_index=True)
retrieve_neuron_data.ipynb at commit 81b5589, under GPL-3.0 · at the source
Overview
- Department of Neurobiology, Harvard Medical School, Boston, Massachusetts, United States of America
- Molecules, Cells, and Organisms Training Program, Department of Molecular and Cellular Biology, Harvard University, Cambridge, Massachusetts, United States of America
- Department of Biology, Boston University, Boston, Massachusetts, United States of America
- Department of Biomedical Engineering, Boston University, Boston, Massachusetts, United States of America
- Laboratory of Neural Systems, The Rockefeller University, New York, New York, United States of America
- Department of Vision Sciences, College of Optometry, University of Houston, Houston, Texas, United States of America
- F.M. Kirby Neurobiology Center, Boston Children’s Hospital, Harvard Medical School, Boston, Massachusetts, United States of America
Abstract
The mosquito Aedes aegypti’s human host-seeking behavior depends on the integration of multiple sensory cues. One of these cues, carbon dioxide (CO2), gates odorant and heat pathways and activates host-seeking behavior. The neuronal circuits underlying processing of CO2 information remain unclear. We used automated serial-section transmission electron microscopy (EM) to image and reconstruct the circuitry of the glomeruli that are innervated by the Ae. aegypti maxillary palp, including the glomerulus that responds to CO2. Notably, CO2-sensitive olfactory sensory neurons (OSNs) make high levels of recurrent synaptic connections with one another, while making a low density of feedforward synapses. At some of these contacts between CO2 OSNs, we observe ribbon-like presynaptic structures, which may further enhance recurrent signaling. We compared both feedforward and recurrent connectivity with all olfactory glomeruli in Drosophila melanogaster, and we found more recurrent connections between the Ae. aegypti CO2-responsive OSNs than in any D. melanogaster glomeruli. We developed a computational circuit model that demonstrates recurrent synapses are necessary for robust CO2 detection under normal physiological conditions. Together, elevated levels of recurrent connectivity and ribbon-like structures may amplify sensory information detected by CO2-sensitive OSNs to support mosquito activation and sensitization by CO2, even in the presence of high levels of other odorants in the environment. We propose that this circuit organization supports the salience of CO2 as a mosquito host cue.
Reproduced under the paper's license (CC BY), from the paper cited above.
Repositories
Its files are read in the Code ↔ Paper reader above, with 4 matches between paragraphs and lines of code.
htem/aedes_public
81b5589a63e067c7e35601ee7ebceb342a082d7b, 16 July 2026Availability: 1 check, the latest on 26 September 2026: the link answers
- 26 September 2026: the link answers
71 files
- axo-dendro_grams/
axogram_md1_all.ipynb , Jupyter, 88 lines - axo-dendro_grams/
axogram_md1_osn.ipynb , Jupyter, 82 lines - axo-dendro_grams/
axogram_md1uPN.ipynb , Jupyter, 63 lines - axo-dendro_grams/
axogram_md2_osn.ipynb , Jupyter, 74 lines - axo-dendro_grams/
axogram_md2uPN.ipynb , Jupyter, 54 lines - axo-dendro_grams/
axogram_md3_osn.ipynb , Jupyter, 74 lines - axo-dendro_grams/
axogram_md3uPN.ipynb , Jupyter, 50 lines - axo-dendro_grams/
axogram_ribbons.ipynb , Jupyter, 174 lines - fig_1/
.ipynb_checkpoints/ , Jupyter, 134 linesfig_1j_osn_cableLength-c heckpoint.ipynb - fig_1/
fig_1h_osn_cable_length. , Jupyter, 484 linesipynb - fig_1/
fig_1l_recSynapses.ipynb , Jupyter, 484 lines - fig_1/
fig_1m_recSynDensity.ipy , Jupyter, 484 linesnb - fig_1/
fig_1n_recSynFraction.ip , Jupyter, 484 linesynb - fig_2/
.ipynb_checkpoints/ , Jupyter, 127 linesfig_2d_ffSynapses-checkp oint.ipynb - fig_2/
.ipynb_checkpoints/ , Jupyter, 139 linesfig_2e_ffSynDensity-chec kpoint.ipynb - fig_2/
.ipynb_checkpoints/ , Jupyter, 215 linesfig_2f_3e_fractFFsyns_fr actRCsyns-checkpoint.ipy nb - fig_2/
fig_2e_ffSynapses.ipynb , Jupyter, 485 lines - fig_2/
fig_2f_ffSynDensity.ipyn , Jupyter, 485 linesb - fig_2/
fig_2g_ffSynFraction.ipy , Jupyter, 484 linesnb - fig_2/
fig_2h_totalSynapses.ipy , Jupyter, 484 linesnb - fig_3/
.ipynb_checkpoints/ , Jupyter, 1 linefig_3c_recSynapses-check point.ipynb - fig_3/
.ipynb_checkpoints/ , Jupyter, 1 linefig_3d_recSynDensity-che ckpoint.ipynb - fig_3/
.ipynb_checkpoints/ , Jupyter, 143 linesfig_3f_osnOutSyns-checkp oint.ipynb - fig_3/
fig_3b_ffSynapses.ipynb , Jupyter, 543 lines - fig_3/
fig_3c_ffSynDensity.ipyn , Jupyter, 543 linesb - fig_3/
fig_3d_ffSynFraction.ipy , Jupyter, 543 linesnb - fig_3/
fig_3e_cableLength.ipynb , Jupyter, 544 lines - fig_4/
.ipynb_checkpoints/ , Jupyter, 232 linesfig_4b_flyComp-cableLeng th-checkpoint.ipynb - fig_4/
.ipynb_checkpoints/ , Jupyter, 355 linesfig_4cd_flyComp-ffSynaps es_ffSynDensity-checkpoi nt.ipynb - fig_4/
.ipynb_checkpoints/ , Jupyter, 295 linesfig_4ef_flyComp-recSynap ses_recSynDensity-checkp oint.ipynb - fig_4/
fig_4b_recSynapses.ipynb , Jupyter, 543 lines - fig_4/
fig_4c_recSynDensity.ipy , Jupyter, 543 linesnb - fig_4/
fig_4d_recSynFraction.ip , Jupyter, 543 linesynb - fig_5/
.ipynb_checkpoints/ , Jupyter, 132 linesfig_5g_ribbons-tBars_bra nchOrder-checkpoint.ipyn b - fig_5/
.ipynb_checkpoints/ , Jupyter, 139 linesfig_5h_ribbons-tBars_dis t-1stBP-checkpoint.ipynb - fig_5/
fig_5g_ribbons-tBars_bra , Jupyter, 145 linesnchOrder.ipynb - fig_5/
fig_5h_ribbons-tBars_dis , Jupyter, 147 linest-1stBP.ipynb - fig_s3/
.ipynb_checkpoints/ , Jupyter, 179 linesfig_s3a_osn_cableLength_ 1stBP-checkpoint.ipynb - fig_s3/
.ipynb_checkpoints/ , Jupyter, 271 linesfig_s3bc_ffSynapses_ffSy nDesnsity_1stBP-checkpoi nt.ipynb - fig_s3/
.ipynb_checkpoints/ , Jupyter, 268 linesfig_s3de_recSynapses_rec SynDesnsity_1stBP-checkp oint.ipynb - fig_s3/
fig_s3_skeletons.ipynb , Jupyter, 198 lines - fig_s3/
fig_s3a_osn_cableLength_ , Jupyter, 179 lines1stBP.ipynb - fig_s3/
fig_s3bc_ffSynapses_ffSy , Jupyter, 271 linesnDesnsity_1stBP.ipynb - fig_s3/
fig_s3de_recSynapses_rec , Jupyter, 268 linesSynDesnsity_1stBP.ipynb - fig_s5/
fig_s5a_cable_length.ipy , Jupyter, 487 linesnb - fig_s5/
fig_s5bc_branch_number_b , Jupyter, 178 linesranch_order.ipynb - fig_s5/
fig_s5d_ffSynapses.ipynb , Jupyter, 487 lines - fig_s5/
fig_s5e_ffDensity.ipynb , Jupyter, 487 lines - fig_s5/
fig_s5f_recSynapses.ipyn , Jupyter, 487 linesb - fig_s5/
fig_s5g_recDensity.ipynb , Jupyter, 487 lines - fig_s6/
fig_s6b_cable_length.ipy , Jupyter, 108 linesnb - fig_s6/
fig_s6b_gaba_gene_expres , Jupyter, 189 lines, 1 matchsion.ipynb - fig_s6/
fig_s6c_ffFraction.ipynb , Jupyter, 108 lines - fig_s6/
fig_s6c_ffSynDensity.ipy , Jupyter, 109 linesnb - fig_s6/
fig_s6c_ffSynapses.ipynb , Jupyter, 108 lines - fig_s6/
fig_s6d_recFraction.ipyn , Jupyter, 108 linesb - fig_s6/
fig_s6d_recSynDensity.ip , Jupyter, 109 linesynb - fig_s6/
fig_s6d_recSynapses.ipyn , Jupyter, 108 linesb - fig_s7_s8/
cld_lettering.py , Python, 235 lines, 1 match - fig_s7_s8/
fig_s7a_ffSynapses.ipynb , Jupyter, 509 lines - fig_s7_s8/
fig_s7b_ffSynDensity.ipy , Jupyter, 509 linesnb - fig_s7_s8/
fig_s7c_ffSynFraction.ip , Jupyter, 509 linesynb - fig_s7_s8/
fig_s8a_recSynapses.ipyn , Jupyter, 509 linesb - fig_s7_s8/
fig_s8b_recSynDensity.ip , Jupyter, 509 linesynb - fig_s7_s8/
fig_s8c_recSynFraction.i , Jupyter, 509 linespynb - fig_s9/
fig_s9ab_ffSynapses_ffDe , Jupyter, 686 linesnsity.ipynb - fig_s9/
fig_s9de_ach_gene_expres , Jupyter, 227 linession.ipynb - model/
ReciprocalOSN-model.ipyn , Jupyter, 172 lines, 1 matchb - retrieve data/
retrieve_neuron_data.ipy , Jupyter, 725 lines, 1 matchnb - LICENSE, License, 674 lines
- README.md, Text, 13 lines
Zenodo 21403889
Availability: 1 check, the latest on 26 September 2026: the link answers (HTTP 200)
- 26 September 2026: the link answers (HTTP 200)
71 files
- axo-dendro_grams/
axogram_md1_all.ipynb , Jupyter, 88 lines - axo-dendro_grams/
axogram_md1_osn.ipynb , Jupyter, 82 lines - axo-dendro_grams/
axogram_md1uPN.ipynb , Jupyter, 63 lines - axo-dendro_grams/
axogram_md2_osn.ipynb , Jupyter, 74 lines - axo-dendro_grams/
axogram_md2uPN.ipynb , Jupyter, 54 lines - axo-dendro_grams/
axogram_md3_osn.ipynb , Jupyter, 74 lines - axo-dendro_grams/
axogram_md3uPN.ipynb , Jupyter, 50 lines - axo-dendro_grams/
axogram_ribbons.ipynb , Jupyter, 174 lines - fig_1/
.ipynb_checkpoints/ , Jupyter, 134 linesfig_1j_osn_cableLength-c heckpoint.ipynb - fig_1/
fig_1h_osn_cable_length. , Jupyter, 484 linesipynb - fig_1/
fig_1l_recSynapses.ipynb , Jupyter, 484 lines - fig_1/
fig_1m_recSynDensity.ipy , Jupyter, 484 linesnb - fig_1/
fig_1n_recSynFraction.ip , Jupyter, 484 linesynb - fig_2/
.ipynb_checkpoints/ , Jupyter, 127 linesfig_2d_ffSynapses-checkp oint.ipynb - fig_2/
.ipynb_checkpoints/ , Jupyter, 139 linesfig_2e_ffSynDensity-chec kpoint.ipynb - fig_2/
.ipynb_checkpoints/ , Jupyter, 215 linesfig_2f_3e_fractFFsyns_fr actRCsyns-checkpoint.ipy nb - fig_2/
fig_2e_ffSynapses.ipynb , Jupyter, 485 lines - fig_2/
fig_2f_ffSynDensity.ipyn , Jupyter, 485 linesb - fig_2/
fig_2g_ffSynFraction.ipy , Jupyter, 484 linesnb - fig_2/
fig_2h_totalSynapses.ipy , Jupyter, 484 linesnb - fig_3/
.ipynb_checkpoints/ , Jupyter, 1 linefig_3c_recSynapses-check point.ipynb - fig_3/
.ipynb_checkpoints/ , Jupyter, 1 linefig_3d_recSynDensity-che ckpoint.ipynb - fig_3/
.ipynb_checkpoints/ , Jupyter, 143 linesfig_3f_osnOutSyns-checkp oint.ipynb - fig_3/
fig_3b_ffSynapses.ipynb , Jupyter, 543 lines - fig_3/
fig_3c_ffSynDensity.ipyn , Jupyter, 543 linesb - fig_3/
fig_3d_ffSynFraction.ipy , Jupyter, 543 linesnb - fig_3/
fig_3e_cableLength.ipynb , Jupyter, 544 lines - fig_4/
.ipynb_checkpoints/ , Jupyter, 232 linesfig_4b_flyComp-cableLeng th-checkpoint.ipynb - fig_4/
.ipynb_checkpoints/ , Jupyter, 355 linesfig_4cd_flyComp-ffSynaps es_ffSynDensity-checkpoi nt.ipynb - fig_4/
.ipynb_checkpoints/ , Jupyter, 295 linesfig_4ef_flyComp-recSynap ses_recSynDensity-checkp oint.ipynb - fig_4/
fig_4b_recSynapses.ipynb , Jupyter, 543 lines - fig_4/
fig_4c_recSynDensity.ipy , Jupyter, 543 linesnb - fig_4/
fig_4d_recSynFraction.ip , Jupyter, 543 linesynb - fig_5/
.ipynb_checkpoints/ , Jupyter, 132 linesfig_5g_ribbons-tBars_bra nchOrder-checkpoint.ipyn b - fig_5/
.ipynb_checkpoints/ , Jupyter, 139 linesfig_5h_ribbons-tBars_dis t-1stBP-checkpoint.ipynb - fig_5/
fig_5g_ribbons-tBars_bra , Jupyter, 145 linesnchOrder.ipynb - fig_5/
fig_5h_ribbons-tBars_dis , Jupyter, 147 linest-1stBP.ipynb - fig_s3/
.ipynb_checkpoints/ , Jupyter, 179 linesfig_s3a_osn_cableLength_ 1stBP-checkpoint.ipynb - fig_s3/
.ipynb_checkpoints/ , Jupyter, 271 linesfig_s3bc_ffSynapses_ffSy nDesnsity_1stBP-checkpoi nt.ipynb - fig_s3/
.ipynb_checkpoints/ , Jupyter, 268 linesfig_s3de_recSynapses_rec SynDesnsity_1stBP-checkp oint.ipynb - fig_s3/
fig_s3_skeletons.ipynb , Jupyter, 198 lines - fig_s3/
fig_s3a_osn_cableLength_ , Jupyter, 179 lines1stBP.ipynb - fig_s3/
fig_s3bc_ffSynapses_ffSy , Jupyter, 271 linesnDesnsity_1stBP.ipynb - fig_s3/
fig_s3de_recSynapses_rec , Jupyter, 268 linesSynDesnsity_1stBP.ipynb - fig_s5/
fig_s5a_cable_length.ipy , Jupyter, 487 linesnb - fig_s5/
fig_s5bc_branch_number_b , Jupyter, 178 linesranch_order.ipynb - fig_s5/
fig_s5d_ffSynapses.ipynb , Jupyter, 487 lines - fig_s5/
fig_s5e_ffDensity.ipynb , Jupyter, 487 lines - fig_s5/
fig_s5f_recSynapses.ipyn , Jupyter, 487 linesb - fig_s5/
fig_s5g_recDensity.ipynb , Jupyter, 487 lines - fig_s6/
fig_s6b_cable_length.ipy , Jupyter, 108 linesnb - fig_s6/
fig_s6b_gaba_gene_expres , Jupyter, 189 linession.ipynb - fig_s6/
fig_s6c_ffFraction.ipynb , Jupyter, 108 lines - fig_s6/
fig_s6c_ffSynDensity.ipy , Jupyter, 109 linesnb - fig_s6/
fig_s6c_ffSynapses.ipynb , Jupyter, 108 lines - fig_s6/
fig_s6d_recFraction.ipyn , Jupyter, 108 linesb - fig_s6/
fig_s6d_recSynDensity.ip , Jupyter, 109 linesynb - fig_s6/
fig_s6d_recSynapses.ipyn , Jupyter, 108 linesb - fig_s7_s8/
cld_lettering.py , Python, 235 lines - fig_s7_s8/
fig_s7a_ffSynapses.ipynb , Jupyter, 509 lines - fig_s7_s8/
fig_s7b_ffSynDensity.ipy , Jupyter, 509 linesnb - fig_s7_s8/
fig_s7c_ffSynFraction.ip , Jupyter, 509 linesynb - fig_s7_s8/
fig_s8a_recSynapses.ipyn , Jupyter, 509 linesb - fig_s7_s8/
fig_s8b_recSynDensity.ip , Jupyter, 509 linesynb - fig_s7_s8/
fig_s8c_recSynFraction.i , Jupyter, 509 linespynb - fig_s9/
fig_s9ab_ffSynapses_ffDe , Jupyter, 686 linesnsity.ipynb - fig_s9/
fig_s9de_ach_gene_expres , Jupyter, 227 linession.ipynb - model/
ReciprocalOSN-model.ipyn , Jupyter, 172 linesb - retrieve data/
retrieve_neuron_data.ipy , Jupyter, 725 linesnb - LICENSE, License, 674 lines
- README.md, Text, 13 lines
The paper's code and data availability statement is in the Data section.
Tracing map
Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.
What the map holds:
- 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 138 scripts, each with its path and the digest of its content;
- 4 matches between paragraphs of the paper and lines of the code (method lexical-v1);
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
No dataset and no data link were found in the paper.
Data Availability
Data are publicly available at: doi: https://
Reproduced under the paper's license (CC BY), from the paper cited above.
Versions
The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.
Version 1, 27 September 2026: the first record
Recorded: type, language, journal, volume, issue, pages, dates, 12 authors, 10 MeSH terms, 15 funders, 113 references, 1 integrity notice.
Cite
This paper
Bao, J., Alford, W., Khandelwal, A., Walsh, L., Lantz, G., Poncio, S., Capdevila, L. S., Azatian, Y., DePasquale, B., Hildebrand, D. G. C., Younger, M. A., & Lee, W.-C. A. (2026). Recurrent synapses between CO2-sensitive olfactory sensory neurons enable robust CO2 detection in Aedes aegypti mosquitoes. PLoS biology, 24(9), e3003959. https://
BibTeX
@article{bao2026recurren
author = {Bao, Jialu and Alford, Wesley and Khandelwal, Avinash and Walsh, Laurel and Lantz, George and Poncio, Santiago and Capdevila, Laia Serratosa and Azatian, Yervand and DePasquale, Brian and Hildebrand, David G C and Younger, Meg A and Lee, Wei-Chung Allen},
title = {{Recurrent synapses between CO2-sensitive olfactory sensory neurons enable robust CO2 detection in Aedes aegypti mosquitoes}},
journal = {PLoS biology},
year = {2026},
month = sep,
volume = {24},
number = {9},
pages = {e3003959},
publisher = {PLOS},
issn = {1544-9173},
doi = {10.1371/
url = {https://
pmid = {42721124},
pmcid = {PMC13561330}
}
RIS
TY - JOUR
AU - Bao, Jialu
AU - Alford, Wesley
AU - Khandelwal, Avinash
AU - Walsh, Laurel
AU - Lantz, George
AU - Poncio, Santiago
AU - Capdevila, Laia Serratosa
AU - Azatian, Yervand
AU - DePasquale, Brian
AU - Hildebrand, David G C
AU - Younger, Meg A
AU - Lee, Wei-Chung Allen
TI - Recurrent synapses between CO2-sensitive olfactory sensory neurons enable robust CO2 detection in Aedes aegypti mosquitoes
T2 - PLoS biology
J2 - PLoS Biol
PY - 2026
DA - 2026/
VL - 24
IS - 9
SP - e3003959
SN - 1544-9173
PB - PLOS
DO - 10.1371/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1371/
"type": "article-journal",
"title": "Recurrent synapses between CO2-sensitive olfactory sensory neurons enable robust CO2 detection in Aedes aegypti mosquitoes",
"container-title": "PLoS biology",
"author": [
{
"family": "Bao",
"given": "Jialu"
},
{
"family": "Alford",
"given": "Wesley"
},
{
"family": "Khandelwal",
"given": "Avinash"
},
{
"family": "Walsh",
"given": "Laurel"
},
{
"family": "Lantz",
"given": "George"
},
{
"family": "Poncio",
"given": "Santiago"
},
{
"family": "Capdevila",
"given": "Laia Serratosa"
},
{
"family": "Azatian",
"given": "Yervand"
},
{
"family": "DePasquale",
"given": "Brian"
},
{
"family": "Hildebrand",
"given": "David G C"
},
{
"family": "Younger",
"given": "Meg A"
},
{
"family": "Lee",
"given": "Wei-Chung Allen"
}
],
"container-title-short":
"volume": "24",
"issue": "9",
"page": "e3003959",
"DOI": "10.1371/
"PMID": "42721124",
"PMCID": "PMC13561330",
"ISSN": "1544-9173",
"publisher": "PLOS",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
9,
10
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.3389/fnsys.2026.1822122 [code]
- Convergence-divergence circuits for multimodal integration of innate and learned opponent valences.Journal: Frontiers in systems neuroscienceIn common: seaborn, scikit-learn, pandas, 3 other tools, 23 references
- [2] doi:10.1038/s41586-026-10735-w [code]
- Distributed control circuits across a brain-and-cord connectome.Journal: NatureIn common: seaborn, scikit-learn, pandas, 3 other tools, drosophila, 17 references, author Wei-Chung Allen Lee
- [3] doi:10.1038/s41467-026-72152-x [code]
- Centralized brain networks controlling antennal grooming coordination.Journal: Nature communicationsIn common: statsmodels, seaborn, scikit-learn, 4 other tools, drosophila, 8 references
- [4] doi:10.1126/sciadv.aeg3535 [code]
- Undoing of firing rate adaptation enables invariant population codes.Journal: Science advancesIn common: scikit-learn, SciPy, Matplotlib, 1 other tool, cellular / molecular, 9 references
- [5] doi:10.1038/s41467-026-76682-2 [code]
- Odorant receptor coexpression and multi-expression in the dengue mosquito.Journal: Nature communicationsIn common: NumPy, drosophila, cellular / molecular, 9 references
- [6] doi:10.1016/j.isci.2026.117359 [code]
- Connectomic mapping of pharyngeal and gut sensory circuits in adult &
lt;i& gt;Drosophila& lt;/ i& gt;. Journal: iScienceIn common: statsmodels, seaborn, pandas, 3 other tools, drosophila, 7 references - [7] doi:10.1371/journal.pcbi.1014657 [code]
- Population morphology implies a common developmental blueprint for Drosophila motion detectors.Journal: PLoS computational biologyIn common: statsmodels, seaborn, scikit-learn, 4 other tools, drosophila, 5 references
- [8] doi:10.7554/elife.107276 [code]
- Deployment of endocytic machinery to periactive zones of nerve terminals is independent of active zone assembly and evoked release.Journal: eLifeIn common: scikit-posthocs, seaborn, scikit-learn, 4 other tools, drosophila, cellular / molecular, 3 references
- [9] doi:10.1371/journal.pbio.3003955 [code]
- Beat- and Side-family cell-surface molecules are expressed combinatorially in the partner neurons of the olfactory circuit in Drosophila.Journal: PLoS biologyIn common: drosophila, cellular / molecular, 7 references
- [10] doi:10.1038/s41593-026-02388-9 [code]
- Hippocampal CA3 connectomics reveals a gradient of mossy fiber inputs and selective feedforward inhibition onto pyramidal cells.Journal: Nature neuroscienceIn common: seaborn, scikit-learn, pandas, 3 other tools, histology / microscopy, 4 references
Contribute
The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.
Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 2 repositories of the authors' code, each at its verified commit and with its license, 138 scripts, and 4 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:43c3335e9eb9aad6…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
Request its removal
To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).
Discussion, reproductions, activity
Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.
Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
