OSCR

Recurrent synapses between CO2-sensitive olfactory sensory neurons enable robust CO2 detection in Aedes aegypti mosquitoes.

Code ↔ Paper

4 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 4 matches
  1. [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. [2] § Methods › Network model ↔ model/ReciprocalOSN-model.ipynb, lines 152–169 · score 0.56 · odor responses, background odors, root, model, OSN
  3. [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. [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

  1. # %%
  2. import pandas as pd
  3. import matplotlib.pyplot as plt
  4. from fafbseg import flywire
  5. import pymaid
  6. import navis as nv
  7. import numpy as np
  8. import seaborn as sns
  9. import scipy.stats as stats
  10. import statsmodels
  11. import scikit_posthocs as sp
  12. import sys
  13. import scipy
  14. import random
  15. import string
  16. from sklearn import metrics
  17. from sklearn.cluster import KMeans
  18. from sklearn.preprocessing import StandardScaler
  19. from sklearn.cluster import DBSCAN
  20. import matplotlib.colors as colors
  21. flywire.get_materialization_versions(dataset="production")
  22. # %%
  23. #check available flywire versions
  24. flywire.get_materialization_versions(dataset="production")
  25. #connect your catmaid instance
  26. catmaid_token = ""
  27. instance=pymaid.CatmaidInstance('https://radagast.hms.harvard.edu/catmaidaedes', catmaid_token)
  28. # %%
  29. def get_cable_overlap(OSNs, PN = None, volume = None):
  30. neurons = flywire.skeletonize_neuron(OSNs)
  31. if volume:
  32. neurons = nv.in_volume(neurons, volume)
  33. if PN == None:
  34. cable_overlap = nv.cable_overlap(neurons, neurons, dist= "2 microns")
  35. return cable_overlap
  36. else:
  37. PN = flywire.skeletonize_neuron(PN)
  38. PN_cable_overlap = nv.cable_overlap(neurons, PN, dist= "2 microns")
  39. return PN_cable_overlap
  40. def get_cable_length(OSNs,volume = None):
  41. neurons = flywire.skeletonize_neuron(OSNs)
  42. if volume:
  43. neurons = nv.in_volume(neurons, volume)
  44. return neurons.cable_length
  45. def get_total_synapses(OSNs, volume = None):
  46. neurons = flywire.skeletonize_neuron(OSNs)
  47. if volume:
  48. neurons = nv.in_volume(neurons, volume)
  49. return flywire.get_synapses(neurons, pre=True, post=False, attach=True, dataset='production', min_score=65,progress=False)
  50. def get_num_connectors(neuron1, neuron2, volume = None):
  51. if volume:
  52. neuron1 = nv.in_volume(neuron1, volume)
  53. neuron2 = nv.in_volume(neuron2, volume)
  54. df = flywire.synapses.get_adjacency(neuron1, targets=neuron2, dataset='production', min_score=65, progress=True)
  55. return df.values[0][0]
  56. def synapses_per_micron(cable_overlap_df, PN = None):
  57. cable_overlap_synapse_density = []
  58. for rowIndex, row in cable_overlap_df.iterrows(): #iterate over rows
  59. synapse_count = []
  60. cable_overlap_length = []
  61. for columnIndex, value in row.items():
  62. if value != 0:
  63. synapse_count.append(get_num_connectors(rowIndex, columnIndex))
  64. cable_overlap_length.append(value)
  65. cable_overlap_synapse_density.append(np.nanmean(np.array(synapse_count) / np.array(cable_overlap_length)) * 1000)
  66. return pd.DataFrame(cable_overlap_synapse_density,columns=['overlap_density'], index=cable_overlap_df.index)
  67. def get_neurons_without_overlap(cable_overlap_df):
  68. cable_overlap_df = cable_overlap_df.sum(axis=1)
  69. no_PN_overlap_neurons = [cable_overlap_df.index[index] for index, neuron in enumerate(cable_overlap_df) if neuron == 0.0]
  70. return no_PN_overlap_neurons
  71. # %% [markdown]
  72. # ## Projection Neuron IDs for glomeruli
  73. # |Glomerulus|Right Hemisphere|Left Hemisphere|
  74. # |:---------|:------------:|-----------:|
  75. # |DA4l |720575940608970197 |720575940649045369|
  76. # |DC1| 720575940637056887| 720575940621529435|
  77. # |DL4 |720575940627708688 | 720575940617343316|
  78. # |DL5 |720575940617207185 | 720575940639080765|
  79. # |DM3| 720575940614727903 | 720575940630549370|
  80. # |DM4 |720575940623528925 | 720575940615366055|
  81. # |DP1m |720575940618308825 | 720575940622726271|
  82. # |VA2| 720575940611079236 | 720575940609460491|
  83. # |VA4| 720575940617668747 | 720575940642086389|
  84. # |VA6 |720575940636873791 | 720575940637594334|
  85. # |VA7l | 720575940625784153 | 720575940618277184|
  86. # |VC1 |720575940637526190 | 720575940633190847|
  87. # |VC2 |720575940628739560 | 720575940630097103|
  88. # |VL2a |720575940618295454 | 720575940603464672|
  89. # |VL2p |720575940628467611 | 720575940618865112|
  90. # |VM4 |720575940640971995|
  91. # |DA4m |720575940631930828|
  92. # |VM6 |720575940624057853|
  93. #
  94. # ## Glomeruli with more than one uPN projection neurons
  95. # |Glomerulus|Right Hemisphere|
  96. # |:---------|------------:|
  97. # |D |720575940603985952 720575940633804212 720575940627844734|
  98. # |DA1 |720575940614309535 720575940637208718 720575940613345442 720575940626034819 720575940619385765 720575940605102694 720575940603231916 720575940621185050|
  99. # |DA2 |720575940622364184 720575940611849187 720575940626937617 720575940622734835|
  100. # |DC2 |720575940627160322 720575940616824588|
  101. # |DC3| 720575940630131663 720575940613419695 720575940634939327 720575940634715743|
  102. # |DL1 |720575940616079035 720575940622368792 720575940613809554|
  103. # |DL2d |720575940628316047 720575940630928715 720575940620103590 720575940642046453|
  104. # |DL3 |720575940630778428 720575940621926669 720575940627353426 720575940630778428 720575940620638335|
  105. # |DM2 |720575940638633535 720575940630024566|
  106. # |DM5 |720575940644258327 720575940629926159 720575940640032896|
  107. # |DM6 |720575940631328104 720575940622785062 720575940620437339|
  108. # |DP1l |720575940648650884 720575940606762686|
  109. # |VA1d |720575940622811430 720575940640804853 720575940619620852|
  110. # |VA1v |720575940629097922 720575940620199962 720575940628283560 720575940629733626 720575940632720026 720575940634229615|
  111. # |VA3 |720575940656090017 720575940629009513 720575940604431584|
  112. # |VA5 |720575940619838912 720575940637009636 720575940637231593|
  113. # |VA7m |720575940620068518 720575940640398477 720575940639680957|
  114. # |VC3m |720575940608845525 720575940608199748 720575940624515571|
  115. # |VL1 |720575940624863015 720575940637712243 720575940620595053|
  116. # |VM1 |720575940628077568 720575940623444715|
  117. # |VM2 |720575940640697808 720575940617179451|
  118. # |VM3 |720575940627480586 720575940610048981|
  119. # |VM7d |720575940628524292 720575940613167007|
  120. # |VM7v |720575940619337536 720575940621256212|
  121. # |VM5d |720575940611372714 720575940644961588 720575940635082871 720575940627035388|
  122. # %%
  123. DA4l_pn = 720575940608970197
  124. DC1_pn = 720575940637056887
  125. DL4_pn = 720575940627708688
  126. DL5_pn = [720575940617207185, 720575940630432815]
  127. DM3_pn = 720575940614727903
  128. DM4_pn = [720575940623528925 , 720575940628323919, 720575940606767806]
  129. DP1m_pn = 720575940618308825
  130. VA2_pn = 720575940611079236
  131. VA4_pn = 720575940617668747
  132. VA6_pn = 720575940636873791
  133. VA7l_pn = 720575940625784153
  134. VC1_pn = 720575940637526190
  135. VC2_pn = 720575940628739560
  136. VL2a_pn = 720575940618295454
  137. VL2p_pn = 720575940628467611
  138. VM4_pn = 720575940640971995
  139. DM1_pn = 720575940630770042
  140. V_bilateral_rightsoma_pn=720575940626143806
  141. V_bilateral_leftsoma_pn=720575940630546540
  142. V_unilateral_pn=720575940637910106
  143. V_pn = [720575940626143806,720575940630546540,720575940637910106]
  144. D_pn = [720575940603985952, 720575940633804212, 720575940627844734]
  145. DA1_pn = [720575940614309535, 720575940637208718, 720575940613345442, 720575940626034819, 720575940619385765, 720575940605102694, 720575940603231916, 720575940621185050,720575940646122804]
  146. DA2_pn = [720575940622364184, 720575940611849187, 720575940626937617, 720575940638719104,720575940622734835]
  147. DA4m_pn = 720575940631930828
  148. DC2_pn = [720575940627160322, 720575940616824588]
  149. DC3_pn = [720575940630131663, 720575940613419695, 720575940634939327]
  150. DL1_pn = [720575940616079035, 720575940622368792]
  151. DL2d_pn = [720575940628316047, 720575940630928715, 720575940620103590, 720575940642046453,720575940605421442, 720575940613706866, 720575940623922869]
  152. DL3_pn = [720575940630778428, 720575940621926669, 720575940627353426, 720575940630778428, 720575940620638335]
  153. DM2_pn = [720575940638633535, 720575940630024566]
  154. DM5_pn = [720575940644258327, 720575940629926159, 720575940640032896]
  155. DM6_pn = [720575940631328104, 720575940622785062, 720575940620437339]
  156. DP1l_pn = [720575940648650884, 720575940606762686]
  157. VA1d_pn = [720575940622811430, 720575940640804853, 720575940619620852]
  158. VA1v_pn = [720575940629097922, 720575940620199962, 720575940628283560, 720575940629733626, 720575940632720026, 720575940634229615]
  159. VA3_pn = [720575940656090017, 720575940604431584]
  160. VA5_pn = [720575940619838912, 720575940637009636, 720575940637231593]
  161. VA7m_pn = [720575940620068518, 720575940640398477, 720575940639680957]
  162. VC5_pn = [720575940608845525, 720575940608199748, 720575940624515571] #VC3m PNs due to naming changing VC3m -> VC5
  163. VL1_pn = [720575940624863015, 720575940620595053]
  164. VM1_pn = [720575940628077568, 720575940623444715]
  165. VM2_pn = [720575940640697808, 720575940617179451]
  166. VM3_pn = [720575940627480586, 720575940610048981]
  167. VM6_pn = 720575940624057853
  168. VM7d_pn = [720575940628524292, 720575940613167007]
  169. VM7v_pn = [720575940619337536, 720575940621256212]
  170. VM5d_pn = [720575940611372714, 720575940644961588, 720575940635082871, 720575940627035388]
  171. # added from 2020 Current Biology
  172. DA3_pn = [720575940625924618, 720575940659400577]
  173. DC4_pn = 720575940613579943
  174. DL2v_pn = [720575940620467438,720575940611022515,720575940628181520 ,720575940627772009]
  175. VC3_pn = [720575940615394719,720575940619902598 ,720575940619928429 ,720575940620465904]
  176. VC4_pn = [720575940624001321,720575940635933119,720575940609454603]
  177. VM5v_pn = [720575940610505170 ,720575940620189790 ,720575940625431866 ]
  178. # %%
  179. #load .ply files
  180. dm1_l=nv.read_mesh("../glom_meshes/DM1_R.ply", output='volume') # DM1
  181. v_l=nv.read_mesh("../glom_meshes/V_R.ply", output='volume') # V
  182. gloms = ["DA4l", "DC1", "DL4", "DL5", "DM3","DM4", "DP1m",
  183. "VA2", "VA4", "VA6", "VA7l", "VC1", "VC2", "VL2a",
  184. "VL2p", "VM4","DM1","V",
  185. "D",
  186. "DA1",
  187. "DA2",
  188. "DA4m",
  189. "DC2",
  190. "DC3",
  191. "DL1",
  192. "DL2d",
  193. "DL3",
  194. "DM2",
  195. "DM5",
  196. "DM6",
  197. "DP1l",
  198. "VA1d",
  199. "VA1v",
  200. "VA3",
  201. "VA5",
  202. "VA7m",
  203. "VL1",
  204. "VM1",
  205. "VM2",
  206. "VM3",
  207. "VM7d",
  208. "VM7v",
  209. "VM5d",
  210. "DA3",
  211. "DC4",
  212. "DL2v",
  213. "VC3",
  214. 'VC5',
  215. 'VM6',
  216. "VC4",
  217. "VM5v",
  218. ]
  219. for glom in gloms:
  220. print(glom)
  221. exec(glom +"_mesh = nv.read_mesh(" + "'../glom_meshes/" + glom + "_R.ply' , output='volume')")
  222. # %%
  223. #retrieve neuron_ids
  224. glomeruli_list = ["ORN_DA4l",
  225. "ORN_DC1",
  226. "ORN_DL4",
  227. "ORN_DL5",
  228. "ORN_DM3",
  229. "ORN_DM4",
  230. "ORN_DP1m",
  231. "ORN_VA2",
  232. "ORN_VA4",
  233. "ORN_VA6",
  234. "ORN_VA7l",
  235. "ORN_VC1",
  236. "ORN_VC2",
  237. "ORN_VL2a",
  238. "ORN_VL2p",
  239. "ORN_VM4",
  240. "ORN_DM1",
  241. "ORN_V",
  242. "ORN_D",
  243. "ORN_DA1",
  244. "ORN_DA2",
  245. "ORN_DA4m",
  246. "ORN_DC2",
  247. "ORN_DC3",
  248. "ORN_DL1",
  249. "ORN_DL2d",
  250. "ORN_DL3",
  251. "ORN_DM2",
  252. "ORN_DM5",
  253. "ORN_DM6",
  254. "ORN_DP1l",
  255. "ORN_VA1d",
  256. "ORN_VA1v",
  257. "ORN_VA3",
  258. "ORN_VA5",
  259. "ORN_VA7m",
  260. "ORN_VC3",
  261. 'ORN_VC5',
  262. 'ORN_VM6',
  263. "ORN_VL1",
  264. "ORN_VM1",
  265. "ORN_VM2",
  266. "ORN_VM3",
  267. "ORN_VM7d",
  268. "ORN_VM7v",
  269. "ORN_VM5d",
  270. "ORN_DA3",
  271. "ORN_DC4",
  272. "ORN_DL2v",
  273. "ORN_VC3l",
  274. "ORN_VC4",
  275. "ORN_VM5v",
  276. ]
  277. glomeruli_OSNs = pd.DataFrame()
  278. for glomeruli in glomeruli_list:
  279. if glomeruli in ['ORN_VC3','ORN_VC5','ORN_VM6']:
  280. annotation_search = flywire.search_annotations(flywire.NeuronCriteria(cell_type=glomeruli, side='left', annotation_version="v2.0.0"))
  281. else:
  282. print(glomeruli)
  283. annotation_search = flywire.search_annotations(flywire.NeuronCriteria(hemibrain_type=glomeruli, side='left', annotation_version="v2.0.0"))
  284. print(f' for {glomeruli} {annotation_search.shape[0]} neurons were found')
  285. glomeruli_OSNs = pd.concat([glomeruli_OSNs, annotation_search])
  286. glomeruli_OSNs = glomeruli_OSNs[['root_id','hemibrain_type','cell_type']] #keep just the root_id and the glomeruli
  287. # %%
  288. #the following neurons have no synapses with projection neurons in their glomerulus, so they were excluded from all analysis
  289. neurons_to_exclude = [720575940642936520, 720575940623359466, 720575940633033133, 720575940621862605,
  290. 720575940605724081, 720575940604876977, 720575940630971434, 720575940632824531,
  291. 720575940611791834, 720575940614890642, 720575940611437973, 720575940619969329,
  292. 720575940614019112, 720575940615639199, 720575940639118653, 720575940615629173,
  293. 720575940621082138, 720575940608615363, 720575940630679749, 720575940628398791,
  294. 720575940639089571, 720575940634883179, 720575940638202852, 720575940614006934,
  295. 720575940603870688, 720575940632033875, 720575940632391736, 720575940623750852,
  296. 720575940622248709, 720575940631930415, 720575940613885506, 720575940627787343,
  297. 720575940624671490, 720575940631393823, 720575940619029589, 720575940623655605,
  298. 720575940630462572,
  299. ]
  300. # %%
  301. glomeruli_OSNs = glomeruli_OSNs[~glomeruli_OSNs['root_id'].isin(neurons_to_exclude)]
  302. # %%
  303. glom_list = ["D",
  304. "DA1",
  305. "DA2",
  306. "DA3",
  307. "DA4l",
  308. "DA4m",
  309. "DC1",
  310. "DC2",
  311. "DC3",
  312. "DC4",
  313. "DL1",
  314. "DL2d",
  315. "DL2v",
  316. "DL3",
  317. "DL4",
  318. "DL5",
  319. "DM1",
  320. "DM2",
  321. "DM3",
  322. "DM4",
  323. "DM5",
  324. "DM6",
  325. "DP1l",
  326. "DP1m",
  327. "V",
  328. "VA1d",
  329. "VA1v",
  330. "VA2",
  331. "VA3",
  332. "VA4",
  333. "VA5",
  334. "VA6",
  335. "VA7l",
  336. "VA7m",
  337. "VC1",
  338. "VC2",
  339. "VC3",
  340. "VC4",
  341. "VC5",
  342. "VL1",
  343. "VL2a",
  344. "VL2p",
  345. "VM1",
  346. "VM2",
  347. "VM3",
  348. "VM4",
  349. "VM5d"
  350. "VM5v",
  351. "VM6",
  352. "VM7d",
  353. "VM7v"]
  354. for glom in glom_list:
  355. retries = 5
  356. for retry in range(retries):
  357. try:
  358. print(glom)
  359. if glom in ['VM6']:
  360. 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)")
  361. 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)")
  362. 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)")
  363. 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)")
  364. 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)")
  365. 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)")
  366. elif glom in ['VC3','VC5']:
  367. 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)")
  368. 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)")
  369. exec(f"{glom}_total_synapses = get_total_synapses(glomeruli_OSNs[glomeruli_OSNs['cell_type']=='ORN_{glom}']['root_id'], volume = {glom}_mesh)")
  370. exec(f"{glom}_feedforward = get_cable_overlap(glomeruli_OSNs[glomeruli_OSNs['cell_type']=='ORN_{glom}']['root_id'],PN={glom}_pn, volume={glom}_mesh)")
  371. exec(f"{glom}_recurrent = get_cable_overlap(glomeruli_OSNs[glomeruli_OSNs['cell_type']=='ORN_{glom}']['root_id'],volume={glom}_mesh)")
  372. exec(f"{glom}_cable_length = get_cable_length(glomeruli_OSNs[glomeruli_OSNs['cell_type']=='ORN_{glom}']['root_id'], volume={glom}_mesh)")
  373. else:
  374. 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)")
  375. 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)")
  376. exec(f"{glom}_total_synapses = get_total_synapses(glomeruli_OSNs[glomeruli_OSNs['hemibrain_type']=='ORN_{glom}']['root_id'], volume = {glom}_mesh)")
  377. exec(f"{glom}_feedforward = get_cable_overlap(glomeruli_OSNs[glomeruli_OSNs['hemibrain_type']=='ORN_{glom}']['root_id'],PN={glom}_pn, volume={glom}_mesh)")
  378. exec(f"{glom}_recurrent = get_cable_overlap(glomeruli_OSNs[glomeruli_OSNs['hemibrain_type']=='ORN_{glom}']['root_id'],volume={glom}_mesh)")
  379. exec(f"{glom}_cable_length = get_cable_length(glomeruli_OSNs[glomeruli_OSNs['hemibrain_type']=='ORN_{glom}']['root_id'], volume={glom}_mesh)")
  380. exec(f"{glom}_feedforward_synapses_per_micron = synapses_per_micron({glom}_feedforward,PN={glom}_pn)")
  381. exec(f"{glom}_recurrent_synapses_per_micron = synapses_per_micron({glom}_recurrent)")
  382. except:
  383. if retry < retries - 1:
  384. print(f'number of retries left = {retries-retry}')
  385. continue
  386. else:
  387. raise
  388. break
  389. # %% [markdown]
  390. # retrieve mosquito data from catmaid
  391. # %%
  392. #MD1
  393. MD1OSNs = pymaid.get_skids_by_annotation(['innervates MD1', 'left palp nerve', 'sensory neuron', 'PSPs done'], allow_partial = False, intersect = True)
  394. MD1OSNsALL = pymaid.get_skids_by_annotation(['innervates MD1', 'left palp nerve', 'sensory neuron'], allow_partial = False, intersect = True)
  395. MD1volume = pymaid.get_volume('MD1 04/06/21')
  396. MD1neurons = pymaid.get_neuron(MD1OSNs)
  397. MD1neurons = pymaid.CatmaidNeuron.prune_by_volume(MD1neurons,v=MD1volume,mode='IN',prevent_fragments=True)
  398. MD1neuronsALL = pymaid.get_neuron(MD1OSNsALL)
  399. # %%
  400. #MD2
  401. MD2OSNs = pymaid.get_skids_by_annotation(['innervates MD2', 'left palp nerve', 'sensory neuron', 'PSPs done'], allow_partial = False, intersect = True)
  402. MD2OSNsALL = pymaid.get_skids_by_annotation(['innervates MD2', 'left palp nerve', 'sensory neuron'], allow_partial = False, intersect = True)
  403. MD2volume = pymaid.get_volume('MD2 2022')
  404. MD2neurons = pymaid.get_neuron(MD2OSNs)
  405. MD2neurons = pymaid.CatmaidNeuron.prune_by_volume(MD2neurons,v=MD2volume,mode='IN',prevent_fragments=True)
  406. MD2neuronsALL = pymaid.get_neuron(MD2OSNsALL)
  407. # %%
  408. #MD3
  409. MD3OSNs = pymaid.get_skids_by_annotation(['innervates MD3', 'left palp nerve', 'sensory neuron', 'PSPs done'], allow_partial = False, intersect = True)
  410. MD3OSNsALL = pymaid.get_skids_by_annotation(['innervates MD3', 'left palp nerve', 'sensory neuron'], allow_partial = False, intersect = True)
  411. MD3volume = pymaid.get_volume('MD3 2022')
  412. MD3neurons = pymaid.get_neuron(MD3OSNs)
  413. MD3neurons = pymaid.CatmaidNeuron.prune_by_volume(MD3neurons,v=MD3volume,mode='IN',prevent_fragments=True)
  414. MD3neuronsALL = pymaid.get_neuron(MD3OSNsALL)
  415. # %%
  416. #initialize empty dataframe
  417. flyneurons=pd.DataFrame(columns=['id', 'total cable length', 'cable length in glom', 'unilateral feedforward', 'bilateral left feedforward', 'bilateral right feedforward', 'recurrent connections', 'glomerulus'])
  418. md1_synapse_count = []
  419. md1_synapse_count_in_volume = []
  420. md1_total_synapses = []
  421. md1_total_synapses_restricted = []
  422. md1_synapse_count_feedforward = []
  423. md1_synapse_count_feedforward_unrestricted = []
  424. md1_cable_overlap = []
  425. md1_feedforward_density = []
  426. md1_feedforward_density_unrestricted = []
  427. md1_recurrent_density = []
  428. md1_recurrent_density_unrestricted = []
  429. md1_cable_length = []
  430. md1_cable_overlap_percentage = []
  431. md1_feedforward_fraction = []
  432. md1_recurrent_fraction = []
  433. md1_recurrent_fraction_restricted = []
  434. md1_recurrent_synapses = []
  435. md1_recurrent_synapses_restricted = []
  436. for n in MD1neurons:
  437. skeletonid=n.skeleton_id
  438. skelid=int(skeletonid)
  439. print(skelid)
  440. labels = pymaid.get_label_list()
  441. neuronlabels=labels[labels.skeleton_id==skelid]
  442. branchpoint=neuronlabels[neuronlabels.tag=='first branch point']
  443. if len(branchpoint) !=1:
  444. print('error, neuron skelid=%i does not have exactly 1 branchpoint tag'% skelid)
  445. else: bpnode=branchpoint.node_id.values[0]
  446. PN = pymaid.get_neuron('295')
  447. cable_overlap_length = nv.cable_overlap(n, PN, dist= "2 microns")
  448. connections = pymaid.get_partners(n).set_index('skeleton_id')
  449. connections = connections[connections['relation'] == 'downstream']
  450. total_synapses = pd.DataFrame(connections['total']).transpose()
  451. total_synapses.columns.names = ['targets']
  452. total_synapses.index = [n.id]
  453. total_synapses.index.names = ['sources']
  454. total_synapses_restricted = pymaid.filter_connectivity(total_synapses, restrict_to='MD1 04/06/21')
  455. #feedforward connections
  456. feedforward = pymaid.adjacency_matrix(n, targets=295)
  457. glom_connectivity=pymaid.filter_connectivity(feedforward, restrict_to='MD1 04/06/21')
  458. feedforward_value=int(glom_connectivity.iloc[0])
  459. #recurrent connections
  460. recurrent = pymaid.adjacency_matrix(n, targets=MD1neuronsALL)
  461. recurrent_glom_connectivity=pymaid.filter_connectivity(recurrent, restrict_to='MD1 04/06/21')
  462. print(recurrent_glom_connectivity)
  463. cable_overlap = nv.cable_overlap(n,MD1neuronsALL,dist= "2 microns")
  464. synapse_density_unrestricted = recurrent / (cable_overlap.values / 1000)
  465. synapse_density = recurrent_glom_connectivity / (cable_overlap.values / 1000)
  466. md1_total_synapses.append(sum(total_synapses.iloc[0]))
  467. md1_total_synapses_restricted.append(sum(total_synapses_restricted.iloc[0]))
  468. md1_synapse_count.append(recurrent.values)
  469. md1_synapse_count_feedforward.append(feedforward_value)
  470. md1_synapse_count_feedforward_unrestricted.append(int(feedforward.iloc[0]))
  471. md1_cable_overlap.append(cable_overlap.values)
  472. md1_feedforward_density.append((glom_connectivity/(cable_overlap_length/1000)).iloc[0].values[0])
  473. md1_feedforward_density_unrestricted.append((int(feedforward.iloc[0])/(cable_overlap_length/1000)).iloc[0].values[0])
  474. md1_recurrent_density.append(synapse_density.mean(axis=1).iloc[0])
  475. md1_recurrent_density_unrestricted.append(synapse_density_unrestricted.mean(axis=1).iloc[0])
  476. md1_cable_length.append(n.cable_length/1000)
  477. md1_cable_overlap_percentage.append(((cable_overlap.values /1000)/(n.cable_length/1000)).mean())
  478. sum_recurrent=recurrent.iloc[0].sum()
  479. md1_feedforward_fraction.append(feedforward_value / total_synapses_restricted.sum(axis=1)[0])
  480. md1_recurrent_synapses.append(recurrent.iloc[0].sum())
  481. md1_recurrent_synapses_restricted.append(recurrent_glom_connectivity.sum(axis=1)[0])
  482. md1_recurrent_fraction.append(sum_recurrent / total_synapses)
  483. md1_recurrent_fraction_restricted.append(recurrent_glom_connectivity.sum(axis=1)[0]/sum(total_synapses_restricted.iloc[0]))
  484. #append to dataframe
  485. flyneurons= pd.concat([flyneurons,
  486. pd.DataFrame({'id':n,
  487. 'total cable length':n.cable_length,
  488. 'cable length in glom': cable_overlap_length.values[0][0], #dlength,
  489. 'unilateral feedforward':feedforward_value,
  490. 'recurrent connections': sum_recurrent,
  491. 'glomerulus':'Glomerulus 1'}, index = [0])
  492. ],
  493. ignore_index=True)
  494. # %%
  495. #initialize empty dataframe
  496. flyneurons=pd.DataFrame(columns=['id', 'total cable length', 'cable length in glom', 'unilateral feedforward', 'bilateral left feedforward', 'bilateral right feedforward', 'recurrent connections', 'glomerulus'])
  497. md2_synapse_count = []
  498. md2_synapse_count_in_volume = []
  499. md2_total_synapses = []
  500. md2_total_synapses_restricted = []
  501. md2_synapse_count_feedforward = []
  502. md2_synapse_count_feedforward_unrestricted = []
  503. md2_cable_overlap = []
  504. md2_feedforward_density = []
  505. md2_feedforward_density_unrestricted = []
  506. md2_recurrent_density = []
  507. md2_recurrent_density_unrestricted = []
  508. md2_cable_length = []
  509. md2_cable_overlap_percentage = []
  510. md2_feedforward_fraction = []
  511. md2_recurrent_fraction = []
  512. md2_recurrent_fraction_restricted = []
  513. md2_recurrent_synapses = []
  514. md2_recurrent_synapses_restricted = []
  515. for n in MD2neurons:
  516. skeletonid=n.skeleton_id
  517. skelid=int(skeletonid)
  518. print(skelid)
  519. labels = pymaid.get_label_list()
  520. neuronlabels=labels[labels.skeleton_id==skelid]
  521. branchpoint=neuronlabels[neuronlabels.tag=='first branch point']
  522. if len(branchpoint) !=1:
  523. print('error, neuron skelid=%i does not have exactly 1 branchpoint tag'% skelid)
  524. else: bpnode=branchpoint.node_id.values[0]
  525. PN = pymaid.get_neuron('690')
  526. cable_overlap_length = nv.cable_overlap(n, PN, dist= "2 microns")
  527. connections = pymaid.get_partners(n).set_index('skeleton_id')
  528. connections = connections[connections['relation'] == 'downstream']
  529. total_synapses = pd.DataFrame(connections['total']).transpose()
  530. total_synapses.columns.names = ['targets']
  531. total_synapses.index = [n.id]
  532. total_synapses.index.names = ['sources']
  533. total_synapses_restricted = pymaid.filter_connectivity(total_synapses, restrict_to='MD2 2022')
  534. #feedforward connections
  535. feedforward = pymaid.adjacency_matrix(n, targets=690)
  536. glom_connectivity=pymaid.filter_connectivity(feedforward, restrict_to='MD2 2022')
  537. feedforward_value=int(glom_connectivity.iloc[0])
  538. #recurrent connections
  539. recurrent = pymaid.adjacency_matrix(n, targets=MD2neuronsALL)
  540. recurrent_glom_connectivity=pymaid.filter_connectivity(recurrent, restrict_to='MD2 2022')
  541. print(recurrent_glom_connectivity)
  542. cable_overlap = nv.cable_overlap(n,MD2neuronsALL,dist= "2 microns")
  543. synapse_density_unrestricted = recurrent / (cable_overlap.values / 1000)
  544. synapse_density = recurrent_glom_connectivity / (cable_overlap.values / 1000)
  545. md2_total_synapses.append(sum(total_synapses.iloc[0]))
  546. md2_total_synapses_restricted.append(sum(total_synapses_restricted.iloc[0]))
  547. md2_synapse_count.append(recurrent.values)
  548. md2_synapse_count_feedforward.append(feedforward_value)
  549. md2_synapse_count_feedforward_unrestricted.append(int(feedforward.iloc[0]))
  550. md2_cable_overlap.append(cable_overlap.values)
  551. md2_feedforward_density.append((glom_connectivity/(cable_overlap_length/1000)).iloc[0].values[0])
  552. md2_feedforward_density_unrestricted.append((int(feedforward.iloc[0])/(cable_overlap_length/1000)).iloc[0].values[0])
  553. md2_recurrent_density.append(synapse_density.mean(axis=1).iloc[0])
  554. md2_recurrent_density_unrestricted.append(synapse_density_unrestricted.mean(axis=1).iloc[0])
  555. md2_cable_length.append(n.cable_length/1000)
  556. md2_cable_overlap_percentage.append(((cable_overlap.values /1000)/(n.cable_length/1000)).mean())
  557. sum_recurrent=recurrent.iloc[0].sum()
  558. md2_feedforward_fraction.append(feedforward_value / total_synapses_restricted.sum(axis=1)[0])
  559. md2_recurrent_synapses.append(recurrent.iloc[0].sum())
  560. md2_recurrent_synapses_restricted.append(recurrent_glom_connectivity.sum(axis=1)[0])
  561. md2_recurrent_fraction.append(sum_recurrent / total_synapses)
  562. md2_recurrent_fraction_restricted.append(recurrent_glom_connectivity.sum(axis=1)[0]/sum(total_synapses_restricted.iloc[0]))
  563. #append to dataframe
  564. flyneurons= pd.concat([flyneurons,
  565. pd.DataFrame({'id':n,
  566. 'total cable length':n.cable_length,
  567. 'cable length in glom': cable_overlap_length.values[0][0], #dlength,
  568. 'unilateral feedforward':feedforward_value,
  569. 'recurrent connections': sum_recurrent,
  570. 'glomerulus':'Glomerulus 1'}, index = [0])
  571. ],
  572. ignore_index=True)
  573. # %%
  574. #initialize empty dataframe
  575. flyneurons=pd.DataFrame(columns=['id', 'total cable length', 'cable length in glom', 'unilateral feedforward', 'bilateral left feedforward', 'bilateral right feedforward', 'recurrent connections', 'glomerulus'])
  576. md3_synapse_count = []
  577. md3_synapse_count_in_volume = []
  578. md3_total_synapses = []
  579. md3_total_synapses_restricted = []
  580. md3_synapse_count_feedforward = []
  581. md3_synapse_count_feedforward_unrestricted = []
  582. md3_cable_overlap = []
  583. md3_feedforward_density = []
  584. md3_feedforward_density_unrestricted = []
  585. md3_recurrent_density = []
  586. md3_recurrent_density_unrestricted = []
  587. md3_cable_length = []
  588. md3_cable_overlap_percentage = []
  589. md3_feedforward_fraction = []
  590. md3_recurrent_fraction = []
  591. md3_recurrent_fraction_restricted = []
  592. md3_recurrent_synapses = []
  593. md3_recurrent_synapses_restricted = []
  594. for n in MD3neurons:
  595. skeletonid=n.skeleton_id
  596. skelid=int(skeletonid)
  597. print(skelid)
  598. labels = pymaid.get_label_list()
  599. neuronlabels=labels[labels.skeleton_id==skelid]
  600. branchpoint=neuronlabels[neuronlabels.tag=='first branch point']
  601. if len(branchpoint) !=1:
  602. print('error, neuron skelid=%i does not have exactly 1 branchpoint tag'% skelid)
  603. else: bpnode=branchpoint.node_id.values[0]
  604. PN = pymaid.get_neuron('11126')
  605. cable_overlap_length = nv.cable_overlap(n, PN, dist= "2 microns")
  606. connections = pymaid.get_partners(n).set_index('skeleton_id')
  607. connections = connections[connections['relation'] == 'downstream']
  608. total_synapses = pd.DataFrame(connections['total']).transpose()
  609. total_synapses.columns.names = ['targets']
  610. total_synapses.index = [n.id]
  611. total_synapses.index.names = ['sources']
  612. total_synapses_restricted = pymaid.filter_connectivity(total_synapses, restrict_to='MD3 2022')
  613. #feedforward connections
  614. feedforward = pymaid.adjacency_matrix(n, targets=11126)
  615. glom_connectivity=pymaid.filter_connectivity(feedforward, restrict_to='MD3 2022')
  616. feedforward_value=int(glom_connectivity.iloc[0])
  617. #recurrent connections
  618. recurrent = pymaid.adjacency_matrix(n, targets=MD3neuronsALL)
  619. recurrent_glom_connectivity=pymaid.filter_connectivity(recurrent, restrict_to='MD3 2022')
  620. print(recurrent_glom_connectivity)
  621. cable_overlap = nv.cable_overlap(n,MD3neuronsALL,dist= "2 microns")
  622. synapse_density_unrestricted = recurrent / (cable_overlap.values / 1000)
  623. synapse_density = recurrent_glom_connectivity / (cable_overlap.values / 1000)
  624. md3_total_synapses.append(sum(total_synapses.iloc[0]))
  625. md3_total_synapses_restricted.append(sum(total_synapses_restricted.iloc[0]))
  626. md3_synapse_count.append(recurrent.values)
  627. md3_synapse_count_feedforward.append(feedforward_value)
  628. md3_synapse_count_feedforward_unrestricted.append(int(feedforward.iloc[0]))
  629. md3_cable_overlap.append(cable_overlap.values)
  630. md3_feedforward_density.append((glom_connectivity/(cable_overlap_length/1000)).iloc[0].values[0])
  631. md3_feedforward_density_unrestricted.append((int(feedforward.iloc[0])/(cable_overlap_length/1000)).iloc[0].values[0])
  632. md3_recurrent_density.append(synapse_density.mean(axis=1).iloc[0])
  633. md3_recurrent_density_unrestricted.append(synapse_density_unrestricted.mean(axis=1).iloc[0])
  634. md3_cable_length.append(n.cable_length/1000)
  635. md3_cable_overlap_percentage.append(((cable_overlap.values /1000)/(n.cable_length/1000)).mean())
  636. sum_recurrent=recurrent.iloc[0].sum()
  637. md3_feedforward_fraction.append(feedforward_value / total_synapses_restricted.sum(axis=1)[0])
  638. md3_recurrent_synapses.append(recurrent.iloc[0].sum())
  639. md3_recurrent_synapses_restricted.append(recurrent_glom_connectivity.sum(axis=1)[0])
  640. md3_recurrent_fraction.append(sum_recurrent / total_synapses)
  641. md3_recurrent_fraction_restricted.append(recurrent_glom_connectivity.sum(axis=1)[0]/sum(total_synapses_restricted.iloc[0]))
  642. #append to dataframe
  643. flyneurons= pd.concat([flyneurons,
  644. pd.DataFrame({'id':n,
  645. 'total cable length':n.cable_length,
  646. 'cable length in glom': cable_overlap_length.values[0][0], #dlength,
  647. 'unilateral feedforward':feedforward_value,
  648. 'recurrent connections': sum_recurrent,
  649. 'glomerulus':'Glomerulus 1'}, index = [0])
  650. ],
  651. ignore_index=True)

