OSCR

Designer indicators for two-photon recording of subthreshold voltage dynamics.

Code ↔ Paper

5 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 5 matches
  1. [1] § Methods › JEDI3hyp optical tracking of brain state in the mouse cortex › Pupil phase binning: Δ2–10-Hz Hilbert transform amplitude ↔ vip-som/pupil_phase_binning.py, lines 338–392 · score 0.86 · Hamming bandpass filter, Hilbert transform, phase binned, 0.1–1 Hz, pupil phase, 2–10
  2. [2] § Methods › JEDI3hyp optical tracking of brain state in the mouse cortex › Pupil phase binning: fluorescence response amplitude ↔ vip-som/pupil_phase_binning.py, lines 35–63 · score 0.68 · pupil phase, low pass filter, fluorescence traces, Hamming, AOD, amplitude
  3. [3] § Methods › JEDI3hyp optical tracking of brain state in the mouse cortex › Pupil phase binning: fluorescence response amplitude ↔ vip-som/pupil_phase_binning.py, lines 66–139 · score 0.59 · phase binned fluorescence, pupil period, selective, constriction, dilation, amplitude
  4. [4] § Methods › JEDI3hyp optical tracking of brain state in the mouse cortex › Preprocessing of voltage imaging data ↔ jedi3_reso_meso.py, lines 65–153 · score 0.58 · segmented masks, motion correction, Somatodendritic, somatic, field, scans
  5. [5] § Methods › JEDI3hyp optical tracking of brain state in the mouse cortex › Pupil phase binning: fluorescence response amplitude ↔ vip-som/pupil_phase_binning.py, lines 463–480 · score 0.57 · constriction medians, constriction period, binned, pupil, phase, dilation

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

