OSCR

Quantifying electrostatic control of docking and binding energetics in functional Cx36 gap junctions.

Code ↔ Paper

6 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 6 matches
  1. [1] § Results › ESI number at the E2–E2 interface governs GJ formation ↔ cx36_mut_corr.ipynb, lines 1–57 · score 0.82 · K238Q, K238A, K238E, E241A, E230K, E239K
  2. [2] § Results › ESI number at the E2–E2 interface governs GJ formation ↔ cx36_mut_corr.ipynb, lines 1–57 · score 0.82 · K238Q, K238A, K238E, E241A, E230K, E239K
  3. [3] § Results › E241K-containing variants could not form functional GJs ↔ cx36_mut_corr.ipynb, lines 1–57 · score 0.70 · K238E, E241A, E230K, E239K, E241K, hetero
  4. [4] § Results › E241K-containing variants could not form functional GJs ↔ cx36_mut_corr.ipynb, lines 1–57 · score 0.70 · K238E, E241A, E230K, E239K, E241K, hetero
  5. [5] § Methods › Free energy calculation on designed Cx36 variants ↔ cx36_het_dock.ipynb, lines 39–69 · score 0.61 · van der Waals, interaction energies, backbone, bonding, solvation, docking
  6. [6] § Results › The essential role of K238 in forming functional GJs ↔ cx36_het_dock.ipynb, lines 39–69 · score 0.52 · van der Waals, interaction energy, bonds, docked, electrostatic, Cx36

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 · 869 lines · 29 KB · no license · 2 matches

  1. # %%
  2. cx36_mut = {
  3. 'hetero': {
  4. 'mut_type':
  5. [
  6. 'K238A', # L -3-2=-5
  7. 'E239K;E230K,E239K', # N 0+2=2
  8. 'K238E,E239K', # O 0+0=0
  9. 'E230K;E230K,E239K', # Q 0+2=2
  10. 'E241A;E230K,E239K', # P -1+2=1
  11. 'K238E,E230K', # R -2-2=-4
  12. 'E230K,E239K', # D 2-2 = 0
  13. 'E230K', # B 0-2 =-2
  14. 'E239K', # C -2
  15. 'E230K,E239K;K238E,E230K', # E 2-2 = 0
  16. 'E230K;K238E', # F 0-4 = -4
  17. 'E239K;K238E', # G 0-4 = -4
  18. 'K238Q', # M -3 - 2 = -5
  19. 'E239K;E230K,E239K', # N 0+2=2
  20. 'K238E;K238E,E230K', # V -4 -2 = -6
  21. 'K238E;K238E,E239K', # W -4 -2 = -6
  22. 'K238E;E230K,E239K,E241K', # a -4 + 4 = 0
  23. 'K238E;E241K', #b -4 + 0 = -4
  24. ],
  25. 'label': ['L', 'N', 'O', 'Q', 'P', 'R', 'D' ,'B', 'C', 'E', 'F', 'G', 'M', 'N', 'V', 'W', 'a', 'b'],
  26. 'ESIs': [3, 3, 3, 3, 3, 2, 4, 5, 5, 4, 4, 4, 3, 3, 1, 1, 2, 2],
  27. 'net_charge' :[-5, 2, 0, 2, 1, -4, 0, -2, -2, 0, -4, -4, -5, 2, -6, -6, 0, -4],
  28. 'Functional': [True, True, True, False, False, False, True, True, True, True, True, True, True, True, False, False, False, False]
  29. },
  30. 'homo': {
  31. 'mut_type':
  32. [
  33. 'E241A;E241A', # J -1*2 = -2
  34. 'E239K;E239K', # I 0*2 = 0
  35. 'E230K;E230K', # H 0*2 = 0
  36. 'K238E,E230K,E239K;K238E,E230K,E239K', # K -2*2 = -4
  37. 'E230K,E239K;E230K,E239K', # S 2*2=4
  38. 'K238E,E230K;K238E,E230K', # T -2*2 = -4
  39. 'K238E,E239K;K238E,E239K', # U -2*2 = -4
  40. 'K238Q;K238Q', # Z -3*2 = -6
  41. 'K238A;K238A', # X -3*2 = -6
  42. 'K238E;K238E', # Y -4*2 = -8
  43. 'E241K;E241K', # c 0*2 = 0
  44. 'E241K,E239K,E230K;E241K,E239K,E230K', # d 2*4 = 8
  45. 'E241K,E239K,E230K,K238E;E241K,E239K,E230K,K238E', # e 2*2 = 4
  46. ],
  47. 'label': ['J', 'I', 'H', 'K','S', 'T', 'U', 'Z', 'X', 'Y', 'c', 'd', 'e'],
  48. 'ESIs': [4, 4, 4, 4, 2, 2, 2, 0, 0, 0, 4, 0, 6],
  49. 'net_charge' : [-2, 0, 0, -4, 4, -4, -4, -6, -6, -8, 0, 8, 4],
  50. 'Functional': [True, True, True, True, False, False, False, False, False, False, False, False, False]
  51. }
  52. }
  53. stru = ['8xgd','8iyg']
  54. for key in cx36_mut:
  55. for ter in cx36_mut[key]:
  56. print(key, ter, len(cx36_mut[key][ter]))
  57. # %%
  58. import pandas as pd
  59. import matplotlib.pyplot as plt
  60. import seaborn as sns
  61. import numpy as np
  62. from scipy.stats import linregress
  63. def pval_to_stars(p):
  64. if p < 0.001:
  65. return '***'
  66. elif p < 0.01:
  67. return '**'
  68. elif p < 0.05:
  69. return '*'
  70. else:
  71. return 'ns'
  72. # %% [markdown]
  73. # # Dataset Combine for difference to WT
  74. # %%
  75. #pdb = '8xgd' # '8xgd','8iyg'
  76. pdb = '8xgd'
  77. file = 'Dif' #Average, Dif, Raw
  78. # %%
  79. all_diff_df = []
  80. use_e241k = True
  81. for mut_sym in ['hetero', 'homo']:
  82. fdx_df = pd.read_csv(f'./{pdb}_{mut_sym}/{file}_{pdb}.fxout', sep='\t', skiprows=8)
  83. e241k_mut_df = pd.read_csv(f'./{pdb}_{mut_sym}/{file}_{pdb}_e241k.fxout', sep='\t', skiprows=8)
  84. #drop_cols
  85. drop_cols = ['Van der Waals clashes', 'cis_bond', 'torsional clash', 'backbone clash', 'disulfide',
  86. 'electrostatic kon', 'helix dipole', 'Sidechain Hbond'] #'Backbone Hbond', ,'Solvation Hydrophobic', 'energy Ionisation'
  87. fdx_df = fdx_df.drop(drop_cols, axis=1)
  88. e241k_mut_df = e241k_mut_df.drop(drop_cols, axis=1)
  89. drop_cols = fdx_df.columns[~(fdx_df != 0).all()]
  90. fdx_df = fdx_df.drop(drop_cols, axis=1)
  91. e241k_mut_df = e241k_mut_df.drop(drop_cols, axis=1)
  92. if use_e241k:
  93. fdx_df = pd.concat([fdx_df, e241k_mut_df], ignore_index=True)
  94. fdx_df['label'] = [lb for lb in cx36_mut[mut_sym]['label'] for i in range(10)]
  95. fdx_df['ESI'] = [esi for esi in cx36_mut[mut_sym]['ESIs'] for i in range(10)]
  96. fdx_df['net_charge'] = [nc for nc in cx36_mut[mut_sym]['net_charge'] for i in range(10)]
  97. fdx_df['mut'] = [mt for mt in cx36_mut[mut_sym]['mut_type'] for i in range(10)]
  98. fdx_df['mut_type'] = [mut_sym for i in range(len(fdx_df))]
  99. fdx_df['functional'] = [fn for fn in cx36_mut[mut_sym]['Functional'] for i in range(10)]
  100. drop_cols = ['Pdb']
  101. fdx_df = fdx_df.drop(drop_cols, axis=1)
  102. all_diff_df.append(fdx_df)
  103. all_diff_df = pd.concat(all_diff_df, ignore_index=True)
  104. # %%
  105. all_diff_df
  106. # %% [markdown]
  107. # ## Direct statitics
  108. # %%
  109. from sklearn.metrics import silhouette_score
  110. import numpy as np
  111. from scipy.stats import mannwhitneyu
  112. # %% [markdown]
  113. # ### All pairs
  114. # %% [markdown]
  115. # Check sample size
  116. # %%
  117. len(all_diff_df[all_diff_df['functional'] == True]), len(all_diff_df[all_diff_df['functional'] == False])
  118. # %% [markdown]
  119. # plot figure
  120. # %%
  121. # Prepare data
  122. all_diff_df['functional_label'] = all_diff_df['functional'].map({True: 'Functional', False: 'Non-functional'})
  123. feature_cols = [col for col in all_diff_df.columns if all_diff_df[col].dtype != 'O' and col not in\
  124. ['functional', 'ESI','functional_label', 'mut','mut_type', 'label', 'net_charge']]
  125. labels = all_diff_df['functional_label']
  126. font_label = 18
  127. # Create PairGrid
  128. g = sns.PairGrid(
  129. all_diff_df,
  130. vars=feature_cols,
  131. hue='functional_label',
  132. palette={'Functional': 'green', 'Non-functional': 'red'},
  133. )
  134. # Map scatter plots
  135. g.map_lower(sns.scatterplot, edgecolor='k', s=60, alpha=0.8)
  136. g.map_diag(sns.kdeplot, fill=True, alpha=0.5) # KDE on diagonal, like pairplot
  137. # Compute and annotate silhouette scores
  138. for i, x_var in enumerate(feature_cols):
  139. for j, y_var in enumerate(feature_cols):
  140. if j > i: # Upper triangle (blank by default)
  141. g.axes[i, j].set_axis_off()
  142. if j < i:
  143. ax = g.axes[i, j]
  144. X = all_diff_df[[y_var, x_var]].values # Note: y_var first for rows, x_var for columns
  145. score = silhouette_score(X, labels)
  146. # Linear regression on all data
  147. slope, intercept, r_val, p_val, _ = linregress(X[:,0], X[:,1])
  148. # Plot the regression line
  149. x_fit = pd.Series(sorted(X[:,0]))
  150. y_fit = slope * x_fit + intercept
  151. ax.plot(x_fit, y_fit, color='grey', linestyle='-', linewidth=1)
  152. ax.set_title(f"S. score: {score:.2f}; R: {r_val:.2f} ({pval_to_stars(p_val)})", fontsize=font_label-3)
  153. if j == i:
  154. ax = g.axes[i, j]
  155. # Compute silhouette score for the diagonal (self-comparison)
  156. X = all_diff_df[[x_var]].values
  157. score = silhouette_score(X, labels)
  158. # Compute p-value (Mann-Whitney U test, non-parametric) for Non-functional vs Functional
  159. #elec_func = all_diff_df[all_diff_df['functional']==True][x_var]
  160. #elec_nonfunc = all_diff_df[all_diff_df['functional']==False][x_var]
  161. #stat, pval = mannwhitneyu(elec_func, elec_nonfunc, alternative='two-sided')
  162. ax.set_title(f"S. score: {score:.2f}", fontsize=font_label-3)
  163. g.add_legend(fontsize=30)
  164. g._legend.set_title("") # Access the legend directly from the PairGrid
  165. #plt.suptitle("Pairwise Scatter Plots with Silhouette Scores", y=1.02, fontsize=30)
  166. for i, feature in enumerate(feature_cols):
  167. if feature == 'total energy':
  168. # Set y-label for the first feature
  169. g.axes[i, 0].set_ylabel('∆∆G', fontsize=font_label-4)
  170. # Set x-label for the first feature
  171. g.axes[-1, i].set_xlabel('∆∆G', fontsize=font_label-2)
  172. elif feature == 'Electrostatics':
  173. # Set y-labels for the first column (leftmost)
  174. g.axes[i, 0].set_ylabel('∆∆Ψ ', fontsize=font_label-4)
  175. # Set x-labels for the bottom row
  176. g.axes[-1, i].set_xlabel('∆∆Ψ', fontsize=font_label-2)
  177. else:
  178. # Set y-labels for the first column (leftmost)
  179. g.axes[i, 0].set_ylabel(f'∆{feature}', fontsize=font_label-4)
  180. # Set x-labels for the bottom row
  181. g.axes[-1, i].set_xlabel(f'∆{feature}', fontsize=font_label-2)
  182. plt.tight_layout()
  183. plt.savefig(f"{pdb}_Pairwise_Plots.svg", format="svg")
  184. # %% [markdown]
  185. # Output Excel for the figure
  186. # %%
  187. if pdb == '8xgd':
  188. all_diff_df[feature_cols+['functional_label']].to_csv(f"Fig_S4A.csv", index=False)
  189. else:
  190. all_diff_df[feature_cols+['functional_label']].to_csv(f"Fig_S5C.csv", index=False)
  191. # %% [markdown]
  192. # ### Single figure of a quantity vs ∆∆G
  193. # %%
  194. all_diff_df_reduced = all_diff_df[~all_diff_df['mut'].isin(['E241A;E241A', 'E241K,E239K,E230K;E241K,E239K,E230K'])]
  195. # %% [markdown]
  196. # Plot data
  197. # %%
  198. from scipy.stats import linregress
  199. # Prepare data
  200. X = all_diff_df_reduced[all_diff_df_reduced['mut_type']=='homo'][['Electrostatics', 'total energy']].values
  201. x = X[:, 0] # Electrostatics
  202. y = X[:, 1] # Total Energy
  203. # Scatter plot
  204. plt.figure(figsize=(6, 5))
  205. plt.scatter(x, y, color='darkcyan', edgecolor='k', s=60, alpha=0.8)
  206. # Linear fit
  207. slope, intercept, r_val, p_val, _ = linregress(x, y)
  208. x_fit = np.linspace(x.min(), x.max(), 100)
  209. y_fit = slope * x_fit + intercept
  210. plt.plot(x_fit, y_fit, color='Grey', linestyle='-', linewidth=2, label='Linear fit')
  211. # Annotation
  212. stats_text = f"Rp = {r_val:.2f} ({pval_to_stars(p_val)})"
  213. # Labels and formatting
  214. plt.xlabel('∆∆ϕ, kcal/mol', fontsize=14)
  215. plt.ylabel('∆∆G, kcal/mol', fontsize=14)
  216. plt.ylim(-21, 41) #(-15, 32)
  217. plt.xlim(-9, 18) #(-20, 22)
  218. ax = plt.gca()
  219. #ax.tick_params(labelbottom=False, labelleft=False)
  220. plt.tight_layout()
  221. print(len(X))
  222. #plt.savefig(f"{pdb}_∆E_vs_∆∆G.svg", format="svg")
  223. # %%
  224. r_val, p_val
  225. # %% [markdown]
  226. # output csv file for the plot
  227. # %%
  228. if pdb == '8xgd':
  229. (all_diff_df_reduced[all_diff_df_reduced['mut_type']=='homo'][['Electrostatics', 'total energy']]).to_csv(f"Fig_1B.csv", index=False)
  230. # %% [markdown]
  231. # ### Multiple quantities vs ∆∆G
  232. # %% [markdown]
  233. # Plot
  234. # %%
  235. from scipy.stats import linregress
  236. # Scatter plot
  237. fig, axes = plt.subplots(figsize=(16, 10), ncols=3, nrows=2)
  238. axes = axes.flatten()
  239. ener_terms = ['Backbone Hbond', 'Van der Waals', 'Solvation Polar', 'Solvation Hydrophobic', 'entropy sidechain', 'entropy mainchain']
  240. ener_term_short = ['BB Hbond', 'VdW', 'Solv Polar', 'Solv Hydrophobic', 'Ent Sidechain', 'Ent Mainchain']
  241. # Prepare elestrostaics data
  242. X_e = all_diff_df_reduced[all_diff_df_reduced['mut_type']=='homo'][['Electrostatics', 'total energy']].values
  243. x_e = X_e[:, 0] # Electrostatics
  244. y_e = X_e[:, 1] # Total Energy
  245. # Scatter plot
  246. #plt.figure(figsize=(6, 5))
  247. #plt.scatter(x, y, color='darkcyan', edgecolor='k', s=60, alpha=0.8)
  248. # Linear fit
  249. slope_e, intercept_e, r_val_e, p_val_e, _ = linregress(x_e, y_e)
  250. x_e_fit = np.linspace(x_e.min(), x_e.max(), 100)
  251. y_e_fit = slope_e * x_e_fit + intercept_e
  252. for i, ax in enumerate(axes):
  253. # Prepare data
  254. X = all_diff_df_reduced[all_diff_df_reduced['mut_type']=='homo'][[ener_terms[i], 'total energy']].values
  255. x = X[:, 0]
  256. y = X[:, 1]
  257. ax.scatter(x, y, color='darkcyan', edgecolor='k', s=60, alpha=0.8)
  258. ax.scatter(x_e, y_e, color='Grey', edgecolor='k', s=20, alpha=0.3)
  259. # Linear fit
  260. slope, intercept, r_val, p_val, _ = linregress(x, y)
  261. x_fit = np.linspace(x.min(), x.max(), 100)
  262. y_fit = slope * x_fit + intercept
  263. ax.plot(x_fit, y_fit, color='k', linestyle='-', linewidth=2, label='Linear fit')
  264. ax.plot(x_e_fit, y_e_fit, color='Grey', linestyle='-', linewidth=2, label='Linear fit (Electrostatics)')
  265. ax.set_xlabel('∆'+ener_term_short[i]+' (kcal/mol)', fontsize=14)
  266. ax.set_ylim(-15, 32)
  267. ax.set_xlim(-20, 22)
  268. if i == 0 or i == 3:
  269. ax.set_ylabel('∆∆G (kcal/mol)', fontsize=14)
  270. # Annotation
  271. stats_text = f"Rp={r_val:.2f}"
  272. ax.set_title('∆∆G vs ∆'+ener_terms[i]+' '+stats_text, fontsize=16)
  273. plt.tight_layout()
  274. plt.savefig(f"{pdb}_∆E_vs_other_SI.svg", format="svg")
  275. # %% [markdown]
  276. # Ouput figure csv file
  277. # %%
  278. all_diff_df_reduced[all_diff_df_reduced['mut_type']=='homo']\
  279. [['total energy','Backbone Hbond', 'Van der Waals', 'Solvation Polar', 'Solvation Hydrophobic', 'entropy sidechain', 'entropy mainchain']].to_csv(f"Fig_S1.csv", index=False)
  280. # %% [markdown]
  281. # ### ∆phi distribution
  282. # %% [markdown]
  283. # Plot
  284. # %%
  285. import seaborn as sns
  286. from scipy.stats import mannwhitneyu
  287. # Prepare data
  288. df = all_diff_df.copy()
  289. df['functional_label'] = df['functional'].map({True: 'Functional', False: 'Non-functional'})
  290. # Extract values
  291. elec_func = df[df['functional_label'] == 'Functional']['Electrostatics']
  292. elec_nonfunc = df[df['functional_label'] == 'Non-functional']['Electrostatics']
  293. # Compute p-value (Mann-Whitney U test, non-parametric)
  294. stat, pval = mannwhitneyu(elec_func, elec_nonfunc, alternative='two-sided')
  295. # Plot
  296. plt.figure(figsize=(7, 5))
  297. sns.histplot(elec_func, color='g', label='Functional', kde=True, stat='density',
  298. bins=12, alpha=0.35, edgecolor=None, kde_kws={'bw_adjust': 1})
  299. sns.histplot(elec_nonfunc, color='r', label='Non-functional', kde=True, stat='density',
  300. bins=12, alpha=0.35, edgecolor=None, kde_kws={'bw_adjust': 1})
  301. #plt.xlabel('∆Electrostatics', fontsize=14)
  302. #plt.ylabel('Frequency', fontsize=14)
  303. plt.yticks([0.0, 0.05, 0.1,0.15,0.2])
  304. ax = plt.gca()
  305. ax.tick_params(labelbottom=False, labelleft=False)
  306. ax.set_xlabel('')
  307. ax.set_ylabel('')
  308. plt.tight_layout()
  309. print(len(df[df['functional']==True]), len(df[df['functional']==False]))
  310. #plt.savefig(f"{pdb}_∆Electrostatics_dist.svg", format="svg")
  311. # %% [markdown]
  312. # Output plot data csv file
  313. # %%
  314. if pdb == '8xgd':
  315. df[['functional_label','Electrostatics']].to_csv(f"Fig_4C.csv", index=False)
  316. # %% [markdown]
  317. # ## ESI vs some energy
  318. # %%
  319. grouped_df = all_diff_df.groupby(['label', 'mut']).agg({
  320. 'net_charge': 'first',
  321. 'ESI': 'first',
  322. 'mut_type': 'first',
  323. 'functional': 'first',
  324. 'total energy': ['mean', 'std'],
  325. 'Electrostatics': ['mean', 'std'],
  326. 'Solvation Polar': ['mean', 'std'],
  327. })
  328. # Flatten the column MultiIndex
  329. grouped_df.columns = ['_'.join(col).strip() if col[1] != 'first' else col[0] for col in grouped_df.columns] #[col[0] if isinstance(col, tuple) else col for col in grouped_df.columns] or ['_'.join(col).strip() if isinstance(col, tuple) else col for col in grouped_df.columns]
  330. grouped_df = grouped_df.reset_index()
  331. grouped_df
  332. # %%
  333. grouped_df_homo = grouped_df[grouped_df['mut_type']=='homo']
  334. grouped_df_homo
  335. # %% [markdown]
  336. # ### Homo samples ESI vs ∆phi
  337. # %%
  338. # drop mut == 'E241A;E241A' and E241K,E239K,E230K;E241K,E239K,E230K
  339. grouped_df_homo_reduced = grouped_df_homo[~grouped_df_homo['mut'].isin(['E241A;E241A', 'E241K,E239K,E230K;E241K,E239K,E230K'])]
  340. # %% [markdown]
  341. # plot
  342. # %%
  343. # ====== USER CONFIGURATION ======
  344. x_col = 'ESI' # x-axis
  345. y_base = 'Electrostatics' # or 'Electrostatics' 'total energy', 'Solvation Polar'
  346. group_col = 'functional' # now using functional: True / False
  347. font_size = 16
  348. font_style = 'Arial'
  349. x_label = 'ESI'
  350. y_label = '∆∆G' if y_base == 'total energy' else '∆Electrostatics'
  351. error_capsize = 10
  352. # =================================
  353. # Derived columns
  354. y_col = f'{y_base}_mean'
  355. y_err = f'{y_base}_std'
  356. # Color mapping by functional
  357. colors = {True: '#00A859', False: 'red'}
  358. # Plot setup
  359. plt.figure(figsize=(8, 6))
  360. # Scatter with error bars colored by functional
  361. for func_value in [True, False]:
  362. sub_df = grouped_df_homo_reduced[grouped_df_homo_reduced[group_col] == func_value]
  363. plt.errorbar(
  364. sub_df[x_col], sub_df[y_col], yerr=sub_df[y_err],
  365. fmt='o', color=colors[func_value], ecolor=colors[func_value],
  366. capsize=error_capsize, capthick=2, markersize=10,
  367. label='Functional' if func_value else 'Non-functional'
  368. )
  369. # Linear regression on all data
  370. x_all = grouped_df_homo_reduced[x_col]
  371. y_all = grouped_df_homo_reduced[y_col]
  372. slope, intercept, r_val, p_val, _ = linregress(x_all, y_all)
  373. # Plot the regression line (optional)
  374. x_fit = pd.Series(sorted(x_all))
  375. y_fit = slope * x_fit + intercept
  376. label_fit = f"Linear fitting"
  377. #plt.plot(x_fit, y_fit, color='darkgrey', linestyle='-', linewidth=1.5, label=label_fit)
  378. ax = plt.gca()
  379. ax.tick_params(labelbottom=False, labelleft=False)
  380. plt.gca().invert_xaxis()
  381. plt.ylim(-7, 18) # 8igy
  382. #plt.ylim(-7, 16) #8xgd
  383. plt.tight_layout()
  384. #plt.savefig(f"{pdb}_{y_label}_vs_ESI.svg", format="svg")
  385. # %% [markdown]
  386. # Output plot data csv file
  387. # %%
  388. if pdb == '8xgd':
  389. grouped_df_homo_reduced[['label','mut','ESI', 'Electrostatics_mean', 'Electrostatics_std', 'total energy_mean','total energy_std','functional']].to_csv(f"Fig_2E.csv", index=False)
  390. # %% [markdown]
  391. # ### Homo samples ESI vs ∆phi Demo version
  392. # %%
  393. # ====== USER CONFIGURATION ======
  394. x_col = 'ESI' # x-axis
  395. y_base = 'Electrostatics' # or 'Electrostatics' 'total energy', 'Solvation Polar'
  396. group_col = 'functional' # now using functional: True / False
  397. font_size = 16
  398. font_style = 'Arial'
  399. plot_title = f'{y_base} vs ESI'
  400. x_label = 'ESI'
  401. y_label = '∆∆G' if y_base == 'total energy' else '∆Electrostatics' + ' (kcal/mol)'
  402. error_capsize = 3
  403. # =================================
  404. # Derived columns
  405. y_col = f'{y_base}_mean'
  406. y_err = f'{y_base}_std'
  407. # Colors by functional
  408. colors = {True: '#00A859', False: 'red'}
  409. # Marker settings for 'functional' True/False
  410. marker_style = {
  411. True: {'marker': 'o', 'facecolors': colors[True], 'edgecolors': 'black', 'label': 'Functional'},
  412. False: {'marker': 'o', 'facecolors': colors[False], 'edgecolors': 'black', 'label': 'Non-functional'}
  413. }
  414. # Plot setup
  415. plt.figure(figsize=(8, 6))
  416. # Scatter plot with error bars
  417. for functional_value in [True, False]:
  418. sub_df = grouped_df_homo_reduced[grouped_df_homo_reduced[group_col] == functional_value]
  419. x = sub_df[x_col]
  420. y = sub_df[y_col]
  421. y_std = sub_df[y_err]
  422. style = marker_style[functional_value]
  423. plt.errorbar(x, y, yerr=y_std, fmt=style['marker'],
  424. markerfacecolor=style['facecolors'], markeredgecolor=style['edgecolors'],
  425. ecolor=style['facecolors'],
  426. markersize=6, capsize=error_capsize, linestyle='none',
  427. label=style['label'])
  428. # Add label text near each point
  429. for i, row in sub_df.iterrows():
  430. plt.text(row[x_col] + 0.2, row[y_col]+1, str(row['mut'].split(';')[0]),
  431. fontsize=font_size-2, color=style['edgecolors'],
  432. ha='left', va='center')
  433. # Linear regression on all data
  434. x_all = grouped_df_homo_reduced[x_col]
  435. y_all = grouped_df_homo_reduced[y_col]
  436. slope, intercept, r_val, p_val, _ = linregress(x_all, y_all)
  437. # Plot the regression line
  438. x_fit = pd.Series(sorted(x_all))
  439. y_fit = slope * x_fit + intercept
  440. label_fit = f"Linear fitting"
  441. plt.plot(x_fit, y_fit, color='black', linestyle='-', linewidth=1.5, label=label_fit)
  442. # Add horizontal line at y=0
  443. plt.axhline(0, color='grey', linestyle='--', linewidth=1.5, label='y=0')
  444. # Add stats textbox
  445. stats_text = f"$R^2$ = {r_val:.3f}\np = {p_val:.1e} ({pval_to_stars(p_val)})"
  446. plt.text(0.7, 0.15, stats_text,
  447. transform=plt.gca().transAxes,
  448. fontsize=font_size,
  449. verticalalignment='top',
  450. bbox=dict(boxstyle="round,pad=0.3", facecolor='lightgrey', alpha=0.5))
  451. # Axis formatting
  452. plt.xlabel(x_label, fontsize=font_size, fontname=font_style)
  453. plt.ylabel(y_label, fontsize=font_size, fontname=font_style)
  454. plt.xticks(fontsize=font_size-1, fontname=font_style)
  455. plt.yticks(fontsize=font_size-1, fontname=font_style)
  456. plt.legend(fontsize=font_size-1)
  457. plt.gca().invert_xaxis()
  458. plt.tight_layout()
  459. # %% [markdown]
  460. # ### ALl samples ESI vs ∆phi excluding E241K-related mutants Demo version
  461. # %%
  462. # drop mut that include 'E241K' samples
  463. grouped_df_reduced = grouped_df[~grouped_df['mut'].str.contains('E241K')]
  464. # %% [markdown]
  465. # Plot
  466. # %%
  467. # ====== USER CONFIGURATION ======
  468. x_col = 'ESI' # x-axis
  469. y_base = 'Electrostatics' # or 'Electrostatics' 'total energy', 'Solvation Polar'
  470. group_col = 'functional' # now using functional: True / False
  471. font_size = 16
  472. font_style = 'Arial'
  473. plot_title = f'{y_base} vs ESI'
  474. x_label = 'ESI'
  475. y_label = '∆∆G' if y_base == 'total energy' else '∆Electrostatics' + ' (kcal/mol)'
  476. error_capsize = 10
  477. # =================================
  478. # Derived columns
  479. y_col = f'{y_base}_mean'
  480. y_err = f'{y_base}_std'
  481. # Colors by functional
  482. colors = {True: '#00A859', False: 'red'}
  483. # Marker settings for 'functional' True/False
  484. marker_style = {
  485. True: {'marker': 'o', 'facecolors': colors[True], 'edgecolors': 'black', 'label': 'Functional'},
  486. False: {'marker': 'o', 'facecolors': colors[False], 'edgecolors': 'black', 'label': 'Non-functional'}
  487. }
  488. # Plot setup
  489. plt.figure(figsize=(8, 6))
  490. # Scatter with error bars colored by functional
  491. for func_value in [True, False]:
  492. sub_df = grouped_df_reduced[grouped_df_reduced[group_col] == func_value]
  493. plt.errorbar(
  494. sub_df[x_col], sub_df[y_col], yerr=sub_df[y_err],
  495. fmt='o', color=colors[func_value], ecolor=colors[func_value],
  496. capsize=error_capsize, capthick=2, markersize=10,
  497. label='Functional' if func_value else 'Non-functional'
  498. )
  499. # Add label text near each point
  500. for i, row in sub_df.iterrows():
  501. plt.text(row[x_col] + 0.2, row[y_col]+1, str(row['label']),
  502. fontsize=font_size-2, color=marker_style[func_value]['edgecolors'],
  503. ha='left', va='center')
  504. # Linear regression on all data
  505. x_all = grouped_df_reduced[x_col]
  506. y_all = grouped_df_reduced[y_col]
  507. slope, intercept, r_val, p_val, _ = linregress(x_all, y_all)
  508. # Plot the regression line
  509. x_fit = pd.Series(sorted(x_all))
  510. y_fit = slope * x_fit + intercept
  511. label_fit = f"Linear fitting"
  512. plt.plot(x_fit, y_fit, color='darkgrey', linestyle='-', linewidth=2, label=label_fit)
  513. # Add stats textbox
  514. stats_text = f"$R$ = {r_val:.3f}\np = {p_val:.1e} ({pval_to_stars(p_val)})"
  515. plt.text(0.7, 0.15, stats_text,
  516. transform=plt.gca().transAxes,
  517. fontsize=font_size,
  518. verticalalignment='top',
  519. bbox=dict(boxstyle="round,pad=0.3", facecolor='lightgrey', alpha=0.5))
  520. # Axis formatting
  521. plt.xlabel(x_label, fontsize=font_size, fontname=font_style)
  522. plt.ylabel(y_label, fontsize=font_size, fontname=font_style)
  523. plt.xticks(fontsize=font_size-1, fontname=font_style)
  524. plt.yticks(fontsize=font_size-1, fontname=font_style)
  525. plt.legend(fontsize=font_size-1)
  526. plt.gca().invert_xaxis()
  527. plt.tight_layout()
  528. # %% [markdown]
  529. # Output plot data csv file
  530. # %%
  531. if pdb == '8xgd':
  532. grouped_df_reduced\
  533. [['label','mut','ESI', 'Electrostatics_mean', 'Electrostatics_std', 'total energy_mean','total energy_std','functional']].to_csv(f"Fig_4D_and_Fig_S4B.csv", index=False)
  534. else:
  535. grouped_df_reduced\
  536. [['label','mut','ESI', 'Electrostatics_mean', 'Electrostatics_std', 'total energy_mean','total energy_std','functional']].to_csv(f"Fig_S5A_and_Fig_S5B.csv", index=False)
  537. # %% [markdown]
  538. # ### ALl samples ESI vs ∆phi excluding E241K-related mutants
  539. # %%
  540. # ====== USER CONFIGURATION ======
  541. x_col = 'ESI' # x-axis
  542. y_base = 'Electrostatics' # or 'Electrostatics' 'total energy', 'Solvation Polar'
  543. group_col = 'functional' # now using functional: True / False
  544. font_size = 16
  545. font_style = 'Arial'
  546. plot_title = f'{y_base} vs ESI'
  547. x_label = 'ESI'
  548. y_label = '∆∆G' if y_base == 'total energy' else '∆Electrostatics'
  549. error_capsize = 10
  550. # =================================
  551. # Derived columns
  552. y_col = f'{y_base}_mean'
  553. y_err = f'{y_base}_std'
  554. # Colors by functional
  555. colors = {True: '#00A859', False: 'red'}
  556. # Marker settings for 'functional' True/False
  557. marker_style = {
  558. True: {'marker': 'o', 'facecolors': colors[True], 'edgecolors': 'black', 'label': 'Functional'},
  559. False: {'marker': 'o', 'facecolors': colors[False], 'edgecolors': 'black', 'label': 'Non-functional'}
  560. }
  561. # Plot setup
  562. plt.figure(figsize=(8, 6))
  563. # Scatter with error bars colored by functional
  564. for func_value in [True, False]:
  565. sub_df = grouped_df_reduced[grouped_df_reduced[group_col] == func_value]
  566. plt.errorbar(
  567. sub_df[x_col], sub_df[y_col], yerr=sub_df[y_err],
  568. fmt='o', color=colors[func_value], ecolor=colors[func_value],
  569. capsize=error_capsize, capthick=2, markersize=10,
  570. label='Functional' if func_value else 'Non-functional'
  571. )
  572. # Linear regression on all data
  573. x_all = grouped_df_reduced[x_col]
  574. y_all = grouped_df_reduced[y_col]
  575. slope, intercept, r_val, p_val, _ = linregress(x_all, y_all)
  576. # Plot the regression line
  577. x_fit = pd.Series(sorted(x_all))
  578. y_fit = slope * x_fit + intercept
  579. label_fit = f"Linear fitting"
  580. plt.plot(x_fit, y_fit, color='darkgrey', linestyle='-', linewidth=2, label=label_fit)
  581. # Add stats textbox
  582. stats_text = f"$R^2$ = {r_val:.3f}\np = {p_val:.1e} ({pval_to_stars(p_val)})"
  583. # Axis formatting
  584. ax = plt.gca()
  585. ax.tick_params(labelbottom=False, labelleft=False)
  586. plt.gca().invert_xaxis()
  587. #plt.ylim(-7, 16) #8xgd
  588. plt.ylim(-7, 18) #8iyg
  589. plt.tight_layout()
  590. plt.savefig(f"{pdb}_{y_label}_vs_ESI_homo_hetero.svg", format="svg")
  591. # %% [markdown]
  592. # ### All samples ESI vs ∆∆G Demo version
  593. # %%
  594. # ====== USER CONFIGURATION ======
  595. x_col = 'ESI' # x-axis
  596. y_base = 'total energy'
  597. group_col = 'functional' # now using functional: True / False
  598. font_size = 16
  599. font_style = 'Arial'
  600. plot_title = f'{y_base} vs ESI'
  601. x_label = 'ESI'
  602. y_label = '∆∆G' if y_base == 'total energy' else '∆Electrostatics' + ' (kcal/mol)'
  603. error_capsize = 10
  604. # =================================
  605. # Derived columns
  606. y_col = f'{y_base}_mean'
  607. y_err = f'{y_base}_std'
  608. # Colors by functional
  609. colors = {True: '#00A859', False: 'red'}
  610. # Marker settings for 'functional' True/False
  611. marker_style = {
  612. True: {'marker': 'o', 'facecolors': colors[True], 'edgecolors': 'black', 'label': 'Functional'},
  613. False: {'marker': 'o', 'facecolors': colors[False], 'edgecolors': 'black', 'label': 'Non-functional'}
  614. }
  615. # Plot setup
  616. plt.figure(figsize=(8, 6))
  617. # Scatter with error bars colored by functional
  618. for func_value in [True, False]:
  619. sub_df = grouped_df_reduced[grouped_df_reduced[group_col] == func_value]
  620. plt.errorbar(
  621. sub_df[x_col], sub_df[y_col], yerr=sub_df[y_err],
  622. fmt='o', color=colors[func_value], ecolor=colors[func_value],
  623. capsize=error_capsize, capthick=2, markersize=10,
  624. label='Functional' if func_value else 'Non-functional'
  625. )
  626. # Add label text near each point
  627. for i, row in sub_df.iterrows():
  628. plt.text(row[x_col] + 0.2, row[y_col]+1, str(row['label']),
  629. fontsize=font_size-2, color=marker_style[func_value]['edgecolors'],
  630. ha='left', va='center')
  631. # Linear regression on all data
  632. x_all = grouped_df_reduced[x_col]
  633. y_all = grouped_df_reduced[y_col]
  634. slope, intercept, r_val, p_val, _ = linregress(x_all, y_all)
  635. # Plot the regression line
  636. x_fit = pd.Series(sorted(x_all))
  637. y_fit = slope * x_fit + intercept
  638. label_fit = f"Linear fitting"
  639. plt.plot(x_fit, y_fit, color='darkgrey', linestyle='-', linewidth=2, label=label_fit)
  640. # Add stats textbox
  641. stats_text = f"$R$ = {r_val:.3f}\np = {p_val:.1e} ({pval_to_stars(p_val)})"
  642. plt.text(0.7, 0.15, stats_text,
  643. transform=plt.gca().transAxes,
  644. fontsize=font_size,
  645. verticalalignment='top',
  646. bbox=dict(boxstyle="round,pad=0.3", facecolor='lightgrey', alpha=0.5))
  647. # Axis formatting
  648. plt.xlabel(x_label, fontsize=font_size, fontname=font_style)
  649. plt.ylabel(y_label, fontsize=font_size, fontname=font_style)
  650. plt.xticks(fontsize=font_size-1, fontname=font_style)
  651. plt.yticks(fontsize=font_size-1, fontname=font_style)
  652. plt.legend(fontsize=font_size-1)
  653. plt.gca().invert_xaxis()
  654. plt.ylim(-21, 41)
  655. plt.tight_layout()
  656. # %% [markdown]
  657. # ### All samples ESI vs ∆∆G
  658. # %%
  659. # ====== USER CONFIGURATION ======
  660. x_col = 'ESI' # x-axis
  661. y_base = 'total energy'
  662. group_col = 'functional' # now using functional: True / False
  663. font_style = 'Arial'
  664. plot_title = f'{y_base} vs ESI'
  665. x_label = 'ESI'
  666. y_label = '∆∆G' if y_base == 'total energy' else '∆Electrostatics'
  667. error_capsize = 10
  668. # =================================
  669. # Derived columns
  670. y_col = f'{y_base}_mean'
  671. y_err = f'{y_base}_std'
  672. # Colors by functional
  673. colors = {True: '#00A859', False: 'red'}
  674. # Marker settings for 'functional' True/False
  675. marker_style = {
  676. True: {'marker': 'o', 'facecolors': colors[True], 'edgecolors': 'black', 'label': 'Functional'},
  677. False: {'marker': 'o', 'facecolors': colors[False], 'edgecolors': 'black', 'label': 'Non-functional'}
  678. }
  679. # Plot setup
  680. plt.figure(figsize=(8, 6))
  681. # Scatter with error bars colored by functional
  682. for func_value in [True, False]:
  683. sub_df = grouped_df_reduced[grouped_df_reduced[group_col] == func_value]
  684. plt.errorbar(
  685. sub_df[x_col], sub_df[y_col], yerr=sub_df[y_err],
  686. fmt='o', color=colors[func_value], ecolor=colors[func_value],
  687. capsize=error_capsize, capthick=2, markersize=10,
  688. label='Functional' if func_value else 'Non-functional'
  689. )
  690. # Linear regression on all data
  691. x_all = grouped_df_reduced[x_col]
  692. y_all = grouped_df_reduced[y_col]
  693. slope, intercept, r_val, p_val, _ = linregress(x_all, y_all)
  694. # Plot the regression line
  695. x_fit = pd.Series(sorted(x_all))
  696. y_fit = slope * x_fit + intercept
  697. label_fit = f"Linear fitting"
  698. plt.plot(x_fit, y_fit, color='darkgrey', linestyle='-', linewidth=2, label=label_fit)
  699. # Add stats textbox
  700. stats_text = f"$R^2$ = {r_val:.3f}\np = {p_val:.1e} ({pval_to_stars(p_val)})"
  701. # Axis formatting
  702. ax = plt.gca()
  703. ax.tick_params(labelbottom=False, labelleft=False)
  704. plt.gca().invert_xaxis()
  705. plt.ylim(-21, 41)
  706. plt.tight_layout()
  707. plt.savefig(f"{pdb}_{y_label}_vs_ESI.svg", format="svg")