retrieve_neuron_data.ipynb at commit 81b5589, under GPL-3.0 · at the source

Overview

Authors: Jialu Bao1,2, Wesley Alford3, Avinash Khandelwal1, Laurel Walsh1, George Lantz1, Santiago Poncio1, Laia Serratosa Capdevila1, Yervand Azatian1, Brian DePasquale4, David G C Hildebrand5,6, Meg A Younger3, Wei-Chung Allen Lee1,7
  1. Department of Neurobiology, Harvard Medical School, Boston, Massachusetts, United States of America
  2. Molecules, Cells, and Organisms Training Program, Department of Molecular and Cellular Biology, Harvard University, Cambridge, Massachusetts, United States of America
  3. Department of Biology, Boston University, Boston, Massachusetts, United States of America
  4. Department of Biomedical Engineering, Boston University, Boston, Massachusetts, United States of America
  5. Laboratory of Neural Systems, The Rockefeller University, New York, New York, United States of America
  6. Department of Vision Sciences, College of Optometry, University of Houston, Houston, Texas, United States of America
  7. F.M. Kirby Neurobiology Center, Boston Children’s Hospital, Harvard Medical School, Boston, Massachusetts, United States of America
Institutions: Harvard University (United States); Boston University (United States); University of Houston (United States); Rockefeller University (United States); Boston Children's Hospital (United States)
Journal: PLoS biology, volume 24, issue 9, article e3003959
Dates: received 19 January 2026; accepted 5 August 2026; published online 10 September 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1371/journal.pbio.3003959 · PMID 42721124 · PMCID PMC13561330 · OpenAlex W7212152300
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: histology / microscopy (modality), drosophila (organism), cellular / molecular (subfield)
Methods: Statistics, fMRI & imaging
MeSH: Aedes*, Carbon Dioxide*, Olfactory Receptor Neurons*, Synapses*, Animals, Drosophila melanogaster, Female, Microscopy, Electron, Transmission, Odorants, Smell (* major topic)
Topic: Neurobiology and Insect Physiology Research (Cellular and Molecular Neuroscience, Neuroscience), according to OpenAlex
Funding: Alfred P. Sloan Foundation (n/a); National Institute of Neurological Disorders and Stroke (R01NS121874); NCRR NIH HHS (S10 RR028832); National Science Foundation Graduate Research Fellowship Program (n/a); Pew Charitable Trusts (n/a); Searle Scholars Program (n/a); NINDS NIH HHS (R01 NS121874); Wellcome Trust (316808/Z/24/Z); NHLBI NIH HHS (DP2 HL185099); National Heart, Lung, and Blood Institute of the National Institutes of Health (DP2HL185099); HMS Genise Goldenson Award (n/a); Leon Levy Foundation (n/a); Simons Foundation (n/a); Esther A. and Joseph Klingenstein Fund (n/a); Richard and Susan Smith Family Foundation (n/a)
Citations: cited by 1 paper (Europe PMC); 115 references in the paper
Notices: A comment on this paper has been published (42726699, from Europe PMC)

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