Python · 626 lines · 34 KB · no license · 4 matches

  1. import psth_functions
  2. from pipeline import aod
  3. import shared
  4. import numpy as np
  5. import scipy.stats as stats
  6. import datajoint as dj
  7. import scipy.signal as signal
  8. import clocktools as ct
  9. import warnings
  10. with warnings.catch_warnings():
  11. warnings.simplefilter('ignore')
  12. pupil = dj.create_virtual_module(module_name = 'pupil', schema_name = 'pipeline_eye')
  13. treadmill = dj.create_virtual_module(module_name = 'treadmill', schema_name = 'pipeline_treadmill')
  14. # pupilphasebins5 has 20s rolling median data
  15. schema = dj.schema('rob_pupilphasebins5', locals(), create_tables=True)
  16. @schema
  17. class SomaArea(dj.Computed):
  18. definition = """ # computes area of somata
  19. -> aod.Fluorescence.Trace
  20. ---
  21. area_um2 : float # Area in microns**2
  22. """
  23. def make(self, key):
  24. print(key)
  25. pixels = (aod.Segmentation.Mask & key).fetch1('pixels')
  26. n_pixels = len(pixels)
  27. um_h, px_h, um_w, px_w = (aod.ScanInfo.ROI & key).fetch1('um_height', 'px_height', 'um_width', 'px_width')
  28. area_um2 = um_h/px_h * um_w/px_w * n_pixels
  29. self.insert1({**key, 'area_um2': area_um2})
  30. @schema
  31. class NormedTraceStats(dj.Computed):
  32. definition = """ # statistics on normalized trace
  33. -> aod.Fluorescence.Trace
  34. ---
  35. cv : float # coefficient of variation
  36. tv : float # total variation
  37. """
  38. def make(self, key):
  39. fluorescence_filter_method = "5Hz Hamming Lowpass"
  40. print(key)
  41. ## Fetching pipe and basic scan information
  42. pipe = psth_functions.fetch_pipe(key)
  43. scan_times = psth_functions.get_fluorescence_times(key, pipe)
  44. fps = 1 / np.median(np.diff(scan_times))
  45. # Fetching fluorescence trace, making a copy to process separately into 2-10 Hz Hilbert transform amplitude. Original trace will be low-pass filtered & binned
  46. trace = -(pipe.Fluorescence.Trace & key).fetch1('trace')
  47. trace_copy = trace.copy()
  48. # Basic processing of fluorescence trace
  49. filter_table_row = (shared.FilterMethod & f'filter_method = "{fluorescence_filter_method}"')
  50. trace = filter_table_row.run_filter_with_renan(signal=trace, signal_freq=fps)
  51. trace = psth_functions.normalize_dFF(trace, fps)
  52. cv = stats.variation(trace)
  53. tv = sum(abs(np.diff(trace)))/((len(trace)-1)*(np.max(trace)-np.min(trace)))
  54. self.insert1({**key, 'cv': cv, 'tv': tv})
  55. @schema
  56. class PupilPhaseBinsBeta(dj.Computed):
  57. definition = """ #
  58. -> aod.Fluorescence.Trace
  59. -> shared.FilterMethod
  60. ---
  61. phase_bin_edges : blob # An arrray containing the pupil phase bin edges
  62. pupil_radius_avg : mediumblob # an array containing the averaged pupil phase aligned 0.1-1 Hz filtered pupil radius
  63. pupil_phase_avg : mediumblob # an array containing the averaged pupil phase aligned 0.1-1 Hz filtered pupil phase
  64. fluorescence_avg : mediumblob # an array containing the averaged pupil phase aligned filtered fluorescence
  65. hilbert_phase_avg : mediumblob # an array containing the averaged pupil phase aligned filtered (0.1-1 Hz) 2-10 Hz Hilbert
  66. treadmill_avg : mediumblob # an array containing the averaged pupil phase aligned treadmill trace
  67. mean_dilation_minus_constriction : float # mean of dilation period fluorescences minus constriction fluorescences
  68. median_dilation_minus_constriction : float # median of dilation period fluorescences minus constriction fluorescences
  69. preferred_direction=NULL : varchar(256) # preferred direction of averaged pupil-phase aligned binned fluorescence
  70. direction_selectivity_pvalue=NULL : varchar(256) # preferred direction of averaged pupil-phase aligned binned fluorescence
  71. preferred_phase=NULL : varchar(256) # preferred phase of averaged pupil-phase aligned binned fluorescence
  72. pupil_period_nums : int # Number of pupil periods in the PSTH
  73. """
  74. class PeriodFragments(dj.Part):
  75. definition = """#
  76. -> PupilPhaseBinsBeta
  77. period_idx : int # period_idx obtained from pupil.PupilPeriods.DilationConstriction table
  78. period_type : enum('dilation', 'constriction') # pupil period type
  79. ---
  80. pupil_radius_bin_avg : mediumblob # pupil radius binned from -pi to 0 for dilation periods (period_delta>0) or 0 to pi for constriction periods (period_delta<0)
  81. pupil_phase_bin_avg : mediumblob # pupil phase binned from -pi to 0 for dilation periods (period_delta>0) or 0 to pi for constriction periods (period_delta<0)
  82. fluorescence_bin_avg : mediumblob # trace fluorescence values within this pupil period *binned to pupil phase*
  83. hilbert_ampl_bin_avg : mediumblob # filtered (0.1-1 Hz) 2-10 Hz Hilbert transform amplitude values within this pupil period *binned to pupil phase*
  84. treadmill_bin_avg : mediumblob # filtered (0.1-1 Hz) 2-10 Hz Hilbert transform amplitude values within this pupil period *binned to pupil phase*
  85. pupil_radius_fragment : mediumblob # values of pupil_radius within this pupil periods *time*
  86. fluorescence_fragment : mediumblob # values of fluorescence_trace within this pupil periods *time*
  87. hilbert_phase_fragment : mediumblob # values of hilbert_phase within this pupil periods *time*
  88. treadmill_fragment : mediumblob # values of treadmill trace within this pupil periods *time*
  89. trace_mean : float # fluorescence trace mean within this pupil periods *time*
  90. trace_max : float # fluorescence trace max within this pupil periods *time*
  91. trace_min : float # fluorescence trace min within this pupil periods *time*
  92. is_running=NULL : boolean # boolean value declaring whether this is a running period #within this current make function all running periods are discarded. currently an arbirtrary attribute
  93. """
  94. #@property
  95. #def key_source(self):
  96. # return (mario_dendrites.Cell.Compartment & dj.Not("compartment_type='dead_pixels'"))
  97. # def directionality(key):
  98. # mask_keys = (mario_dendrites.Cell.Compartment & key & dj.Not('compartment_type="dead_pixels"')).fetch('KEY')
  99. # #mask_keys = (mario_dendrites.PupilPhaseBins & mask_keys).fetch('KEY')
  100. # for i, mask_key in enumerate(mask_keys):
  101. # print(mask_key)
  102. # if len((mario_dendrites.PupilPhaseBins.Binned & mask_key & 'pupil_period_type="dilation"').fetch('fluorescence_bins')) == 0:
  103. # break
  104. # dilation_fluorescence_avg = np.nanmean(list((mario_dendrites.PupilPhaseBins.Binned & mask_key & 'pupil_period_type="dilation"').fetch('fluorescence_bins')))
  105. # constriction_fluorescence_avg = np.nanmean(list((mario_dendrites.PupilPhaseBins.Binned & mask_key & 'pupil_period_type="constriction"').fetch('fluorescence_bins')))
  106. # print(dilation_fluorescence_avg, constriction_fluorescence_avg)
  107. # if dilation_fluorescence_avg > constriction_fluorescence_avg:
  108. # mod_directionality = 'positive'
  109. # elif dilation_fluorescence_avg < constriction_fluorescence_avg:
  110. # mod_directionality = 'negative'
  111. # mask_key['directionality'] = mod_directionality
  112. # mask_key['fluorescence_dilation_avg'] = dilation_fluorescence_avg
  113. # mask_key['fluorescence_constriction_avg'] = constriction_fluorescence_avg
  114. # mario_dendrites.PupilPhaseBins.ModulationDirectionality.insert1(mask_key, skip_duplicates=True)
  115. # #fluorescence_avg = psth_functions.baseline([fluorescence_avg])
  116. # #fluorescence_avg = fluorescence_avg[0]
  117. def _rolling_average(array, window_size):
  118. # Function to calculate moving average using numpy
  119. array = np.append(array, array[-window_size:])
  120. i = 0
  121. # Initialize an empty list to store moving averages
  122. moving_averages = []
  123. # Loop through the array t o
  124. #consider every window of size 3
  125. while i < len(array)-window_size:
  126. # Calculate the average of current window
  127. window_average = np.sum(array[
  128. i:i+window_size]) / window_size
  129. # Store the average of current
  130. # window in moving average list
  131. moving_averages.append(window_average)
  132. # Shift window to right by one position
  133. i += 1
  134. return moving_averages
  135. # def plot(key, attribute, moving_avg):
  136. # file_text = f"{key['animal_id']-key['session']-key['scan_idx']}_pupil_phased_fluorescence.png"
  137. # mask_keys = (mario_dendrites.Cell.Compartment & key & dj.Not('compartment_type="dead_pixels"')).fetch('KEY')
  138. # bin_edges = (PupilPhaseBinsBeta & mask_keys[0]).fetch1('phase_bin_edges')
  139. # pupil_radius_avg = (PupilPhaseBinsBeta & mask_keys[0]).fetch1('pupil_radius_avg')
  140. # #print(np.shape(bin_edges))
  141. # pupil_periods_radius_avg_fragments = (PupilPhaseBinsBeta.PeriodFragments & mask_keys[0]).fetch('pupil_radius_bin_avg')
  142. # pupil_periods_radius_sem = stats.sem(list(pupil_periods_radius_avg_fragments), nan_policy='omit')
  143. # #print(np.shape(pupil_periods_radius_sem))
  144. # if len(mask_keys) == 1:
  145. # fig, axes = plt.subplots(2, 1, figsize=(9, 9), facecolor="white", subplot_kw=dict(box_aspect=0.75), sharex=True)
  146. # axis_fontsize = 18
  147. # scale_fontsize = 10
  148. # subplot_fontsize = 10
  149. # xtick_label_size=18
  150. # ytick_label_size=14
  151. # if len(mask_keys) > 1:
  152. # fig, axes = plt.subplots(len(mask_keys)+1, 1, figsize=(10, 30), facecolor="white", subplot_kw=dict(box_aspect=0.75), sharex=True)
  153. # axis_fontsize = 18
  154. # subplot_fontsize = 16
  155. # scale_fontsize = 12
  156. # xtick_label_size=18
  157. # ytick_label_size=14
  158. # axes[0].set_title('Average Filtered Pupil Radius Binned by Phase', fontsize=subplot_fontsize)
  159. # axes[0].set_ylabel("Change in Pupil Radius", fontsize=axis_fontsize)
  160. # axes[0].set_xticks([])
  161. # axes[0].set_yticks([])
  162. # axes[0].axvline(0,color='k')
  163. # #axes[0].axhline(0,color='0.8')
  164. # print(len(bin_edges), len(pupil_radius_avg))
  165. # axes[0].plot(
  166. # bin_edges[:int(len(bin_edges)/2)+1],
  167. # pupil_radius_avg[:int(len(bin_edges)/2)+1],
  168. # color="red",
  169. # label="dilation",
  170. # )
  171. # axes[0].fill_between(
  172. # bin_edges[:int(len(bin_edges)/2)+1],
  173. # pupil_radius_avg[:int(len(bin_edges)/2)+1]
  174. # - pupil_periods_radius_sem[:int(len(bin_edges)/2)+1],
  175. # pupil_radius_avg[:int(len(bin_edges)/2)+1]
  176. # + pupil_periods_radius_sem[:int(len(bin_edges)/2)+1],
  177. # color="red",
  178. # alpha=0.1,
  179. # )
  180. # axes[0].plot(
  181. # bin_edges[int(len(bin_edges)/2):],
  182. # pupil_radius_avg[int(len(bin_edges)/2):],
  183. # color="blue",
  184. # label="constriction",
  185. # )
  186. # axes[0].fill_between(
  187. # bin_edges[int(len(bin_edges)/2):],
  188. # pupil_radius_avg[int(len(bin_edges)/2):]
  189. # - pupil_periods_radius_sem[int(len(bin_edges)/2):],
  190. # pupil_radius_avg[int(len(bin_edges)/2):]
  191. # + pupil_periods_radius_sem[int(len(bin_edges)/2):],
  192. # color="blue",
  193. # alpha=0.1,
  194. # )
  195. # for i, a in enumerate(axes.flatten()):
  196. # a.tick_params(axis='x', which = 'major', labelsize=xtick_label_size)
  197. # a.tick_params(axis='y', which = 'major', labelsize=ytick_label_size)
  198. # if i == 0:
  199. # a.legend(loc='upper right',
  200. # frameon=False,
  201. # fontsize=scale_fontsize
  202. # )
  203. # # elif i>0:
  204. # # a.legend(loc='upper right')
  205. # if attribute == 'hilbert_ampl':
  206. # attribute_type = 'hilbert_phase_avg'
  207. # bin_attribute_type = 'hilbert_ampl_bin_avg'
  208. # attribute_plot_title = '2-10 Hz Hilbert Amplitude'
  209. # y_axis_label = 'Δ 2-10 Hz Hilbert Amplitude'
  210. # baseline=False
  211. # if attribute == 'fluorescence':
  212. # attribute_type = 'fluorescence_avg'
  213. # bin_attribute_type = 'fluorescence_bin_avg'
  214. # attribute_plot_title = '5 Hz Lowpass Fluorescence'
  215. # y_axis_label = '"Fluorescence\n (F_norm)"'
  216. # baseline=True
  217. # axes[1].set_title(f'Average {attribute_plot_title}\n by Pupil Phase Bins', fontsize=subplot_fontsize)
  218. # for i, mask_key in enumerate(mask_keys):
  219. # compartment_type = (mario_dendrites.Cell.Compartment & mask_key).fetch1('compartment_type')
  220. # fluorescence_avg = (mario_dendrites.PupilPhaseBinsBeta & mask_key).fetch1(f'{attribute_type}')
  221. # fluorescence_fragments = (mario_dendrites.PupilPhaseBinsBeta.PeriodFragments & mask_key).fetch(f'{bin_attribute_type}')
  222. # ####
  223. # ####
  224. # fluorescence_sem = stats.sem(list(fluorescence_fragments), nan_policy='omit')
  225. # if moving_avg == False:
  226. # fluorescence_array = (mario_dendrites.PupilPhaseBinsBeta & mask_key).fetch1(f'{attribute_type}')
  227. # if moving_avg == 'sma': #simple moving average of window_size=3
  228. # fluorescence_array = (mario_dendrites.PupilPhaseBinsBeta & mask_key).fetch(f'{attribute_type}')
  229. # fluorescence_avg = np.array(mario_dendrites.PupilPhaseBinsBeta._rolling_average(fluorescence_avg, 3))
  230. # fluorescence_sem = np.array(mario_dendrites.PupilPhaseBinsBeta._rolling_average(fluorescence_sem, 3))
  231. # if baseline == True:
  232. # fluorescence_avg = fluorescence_avg-np.mean(fluorescence_avg)
  233. # ####
  234. # ####
  235. # if compartment_type == 'distal dendrite':
  236. # trace_color = 'forestgreen'
  237. # if compartment_type == 'apical dendrite':
  238. # trace_color = 'lightseagreen'
  239. # if compartment_type == 'soma':
  240. # trace_color = 'coral'
  241. # axes[i+1].set_ylabel(y_axis_label, fontsize=axis_fontsize)
  242. # axes[i+1].axvline(0,color='k')
  243. # if baseline == True or attribute == 'hilbert_ampl':
  244. # axes[i+1].axhline(0,color='0.8')
  245. # axes[i+1].set_xticks([])
  246. # axes[i+1].plot(bin_edges, fluorescence_avg,
  247. # color=trace_color,
  248. # label=compartment_type)
  249. # axes[i+1].legend(loc='lower right',
  250. # frameon=False,
  251. # fontsize=scale_fontsize
  252. # )
  253. # axes[i+1].fill_between(bin_edges,
  254. # fluorescence_avg
  255. # - fluorescence_sem,
  256. # fluorescence_avg
  257. # + fluorescence_sem,
  258. # color=trace_color,
  259. # alpha=0.1,
  260. # )
  261. # axes[i+1].xaxis.set_major_locator(plt.MultipleLocator(np.pi/ 2))
  262. # axes[i+1].xaxis.set_major_formatter(plt.FuncFormatter(psth_functions.multiple_formatter()))
  263. # plt.xlim(-np.pi, np.pi)
  264. # #plt.legend()
  265. # plt.savefig('hi.png')
  266. # plt.show()
  267. # plt.close()
  268. def trace_preprocessing(key, fluorescence_filter_method):
  269. fluorescence_filter_method = "5Hz Hamming Lowpass"
  270. ## Fetching pipe and basic scan information
  271. pipe = psth_functions.fetch_pipe(key)
  272. scan_times = psth_functions.get_fluorescence_times(key, pipe)
  273. fps = 1 / np.median(np.diff(scan_times))
  274. # Fetching fluorescence trace, making a copy to process separately into 2-10 Hz Hilbert transform amplitude. Original trace will be low-pass filtered & binned
  275. trace = -(pipe.Fluorescence.Trace & key).fetch1('trace')
  276. trace_copy = trace.copy()
  277. # Basic processing of fluorescence trace
  278. filter_table_row = (shared.FilterMethod & f'filter_method = "{fluorescence_filter_method}"')
  279. trace = filter_table_row.run_filter_with_renan(signal=trace, signal_freq=fps)
  280. trace = psth_functions.normalize_dFF(trace, fps)
  281. # Basic processing of fluorescence trace into filtered 2-10 Hz Hilbert transform amplitude
  282. hilbert_filt_one = (shared.FilterMethod & 'filter_method = "2 - 10Hz Hamming Bandpass"')
  283. print(hilbert_filt_one)
  284. hilbert_trace = hilbert_filt_one.run_filter_with_renan(signal=trace_copy, signal_freq=fps)
  285. hilbert_trace = np.abs(signal.hilbert(hilbert_trace))
  286. #hilbert_filt_two = (shared.FilterMethod & 'filter_method = "0.1 - 1Hz Hamming Bandpass"')
  287. #hilbert_trace = hilbert_filt_two.run_filter_with_renan(signal=hilbert_trace, signal_freq=fps)
  288. #### behavior preprocessing
  289. radius, pupil_fps = (pupil.ProcessedPupil & key & 'pupil_method_id=1').fetch1('filtered_pupil_radius', 'pupil_sampling_rate')
  290. nan_filter_table_row = (shared.FilterMethod & 'filter_method = "NaN Filler"') # Simply filling in NaNs
  291. radius = nan_filter_table_row.run_filter(signal=radius, signal_freq=pupil_fps)
  292. #####
  293. #####
  294. low_bandpass_filter = (shared.FilterMethod & 'filter_method = "0.1 - 1Hz Hamming Bandpass"') # standard 0.1-1Hz Hamming Lowpass Filter
  295. radius = low_bandpass_filter.run_filter(signal=radius, signal_freq=pupil_fps)
  296. radius_time = (pupil.Eye & key).fetch1('eye_time')
  297. radius = psth_functions.interpolate_to_new_timestamps(radius_time, radius, scan_times)
  298. # computing the hilbert transform of filtered pupil radius and subsequently its phase
  299. radius_hilbert = signal.hilbert(radius)
  300. radius_phase = np.angle(radius_hilbert)
  301. #####
  302. #####
  303. # fetching basic treadmill velocity trace attributes, e.g, sampling rate, treadmill_times, and treadmill velocity values
  304. treadmill_trace, treadmill_time = (treadmill.Treadmill & key).fetch1('treadmill_vel', 'treadmill_time')
  305. # interpolating missing values in pupil radius, otherwise interpolating to new timestamps won't work or won't work well
  306. treadmill_trace = psth_functions.interpolate_nans(treadmill_trace)
  307. treadmill_trace = psth_functions.interpolate_to_new_timestamps(treadmill_time, treadmill_trace, scan_times)
  308. return trace, hilbert_trace, radius, radius_phase, treadmill_trace
  309. def fetch_nonrunning_pupil_periods(key): #, pupil_method_id, run_filter_method, running_method_id): ## arguments to consider having to compute non_running_pupil_periods dictionaries containing frame_idxs across different pupil and running methods
  310. pupil_method_id=1
  311. running_method_id = 1
  312. run_filter_method = '0.5sec Median Filter'
  313. running_period_padding = 3
  314. # fetching pipe and scan_times of particular scan_key field to then appropriately convert pupil_period_onset times to fluorescence frame idxs to then be able to iterate per pupil period across non_running_frame_idxs
  315. pipe = psth_functions.fetch_pipe(key)
  316. scan_times = psth_functions.get_fluorescence_times(key, pipe)
  317. pupil_period_list = []
  318. #fetching all pupil periods and select attributes to make into a list of dictionaries that we'll iterate through and discard ones that fall near or within running periods
  319. period_idx, period_onset, period_offset, period_delta, period_duration = (pupil.PupilPeriods.DilationConstriction & key & f'pupil_method_id={pupil_method_id}' & f'period_offset<{scan_times[-1]}'& 'period_method_id=1').fetch('period_idx', 'period_onset', 'period_offset', 'period_delta', 'period_duration')
  320. start_stop_times_list = [[val[0], val[1]] for val in zip(period_onset, period_offset)]
  321. print('start stop times length:', len(start_stop_times_list))
  322. list_of_pupil_periods_idxs = ct.convert_clocks(key,
  323. start_stop_times_list,
  324. source_format= 'times',
  325. source_type= 'fluorescence-behavior',
  326. target_format= 'indices',
  327. target_type= 'fluorescence-behavior',
  328. drop_single_idx=True,
  329. debug=True)
  330. # creating a dictionary of fetched pupil periods to iterate through shortly
  331. print('pupil_period_idxs length:', len(list_of_pupil_periods_idxs))
  332. list_of_pupil_periods = [{f'period_idx': val[0],
  333. 'period_onset': val[1],
  334. 'period_offset': val[2],
  335. 'period_delta': val[3],
  336. 'period_duration': val[4],
  337. } for val in zip(period_idx, period_onset, period_offset, period_delta, period_duration)]
  338. print('pupil periods length', len(list_of_pupil_periods))
  339. for i, pupil_period in enumerate(list_of_pupil_periods):
  340. pupil_period['period_onset_idx'] = list_of_pupil_periods_idxs[i][0]
  341. pupil_period['period_offset_idx'] = list_of_pupil_periods_idxs[i][-1]
  342. #fetching run_onsets and run_offsets that we'll iterate through individually to check whether all pupil_periods fall within that time frame
  343. run_onsets, run_offsets = (treadmill.Running.Period & dict(key, run_filter_method = f'{run_filter_method}', running_method_id = running_method_id)).fetch('run_onset', 'run_offset')
  344. # iterating through each pupil period & determining which one's fall within running periods to then discard those using a boolean mask
  345. pupil_period_idxs_to_delete = []
  346. for i in range(len(run_onsets)):
  347. run_start=run_onsets[i]-running_period_padding
  348. run_stop=run_offsets[i]+running_period_padding
  349. for j, pupil_period_dict in enumerate(list_of_pupil_periods):
  350. period_onset, period_offset = pupil_period_dict['period_onset'], pupil_period_dict['period_offset']
  351. if period_onset >= run_start and period_offset <= run_stop:
  352. pupil_period_idxs_to_delete.append(j)
  353. # making a boolean mask of len(list_of_pupil_periods) of all True values. Iterating through all pupil_period_idxs_to_delete & making those specific array index values = False
  354. pupil_periods_list_boolean_mask = np.full(len(list_of_pupil_periods), True)
  355. # iterates through pupil period indeces list to remove and modifies boolean mask to make into False values
  356. for pupil_periods_idxs in pupil_period_idxs_to_delete:
  357. pupil_periods_list_boolean_mask[pupil_periods_idxs] = False
  358. pupil_periods_list_boolean_mask[pupil_periods_idxs+1] = False # accounts for open ended indexing, otherwise you would discard all but one period index that falls within running_periods
  359. # passes boolean mask to list of pupil periods to remove pupil periods that fall within running period windows
  360. list_of_pupil_periods = np.array(list_of_pupil_periods)[pupil_periods_list_boolean_mask]
  361. return list_of_pupil_periods
  362. def get_directionality_stats(mean_traces, directions):
  363. mean_traces = np.array(mean_traces)
  364. directions = np.array(directions)
  365. constriction_periods = (directions == 'constriction')
  366. dilation_periods = (directions == 'dilation')
  367. constriction_median = np.median(mean_traces[constriction_periods])
  368. dilation_median = np.median(mean_traces[dilation_periods])
  369. constriction_mean = np.mean(mean_traces[constriction_periods])
  370. dilation_mean = np.mean(mean_traces[dilation_periods])
  371. median_diff = dilation_median - constriction_median
  372. mean_diff = dilation_mean - constriction_mean
  373. if constriction_median > dilation_median:
  374. preferred_direction = 'F(constriction) > F(dilation)'
  375. else:
  376. preferred_direction = 'F(dilation) >= F(constriction)'
  377. pvalue = stats.kruskal(mean_traces[constriction_periods], mean_traces[dilation_periods]).pvalue
  378. return mean_diff, median_diff, preferred_direction, pvalue
  379. def make(self, key):
  380. print(key)
  381. fluorescence_filter_method = "5Hz Hamming Lowpass"
  382. trace, hilbert_trace, radius, radius_phase, treadmill_trace = PupilPhaseBinsBeta.trace_preprocessing(key, fluorescence_filter_method)
  383. non_running_pupil_periods = PupilPhaseBinsBeta.fetch_nonrunning_pupil_periods(key)
  384. ###########
  385. ###########
  386. bin_half_width = np.pi/128
  387. bin_centers = np.linspace(-np.pi+bin_half_width, np.pi-bin_half_width, 65)
  388. bin_edges = np.linspace(-np.pi, np.pi, 65)
  389. period_dict_static_key = {**key,
  390. 'filter_method': fluorescence_filter_method,
  391. }
  392. per_period_dict_static_key = period_dict_static_key.copy()
  393. pupil_period_nums = len(non_running_pupil_periods)
  394. all_period_pupil_radius_bin_avgs = []
  395. all_period_pupil_phase_bin_avgs = []
  396. all_period_fluorescence_bin_avgs = []
  397. all_period_hilbert_ampl_bin_avgs = []
  398. all_period_treadmill_bin_avgs = []
  399. all_periods_keys_list = []
  400. for i, pupil_period in enumerate(non_running_pupil_periods):
  401. period_idx = pupil_period['period_idx']
  402. period_delta = pupil_period['period_delta']
  403. period_onset_idx = pupil_period['period_onset_idx']
  404. period_offset_idx = pupil_period['period_offset_idx']+1
  405. pupil_radius_fragment = radius[period_onset_idx:period_offset_idx]
  406. pupil_phase_fragment = radius_phase[period_onset_idx:period_offset_idx]
  407. fluorescence_fragment = trace[period_onset_idx:period_offset_idx]
  408. hilbert_phase_fragment = hilbert_trace[period_onset_idx:period_offset_idx]
  409. treadmill_fragment = treadmill_trace[period_onset_idx:period_offset_idx]
  410. fluorescence_trace_mean = np.mean(fluorescence_fragment)
  411. fluorescence_trace_max = np.max(fluorescence_fragment)
  412. fluorescence_trace_min = np.min(fluorescence_fragment)
  413. current_period_radius_bin_values = np.zeros(65)
  414. current_period_phase_bin_values = np.zeros(65)
  415. current_period_fluorescence_bin_values = np.zeros(65)
  416. current_period_hilbert_bin_values = np.zeros(65)
  417. current_period_treadmill_bin_values = np.zeros(65)
  418. if period_delta > 0:
  419. period_type = 'dilation'
  420. if period_delta < 0:
  421. period_type = 'constriction'
  422. for bin_idx, bin_center in enumerate(bin_centers):
  423. pupil_mask = np.logical_and(pupil_phase_fragment >= bin_center - bin_half_width , pupil_phase_fragment < bin_center + bin_half_width)
  424. if len(pupil_mask) != len(fluorescence_fragment):
  425. print(f'mismatch in fluorescence_fragment & boolean mask: {len(pupil_mask)-len(fluorescence_fragment)}')
  426. if np.abs(len(pupil_mask)-len(fluorescence_fragment)) < 5:
  427. print(f'trimming the pupil_mask & trace fragments')
  428. pupil_mask = pupil_mask[:len(fluorescence_fragment)]
  429. pupil_radius_fragment = pupil_radius_fragment[:len(fluorescence_fragment)]
  430. pupil_phase_fragment = pupil_phase_fragment[:len(fluorescence_fragment)]
  431. fluorescence_fragment = fluorescence_fragment[:len(fluorescence_fragment)]
  432. hilbert_phase_fragment = hilbert_phase_fragment[:len(fluorescence_fragment)]
  433. treadmill_fragment = treadmill_fragment[:len(fluorescence_fragment)]
  434. current_bin_radius_avg = np.nanmean(pupil_radius_fragment[pupil_mask])
  435. current_bin_phase_avg = np.nanmean(pupil_phase_fragment[pupil_mask])
  436. current_bin_fluorescence_avg = np.nanmean(fluorescence_fragment[pupil_mask])
  437. current_bin_hilbert_avg = np.nanmean(hilbert_phase_fragment[pupil_mask])
  438. current_bin_treadmill_avg = np.nanmean(treadmill_fragment[pupil_mask])
  439. current_period_radius_bin_values[bin_idx] = current_bin_radius_avg
  440. current_period_phase_bin_values[bin_idx] = current_bin_phase_avg
  441. current_period_fluorescence_bin_values[bin_idx] = current_bin_fluorescence_avg
  442. current_period_hilbert_bin_values[bin_idx] = current_bin_hilbert_avg
  443. current_period_treadmill_bin_values[bin_idx] = current_bin_treadmill_avg
  444. current_period_key = {**per_period_dict_static_key,
  445. 'period_idx': period_idx,
  446. 'period_type': period_type,
  447. 'pupil_radius_bin_avg': current_period_radius_bin_values,
  448. 'pupil_phase_bin_avg': current_period_phase_bin_values,
  449. 'fluorescence_bin_avg': current_period_fluorescence_bin_values,
  450. 'hilbert_ampl_bin_avg': current_period_hilbert_bin_values,
  451. 'treadmill_bin_avg': current_period_treadmill_bin_values,
  452. 'pupil_radius_fragment' : pupil_radius_fragment,
  453. 'fluorescence_fragment' : fluorescence_fragment,
  454. 'hilbert_phase_fragment': hilbert_phase_fragment,
  455. 'treadmill_fragment': treadmill_fragment,
  456. 'trace_mean': fluorescence_trace_mean,
  457. 'trace_max' : fluorescence_trace_max,
  458. 'trace_min' : fluorescence_trace_min,
  459. }
  460. all_period_pupil_radius_bin_avgs.append(current_period_radius_bin_values)
  461. all_period_pupil_phase_bin_avgs.append(current_period_phase_bin_values)
  462. all_period_fluorescence_bin_avgs.append(current_period_fluorescence_bin_values)
  463. all_period_hilbert_ampl_bin_avgs.append(current_period_hilbert_bin_values)
  464. all_period_treadmill_bin_avgs.append(current_period_treadmill_bin_values)
  465. all_periods_keys_list.append(current_period_key)
  466. #print(f"shape of radius average array for all periods. should be (n_periods, n_bins) {np.reshape(all_periods_radius_list, (len(list_of_pupil_periods), len(period_bin_edges)))}")
  467. phase_binned_radius_all_periods_avg = np.nanmean(all_period_pupil_radius_bin_avgs, axis=0)
  468. phase_binned_phase_all_periods_avg = np.nanmean(all_period_pupil_phase_bin_avgs, axis=0)
  469. phase_binned_fluorescence_all_periods_avg = np.nanmean(all_period_fluorescence_bin_avgs, axis=0)
  470. phase_binned_fluorescence_hilbert_all_periods_avg = np.nanmean(all_period_hilbert_ampl_bin_avgs, axis=0)
  471. phase_binned_treadmill_all_periods_avg = np.nanmean(all_period_treadmill_bin_avgs, axis=0)
  472. all_trace_means = [k['trace_mean'] for k in all_periods_keys_list]
  473. all_pupil_directions = [k['period_type'] for k in all_periods_keys_list]
  474. mean_diff, median_diff, preferred_direction, direction_selectivity_pvalue = PupilPhaseBinsBeta.get_directionality_stats(all_trace_means, all_pupil_directions)
  475. period_dict_static_key = {**period_dict_static_key,
  476. 'mean_dilation_minus_constriction': mean_diff,
  477. 'median_dilation_minus_constriction': median_diff,
  478. 'preferred_direction': preferred_direction,
  479. 'direction_selectivity_pvalue': direction_selectivity_pvalue,
  480. 'phase_bin_edges' : bin_edges,
  481. 'pupil_radius_avg' : phase_binned_radius_all_periods_avg,
  482. 'pupil_phase_avg' : phase_binned_phase_all_periods_avg,
  483. 'fluorescence_avg' : phase_binned_fluorescence_all_periods_avg,
  484. 'hilbert_phase_avg': phase_binned_fluorescence_hilbert_all_periods_avg,
  485. 'treadmill_avg' : phase_binned_treadmill_all_periods_avg,
  486. 'pupil_period_nums': pupil_period_nums,
  487. }
  488. print(period_dict_static_key.keys())
  489. print(all_periods_keys_list[0].keys())
  490. self.insert1(period_dict_static_key)
  491. self.PeriodFragments.insert(all_periods_keys_list)