cx36_mut_corr.ipynb at commit faf83f4, no license · at the source

Overview

Authors: Robert S Wong1, Zhiyuan Song2, Yu T Zheng1, Honghong Chen1, Haiqing Zhao2, Donglin Bai1
  1. Department of Physiology and Pharmacology, University of Western Ontario, London, ON Canada
  2. Department of Biochemistry and Molecular Biology; Sealy Center for Structural Biology and Molecular Biophysics, University of Texas Medical Branch, Galveston, TX USA
Journal: Communications biology, volume 9, issue 1, article 815
Dates: received 21 November 2025; accepted 2 June 2026; published online 11 June 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1038/s42003-026-10464-w · PMID 42277350 · PMCID PMC13269782 · OpenAlex W7164370178
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: human (organism), cellular / molecular (subfield)
Methods: Statistics, Evoked potentials
Keywords: Ion channel signalling, Neurophysiology
MeSH: Gap Junction delta-2 Protein*, Gap Junctions*, Static Electricity*, HEK293 Cells, Humans, Molecular Docking Simulation, Protein Binding (* major topic)
Topic: Connexins and lens biology (Molecular Biology, Biochemistry, Genetics and Molecular Biology), according to OpenAlex
Funding: Canadian Network for Research and Innovation in Machining Technology, Natural Sciences and Engineering Research Council of Canada (288241)
Citations: not cited yet (Europe PMC); 59 references in the paper