License: GPL-3.0
State: the link answers, verified on 26 September 2026
Evidence: files inventoried
Commit: 81b5589a63e067c7e35601ee7ebceb342a082d7b, 16 July 2026
Languages: Jupyter (68), Python (1)
Size: 235 files, 69 scripts
Software Heritage: not archived
Found in: “Data Availability”
Holds: README, license file, environment (model/requirements.txt), 53 notebooks
Not found: CITATION.cff, tests, continuous integration, documentation
Tools: Matplotlib (67 files), seaborn (65 files), NumPy (58 files), pandas (57 files), SciPy (56 files), scikit-posthocs (51 files), statsmodels (37 files), scikit-learn (5 files), Scanpy (2 files)
Availability: 1 check, the latest on 26 September 2026: the link answers
  • 26 September 2026: the link answers
71 files

Zenodo 21403889

License: GPL-3.0
State: the link answers, verified on 26 September 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: “Data Availability”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Matplotlib (67 files), seaborn (65 files), NumPy (58 files), pandas (57 files), SciPy (56 files), scikit-posthocs (51 files), statsmodels (37 files), scikit-learn (5 files), Scanpy (2 files)
Availability: 1 check, the latest on 26 September 2026: the link answers (HTTP 200)
  • 26 September 2026: the link answers (HTTP 200)