pupil_phase_binning.py at commit 80deb0b, no license · at the source

Overview

Authors: Michelle A Land1, Mario Galdamez1, Vincent Villette2, Jun Zhu3, Xiaoyu Lu1,4, Mate Marosi5, Shuyuan Yang6, Gregory Foran1, Alex J McDonald1, Xiaoyu Dong1, Elsayed Zaabout1, Haixin Liu1, Zhuohe Liu4, Kevin L Colbert1, Shujuan Lai1, Matthew Shorey1, Anthony S G Lourdiane7, Annick Ayon2, Jonathan Bradley2, Caroline Mailhes-Hamon2
and 14 other authorsRyan G Natan3, Jian Zhong8, Ryan Kroeger1, Robert G Law1, Noura Hakam1, Cameron L Smith1, Ming Hu1, Shanii Tabb5, Brice Bathellier7, Barna Dudok1,5, Na Ji3,8,9,10, Laurent Bourdieu2, Jacob Reimer1,11,12, François St-Pierre1,4,11,12,13
13 affiliations
  1. Department of Neuroscience, Baylor College of Medicine, Houston, TX USA
  2. Institut de Biologie de l’Ecole Normale Supérieure (IBENS), Ecole Normale Supérieure, CNRS, INSERM, Université PSL, Paris, France
  3. Department of Neuroscience, University of California, Berkeley, Berkeley, CA USA
  4. Systems, Synthetic and Physical Biology program, Rice University, Houston, TX USA
  5. Department of Neurology, Baylor College of Medicine, Houston, TX USA
  6. Department of Chemical and Biomolecular Engineering, Rice University, Houston, TX USA
  7. Université Paris Cité, Institut Pasteur, AP-HP, INSERM, CNRS, Fondation Pour l’Audition, Institut de l’Audition, IHU reConnect, Paris, France
  8. Department of Physics, University of California, Berkeley, Berkeley, CA USA
  9. Helen Wills Neuroscience Institute, University of California, Berkeley, Berkeley, CA USA
  10. Molecular Biophysics and Integrated Bioimaging Division, Lawrence Berkeley National Laboratory, Berkeley, CA USA
  11. Department of Electrical and Computer Engineering, Rice University, Houston, TX USA
  12. Center for Neuroscience and Artificial Intelligence, Baylor College of Medicine, Houston, TX USA
  13. Department of Biochemistry and Molecular Pharmacology, Baylor College of Medicine, Houston, TX USA