Abstract

Connexin36 (Cx36) is broadly expressed in neurons and serves as the principal protein that forms interneuronal gap junctions (GJs), also known as electrical synapses. Recent high-resolution structures of human Cx36 GJ have revealed crucial electrostatic interactions (ESIs) of charged residues between two docked Cx36 hemichannels at the second extracellular (E2) loops. Despite their structural importance, the mechanistic roles of these ESIs remain poorly understood. To investigate their significance, we systematically designed and tested a series of missense variants targeting key E2 interface residues, aiming to disrupt or modulate the electrostatic landscape at the docking interface. Based on the ESI pairs defined from the crystal structure, our combined computational calculations and dual patch-clamp experiments in engineered HEK293 cell pairs suggest that at least three ESI residual pairs per E2–E2 interface are required to support functional GJ formation. Furthermore, we found that these unique ESIs of Cx36 could play a role in its docking specificity to itself, as they rarely form heterotypic GJs with other brain connexins. Overall, these findings provide essential molecular and functional insights into the mechanisms governing Cx36 GJ formation and partner specificity, paving the way for future therapeutic approaches targeting connexin dysfunction in human diseases.

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 6 matches between paragraphs and lines of code.

Zenodo 20303481

License: CC-BY-4.0
State: the link answers, verified on 27 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 (2 files), pandas (2 files), NumPy (1 file), scikit-learn (1 file), SciPy (1 file), seaborn (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)
3 files