71 files

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://doi.org/10.60533/boss-2025-gcyr. Data and code are also available at: https://github.com/htem/aedes_public and https://doi.org/10.5281/zenodo.21403889.

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://doi.org/10.1371/journal.pbio.3003959

BibTeX

@article{bao2026recurrent,
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/journal.pbio.3003959},
url = {https://doi.org/10.1371/journal.pbio.3003959},
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/09/10
VL - 24
IS - 9
SP - e3003959
SN - 1544-9173
PB - PLOS
DO - 10.1371/journal.pbio.3003959
UR - https://doi.org/10.1371/journal.pbio.3003959
LA - en
ER -

CSL-JSON

{
"id": "10.1371/journal.pbio.3003959",
"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": "PLoS Biol",
"volume": "24",
"issue": "9",
"page": "e3003959",
"DOI": "10.1371/journal.pbio.3003959",
"PMID": "42721124",
"PMCID": "PMC13561330",
"ISSN": "1544-9173",
"publisher": "PLOS",
"URL": "https://doi.org/10.1371/journal.pbio.3003959",
"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 neuroscience
In 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: Nature
In common: seaborn, scikit-learn, pandas, 3 other tools, drosophila, 17 references, author Wei-Chung Allen Lee
[3] doi:10.1126/sciadv.aeg3535 [code]
Undoing of firing rate adaptation enables invariant population codes.
Journal: Science advances
In common: scikit-learn, SciPy, Matplotlib, 1 other tool, cellular / molecular, 9 references
[4] doi:10.1038/s41467-026-76682-2 [code]
Odorant receptor coexpression and multi-expression in the dengue mosquito.
Journal: Nature communications
In common: NumPy, drosophila, cellular / molecular, 9 references
[5] 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: iScience
In common: statsmodels, seaborn, pandas, 3 other tools, drosophila, 7 references
[6] doi:10.1371/journal.pcbi.1014657 [code]
Population morphology implies a common developmental blueprint for Drosophila motion detectors.
Journal: PLoS computational biology
In common: statsmodels, seaborn, scikit-learn, 4 other tools, drosophila, 5 references
[7] 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: eLife
In common: scikit-posthocs, seaborn, scikit-learn, 4 other tools, drosophila, cellular / molecular, 3 references
[8] 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 biology
In common: drosophila, cellular / molecular, 7 references
[9] 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 neuroscience
In common: seaborn, scikit-learn, pandas, 3 other tools, histology / microscopy, 4 references
[10] doi:10.7554/elife.96084 [code]
Organization of circuits linking descending input to motor output in the &lt;i&gt;Drosophila&lt;/i&gt; Male Adult Nerve Cord connectome.
Journal: eLife
In common: drosophila, 7 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.

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.