Journal: Nature methods, volume 23, issue 5, pages 986-997
Dates: received 21 January 2025; accepted 24 February 2026; published online 15 April 2026; in print 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1038/s41592-026-03043-8 · PMID 41986688 · PMCID PMC13577304 · OpenAlex W7154477798
Open access: hybrid, a free copy (OpenAlex)
Status: code verified
Categories: histology / microscopy (modality), optical imaging (calcium, voltage, 2-photon) (modality), mouse (organism)
Methods: Spectral & time-frequency, Connectivity, Statistics, Machine learning, Preprocessing, Evoked potentials, fMRI & imaging, Single-unit activity, calcium imaging, Smoothing, state filtering, decompositions, Physiology & signal measures
Keywords: Fluorescent proteins, Fluorescence imaging, Multiphoton microscopy, High-throughput screening
MeSH: Microscopy, Fluorescence, Multiphoton*, Neurons*, Animals, Brain, Hippocampus, Interneurons, Mice, Photons (* major topic)
Topic: Neural dynamics and brain function (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Funding: NSF | Directorate for Biological Sciences (1707359); Welch Foundation (Q-2016-20220331); NIBIB NIH HHS (R01 EB027145, R01 EB032854); U.S. Department of Health & Human Services | National Institutes of Health (NIH) (R01EB027145, NS126115, U01NS118300, U01NS113294); NINDS NIH HHS (U01 NS113294, R00 NS117795, U01 NS137449, R01 NS128901, R34 NS132045, U01 NS118300, UF1 NS107696, RF1 NS128901, U01 NS118288, R01 NS136027, U01 NS133971, T32 NS126115); U.S. Department of Health &amp; Human Services | National Institutes of Health (U01NS113294, NS126115, U01NS118300, R01EB027145)
Citations: cited by 2 papers (Europe PMC); 87 references in the paper

Abstract

Subthreshold voltage dynamics are essential for neuronal information integration, yet they remain technically challenging to measure in vivo. While genetically encoded voltage indicators are emerging as powerful tools for voltage recording, they lack the sensitivity to detect millivolt-scale subthreshold fluctuations with two-photon microscopy—the method of choice for deep-tissue recording. To overcome this limitation, we engineered two genetically encoded voltage indicators, JEDI3sub and JEDI3hyp, with enhanced subthreshold voltage detection under two-photon excitation. In the mouse brain, JEDI3sub enabled simultaneous tracking of subthreshold optical tuning from over 100 cells simultaneously, while JEDI3hyp captured subthreshold dynamics associated with sharp-wave ripples in hippocampal PV+ interneurons. Moreover, JEDI3hyp supported prolonged imaging of brain-state-dependent, millivolt-scale subthreshold voltage changes across deep-layer somas, fine dendritic structures and diverse cell types. By enabling sensitive reporting of subthreshold voltage dynamics, JEDI3 indicators open previously unexplored avenues for dissecting neural information processing in health and disease.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repository

Its files are read in the Code ↔ Paper reader above, with 5 matches between paragraphs and lines of code.

reimerlab/jedi3-paper

License: none: the authors keep all their rights
State: the link answers, verified on 29 September 2026
Evidence: files inventoried
Commit: 80deb0b9c79ca92db257d5f84ed8d433ab4fe8e0, 13 February 2026
Languages: Python (8), Jupyter (2)
Size: 11 files, 10 scripts
Software Heritage: not archived
Found in: the text, “Preprocessing of voltage imaging data”
Holds: README, 2 notebooks
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NumPy (8 files), SciPy (8 files), Matplotlib (5 files), pandas (5 files), seaborn (2 files), Plotly (1 file)
Availability: 1 check, the latest on 29 September 2026: the link answers
  • 29 September 2026: the link answers
11 files

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:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 10 scripts, each with its path and the digest of its content;
  • 5 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

Datasets cited

Data availability

The GenBank accession numbers are https://www.ncbi.nlm.nih.gov/nuccore/PX122673 for JEDI3sub and https://www.ncbi.nlm.nih.gov/nuccore/PX122674 for JEDI3hyp. Plasmids used in this work or that are useful for other applications are available on Addgene (ID numbers 246616–246641). Raw data for main, Extended Data and Supplementary Figures have been uploaded to Zenodo (https://doi.org/10.5281/zenodo.17537897)87. Data that are too large to upload will be made available upon request. Source data are provided with this paper.

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, 29 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 34 authors, 4 keywords, 8 MeSH terms, 6 funders, 87 references, 5 RRIDs.

Cite

This paper

Land, M. A., Galdamez, M., Villette, V., Zhu, J., Lu, X., Marosi, M., Yang, S., Foran, G., McDonald, A. J., Dong, X., Zaabout, E., Liu, H., Liu, Z., Colbert, K. L., Lai, S., Shorey, M., Lourdiane, A. S. G., Ayon, A., Bradley, J., . . . St-Pierre, F. (2026). Designer indicators for two-photon recording of subthreshold voltage dynamics. Nature methods, 23(5), 986-997. https://doi.org/10.1038/s41592-026-03043-8

BibTeX

@article{land2026designer,
author = {Land, Michelle A and Galdamez, Mario and Villette, Vincent and Zhu, Jun and Lu, Xiaoyu and Marosi, Mate and Yang, Shuyuan and Foran, Gregory and McDonald, Alex J and Dong, Xiaoyu and Zaabout, Elsayed and Liu, Haixin and Liu, Zhuohe and Colbert, Kevin L and Lai, Shujuan and Shorey, Matthew and Lourdiane, Anthony S G and Ayon, Annick and Bradley, Jonathan and Mailhes-Hamon, Caroline and Natan, Ryan G and Zhong, Jian and Kroeger, Ryan and Law, Robert G and Hakam, Noura and Smith, Cameron L and Hu, Ming and Tabb, Shanii and Bathellier, Brice and Dudok, Barna and Ji, Na and Bourdieu, Laurent and Reimer, Jacob and St-Pierre, François},
title = {{Designer indicators for two-photon recording of subthreshold voltage dynamics}},
journal = {Nature methods},
year = {2026},
month = apr,
volume = {23},
number = {5},
pages = {986--997},
publisher = {Nature Portfolio},
issn = {1548-7091},
doi = {10.1038/s41592-026-03043-8},
url = {https://doi.org/10.1038/s41592-026-03043-8},
pmid = {41986688},
pmcid = {PMC13577304}
}

RIS

TY - JOUR
AU - Land, Michelle A
AU - Galdamez, Mario
AU - Villette, Vincent
AU - Zhu, Jun
AU - Lu, Xiaoyu
AU - Marosi, Mate
AU - Yang, Shuyuan
AU - Foran, Gregory
AU - McDonald, Alex J
AU - Dong, Xiaoyu
AU - Zaabout, Elsayed
AU - Liu, Haixin
AU - Liu, Zhuohe
AU - Colbert, Kevin L
AU - Lai, Shujuan
AU - Shorey, Matthew
AU - Lourdiane, Anthony S G
AU - Ayon, Annick
AU - Bradley, Jonathan
AU - Mailhes-Hamon, Caroline
AU - Natan, Ryan G
AU - Zhong, Jian
AU - Kroeger, Ryan
AU - Law, Robert G
AU - Hakam, Noura
AU - Smith, Cameron L
AU - Hu, Ming
AU - Tabb, Shanii
AU - Bathellier, Brice
AU - Dudok, Barna
AU - Ji, Na
AU - Bourdieu, Laurent
AU - Reimer, Jacob
AU - St-Pierre, François
TI - Designer indicators for two-photon recording of subthreshold voltage dynamics
T2 - Nature methods
J2 - Nat Methods
PY - 2026
DA - 2026/04/15
VL - 23
IS - 5
SP - 986
EP - 997
SN - 1548-7091
PB - Nature Portfolio
DO - 10.1038/s41592-026-03043-8
UR - https://doi.org/10.1038/s41592-026-03043-8
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s41592-026-03043-8",
"type": "article-journal",
"title": "Designer indicators for two-photon recording of subthreshold voltage dynamics",
"container-title": "Nature methods",
"author": [
{
"family": "Land",
"given": "Michelle A"
},
{
"family": "Galdamez",
"given": "Mario"
},
{
"family": "Villette",
"given": "Vincent"
},
{
"family": "Zhu",
"given": "Jun"
},
{
"family": "Lu",
"given": "Xiaoyu"
},
{
"family": "Marosi",
"given": "Mate"
},
{
"family": "Yang",
"given": "Shuyuan"
},
{
"family": "Foran",
"given": "Gregory"
},
{
"family": "McDonald",
"given": "Alex J"
},
{
"family": "Dong",
"given": "Xiaoyu"
},
{
"family": "Zaabout",
"given": "Elsayed"
},
{
"family": "Liu",
"given": "Haixin"
},
{
"family": "Liu",
"given": "Zhuohe"
},
{
"family": "Colbert",
"given": "Kevin L"
},
{
"family": "Lai",
"given": "Shujuan"
},
{
"family": "Shorey",
"given": "Matthew"
},
{
"family": "Lourdiane",
"given": "Anthony S G"
},
{
"family": "Ayon",
"given": "Annick"
},
{
"family": "Bradley",
"given": "Jonathan"
},
{
"family": "Mailhes-Hamon",
"given": "Caroline"
},
{
"family": "Natan",
"given": "Ryan G"
},
{
"family": "Zhong",
"given": "Jian"
},
{
"family": "Kroeger",
"given": "Ryan"
},
{
"family": "Law",
"given": "Robert G"
},
{
"family": "Hakam",
"given": "Noura"
},
{
"family": "Smith",
"given": "Cameron L"
},
{
"family": "Hu",
"given": "Ming"
},
{
"family": "Tabb",
"given": "Shanii"
},
{
"family": "Bathellier",
"given": "Brice"
},
{
"family": "Dudok",
"given": "Barna"
},
{
"family": "Ji",
"given": "Na"
},
{
"family": "Bourdieu",
"given": "Laurent"
},
{
"family": "Reimer",
"given": "Jacob"
},
{
"family": "St-Pierre",
"given": "François"
}
],
"container-title-short": "Nat Methods",
"volume": "23",
"issue": "5",
"page": "986-997",
"DOI": "10.1038/s41592-026-03043-8",
"PMID": "41986688",
"PMCID": "PMC13577304",
"ISSN": "1548-7091",
"publisher": "Nature Portfolio",
"URL": "https://doi.org/10.1038/s41592-026-03043-8",
"language": "en",
"issued": {
"date-parts": [
[
2026,
4,
15
]
]
}
}

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.1016/j.isci.2026.117010 [code]
Deep learning-assisted mapping of dendritic spines using sequential 2D two-photon calcium imaging.
Journal: iScience
In common: seaborn, pandas, SciPy, 2 other tools, optical imaging (calcium, voltage, 2-photon), histology / microscopy, 4 references
[2] doi:10.1038/s41467-026-71667-7
Behavioural states control binocular vision through input-specific mechanisms.
Journal: Nature communications
In common: mouse, 7 references
[3] doi:10.7554/elife.108352 [code]
Analysis of dendritic input currents during place field dynamics.
Journal: eLife
In common: pandas, Matplotlib, NumPy, 5 references
[4] doi:10.1038/s41586-026-10907-8 [code]
Procognitive restoration of PV neuron plasticity in neurodevelopmental disorders.
Journal: Nature
In common: pandas, SciPy, Matplotlib, 1 other tool, 4 references
[5] doi:10.1111/ejn.70582 [code]
Multifiber Array-Based Photometry System for Multiregional Functional Mapping in the Mouse Brain.
Journal: The European journal of neuroscience
In common: pandas, SciPy, Matplotlib, 1 other tool, optical imaging (calcium, voltage, 2-photon), mouse, 4 references
[6] 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: Plotly, seaborn, pandas, 3 other tools, histology / microscopy, mouse, 2 references
[7] doi:10.1016/j.xpro.2026.104678 [code]
Protocol for longitudinal two-photon calcium imaging and holographic optogenetic manipulation to investigate memory in mice.
Journal: STAR protocols
In common: seaborn, pandas, SciPy, 2 other tools, optical imaging (calcium, voltage, 2-photon), histology / microscopy, mouse, 2 references
[8] doi:10.1038/s41592-026-03179-7 [code]
Voltage imaging of neurons distributed across entire brains of larval zebrafish.
Journal: Nature methods
In common: SciPy, Matplotlib, NumPy, optical imaging (calcium, voltage, 2-photon), histology / microscopy, 4 references
[9] doi:10.1038/s41467-026-73389-2 [code]
Physics-informed multi-encoder adaptive optics enables rapid aberration correction for intravital microscopy of deep complex tissue.
Journal: Nature communications
In common: SciPy, Matplotlib, NumPy, optical imaging (calcium, voltage, 2-photon), histology / microscopy, mouse, 3 references
[10] doi:10.1016/j.crmeth.2026.101421 [code]
EthoPy provides an accessible platform for reproducible behavioral neuroscience.
Journal: Cell reports methods
In common: Plotly, seaborn, pandas, 3 other tools, mouse, 2 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.