zhaolabutmb/Cx36_Channel_Electrostatics

License: none: the authors keep all their rights
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: faf83f4505591cf0c499e3533d7ae0991a06646e, 29 May 2026
Languages: Jupyter (2)
Size: 72 files, 2 scripts
Software Heritage: not archived
Found in: “Code availability”
Holds: README, environment (requirements.txt), 2 notebooks
Not found: license file, CITATION.cff, tests, continuous integration, documentation
Tools: Matplotlib (2 files), pandas (2 files), NumPy (1 file), scikit-learn (1 file), SciPy (1 file), seaborn (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
3 files

Code availability

All codes and scripts used for computational calculations and plotting are available at GitHub (https://github.com/zhaolabutmb/Cx36_Channel_Electrostatics) and from Zenodo (https://zenodo.org/records/20303481).

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

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;
  • 4 scripts, each with its path and the digest of its content;
  • 6 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

Numerical source data underlying patch clamp, computational data, and percentage of morphological GJ plaque figures are provided in Supplementary Data 1. Raw patch clamp recordings are available upon reasonable request to the corresponding author. Computational data including all the calculated datasets can be accessed through Zenodo at https://zenodo.org/records/20303481.

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, 6 authors, 2 keywords, 7 MeSH terms, 1 funder, 58 references.

Cite

This paper

Wong, R. S., Song, Z., Zheng, Y. T., Chen, H., Zhao, H., & Bai, D. (2026). Quantifying electrostatic control of docking and binding energetics in functional Cx36 gap junctions. Communications biology, 9(1), 815. https://doi.org/10.1038/s42003-026-10464-w

BibTeX

@article{wong2026quantifying,
author = {Wong, Robert S and Song, Zhiyuan and Zheng, Yu T and Chen, Honghong and Zhao, Haiqing and Bai, Donglin},
title = {{Quantifying electrostatic control of docking and binding energetics in functional Cx36 gap junctions}},
journal = {Communications biology},
year = {2026},
month = jun,
volume = {9},
number = {1},
pages = {815},
publisher = {Nature Publishing Group},
issn = {2399-3642},
doi = {10.1038/s42003-026-10464-w},
url = {https://doi.org/10.1038/s42003-026-10464-w},
pmid = {42277350},
pmcid = {PMC13269782}
}

RIS

TY - JOUR
AU - Wong, Robert S
AU - Song, Zhiyuan
AU - Zheng, Yu T
AU - Chen, Honghong
AU - Zhao, Haiqing
AU - Bai, Donglin
TI - Quantifying electrostatic control of docking and binding energetics in functional Cx36 gap junctions
T2 - Communications biology
J2 - Commun Biol
PY - 2026
DA - 2026/06/11
VL - 9
IS - 1
SP - 815
SN - 2399-3642
PB - Nature Publishing Group
DO - 10.1038/s42003-026-10464-w
UR - https://doi.org/10.1038/s42003-026-10464-w
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s42003-026-10464-w",
"type": "article-journal",
"title": "Quantifying electrostatic control of docking and binding energetics in functional Cx36 gap junctions",
"container-title": "Communications biology",
"author": [
{
"family": "Wong",
"given": "Robert S"
},
{
"family": "Song",
"given": "Zhiyuan"
},
{
"family": "Zheng",
"given": "Yu T"
},
{
"family": "Chen",
"given": "Honghong"
},
{
"family": "Zhao",
"given": "Haiqing"
},
{
"family": "Bai",
"given": "Donglin"
}
],
"container-title-short": "Commun Biol",
"volume": "9",
"issue": "1",
"page": "815",
"DOI": "10.1038/s42003-026-10464-w",
"PMID": "42277350",
"PMCID": "PMC13269782",
"ISSN": "2399-3642",
"publisher": "Nature Publishing Group",
"URL": "https://doi.org/10.1038/s42003-026-10464-w",
"language": "en",
"issued": {
"date-parts": [
[
2026,
6,
11
]
]
}
}

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.1038/s41586-026-10501-y [code]
Long-term editing of brain circuits using an engineered electrical synapse.
Journal: Nature
In common: seaborn, scikit-learn, pandas, 3 other tools, cellular / molecular, 10 references
[2] doi:10.1126/sciadv.aeg3223 [code]
The extreme diversity of retinal amacrine cells has deep evolutionary roots.
Journal: Science advances
In common: seaborn, scikit-learn, pandas, 3 other tools, cellular / molecular, 1 reference
[3] doi:10.7554/elife.103046 [code]
Dichotomy between extracellular signatures of active dendritic chemical synapses and gap junctions.
Journal: eLife
In common: Matplotlib, NumPy, cellular / molecular, 3 references
[4] doi:10.1038/s41467-026-76676-0 [code]
Determinants of functional burden pleiotropy and gene dosage responses across human traits.
Journal: Nature communications
In common: seaborn, scikit-learn, pandas, 3 other tools, cellular / molecular, 1 reference
[5] doi:10.1038/s41467-026-76675-1 [code]
Long-read proteogenomic atlas of human neuronal differentiation reveals isoform diversity informing neurodevelopmental risk mechanisms.
Journal: Nature communications
In common: seaborn, scikit-learn, pandas, 3 other tools, 1 reference
[6] doi:10.3389/fgene.2026.1799530 [code]
Sex-dependent prediction of autism.
Journal: Frontiers in genetics
In common: seaborn, scikit-learn, pandas, 3 other tools, 1 reference
[7] doi:10.7554/elife.105935
Uncovering the electrical synapse proteome in retinal neurons via in vivo proximity labeling.
Journal: eLife
In common: cellular / molecular, 3 references
[8] doi:10.3389/fnsys.2026.1753562
When the gatekeeper falls: developmental vulnerability of the thalamic reticular nucleus in neonatal and pediatric hypoxic-ischemic brain injury.
Journal: Frontiers in systems neuroscience
In common: 3 references
[9] doi:10.1038/s41398-026-04018-1
Loss of connexin 36 elicits abnormalities in thalamocortical network activity relevant to neuropsychiatric disorders.
Journal: Translational psychiatry
In common: 3 references
[10] doi:10.1016/j.xgen.2026.101280 [code]
BMI-genome interactions regulate global gene expression with emphasis in brain and gut.
Journal: Cell genomics
In common: scikit-learn, pandas, SciPy, 1 other tool, cellular / molecular, 1 reference

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.