OSCR

Selective perturbation of mirror and non-mirror neurons in an in silico model of the action observation network.

Code ↔ Paper

The paper beside its authors' code: matches between them have not been computed for this paper yet.

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 · 199 lines · 6.9 KB · MIT

  1. import os, time, json
  2. import argparse
  3. from pathlib import Path
  4. import numpy as np
  5. import scipy.io as sio
  6. import scipy.ndimage as ndi
  7. import tensorflow as tf
  8. from rnn_rate_tf2 import RNNRateTF2
  9. os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
  10. tf.random.set_seed(42); np.random.seed(42)
  11. def save_json(path, obj):
  12. with open(path, 'w') as f:
  13. json.dump(obj, f, indent=2)
  14. def load_inhibitory_mask(path):
  15. D = sio.loadmat(path)
  16. inh = D.get('inhibitory')
  17. if inh is None:
  18. raise KeyError("Key 'inhibitory' not found in InhibitoryMask.mat")
  19. inh = np.asarray(inh).astype(np.float32).reshape(-1)
  20. return inh
  21. def parse_args():
  22. p = argparse.ArgumentParser()
  23. p.add_argument('--firing_rates_mat', type=str, required=True)
  24. p.add_argument('--inhibitory_mask_mat', type=str, required=True)
  25. p.add_argument('--mode', choices=['train','eval'], default='train')
  26. p.add_argument('--n_trials', type=int, default=100000)
  27. p.add_argument('--learning_rate', type=float, default=1e-3)
  28. p.add_argument('--loss_fn', type=str, default='l2')
  29. p.add_argument('--output_dir', type=str, default='out_tf2')
  30. p.add_argument('--N1', type=int, default=86)
  31. p.add_argument('--N2', type=int, default=106)
  32. p.add_argument('--N3', type=int, default=163)
  33. p.add_argument('--thermal', type=int, default=100)
  34. return p.parse_args()
  35. def load_exp_data(fr_path):
  36. mat = sio.loadmat(fr_path)
  37. Exp = {}
  38. for i in range(1,13):
  39. key = f'FR{i}'
  40. if key not in mat:
  41. raise KeyError(f'{key} missing in {fr_path}')
  42. Exp[key] = np.asarray(mat[key]).astype(np.float32)
  43. return Exp, mat
  44. def build_stim_and_IC(FR_mat, N, thermal, inputF5=0.5):
  45. if 'FR1' not in FR_mat:
  46. raise KeyError('FR1 missing in .mat; cannot infer T')
  47. T_model = 700
  48. T_total = int(thermal) + T_model
  49. sound_on = 100 + thermal
  50. sound_dur = 360
  51. light_on = 260 + thermal
  52. delay_sound = 20
  53. delay_sound_off = 20
  54. delay_object = 20
  55. stim = np.zeros((6, 10, T_total), dtype=np.float32)
  56. cue_on = int(np.ceil(sound_on + delay_sound))
  57. cue_off = int(np.ceil(sound_on + sound_dur + delay_sound_off))
  58. obj_on = int(np.ceil(light_on + delay_object))
  59. stim[0:2, 0, cue_on:cue_off] = 1.0
  60. stim[3:5, 4, cue_on:cue_off] = 1.0
  61. stim[0:2, 5, cue_on:cue_off] = inputF5
  62. stim[3:5, 9, cue_on:cue_off] = inputF5
  63. stim[0, 1, obj_on:] = 1.0; stim[3, 1, obj_on:] = 1.0
  64. stim[1, 2, obj_on:] = 1.0; stim[4, 2, obj_on:] = 1.0
  65. stim[2, 3, obj_on:] = 1.0; stim[5, 3, obj_on:] = 1.0
  66. stim[0, 6, obj_on:] = inputF5; stim[3, 6, obj_on:] = inputF5
  67. stim[1, 7, obj_on:] = inputF5; stim[4, 7, obj_on:] = inputF5
  68. stim[2, 8, obj_on:] = inputF5; stim[5, 8, obj_on:] = inputF5
  69. sigma_gauss = 20
  70. stim = ndi.gaussian_filter1d(stim, sigma_gauss, axis=-1)
  71. for j in range(10):
  72. for c in range(6):
  73. stim[c, j, :] = ndi.gaussian_filter1d(stim[c, j, :], sigma_gauss)
  74. stim += np.random.normal(0.0, 0.005, size=stim.shape).astype(np.float32)
  75. IC_r = []; IC_x = []
  76. for i in range(1, 13):
  77. key_r = f'IC_FR{i}'; key_x = f'IC_X{i}'
  78. if key_r in FR_mat and key_x in FR_mat:
  79. r0 = np.asarray(FR_mat[key_r]).astype(np.float32).reshape(N,1)
  80. x0 = np.asarray(FR_mat[key_x]).astype(np.float32).reshape(N,1)
  81. else:
  82. r0 = np.zeros((N,1), dtype=np.float32)
  83. x0 = np.zeros((N,1), dtype=np.float32)
  84. IC_r.append(r0); IC_x.append(x0)
  85. IC_r = np.stack(IC_r, axis=0); IC_x = np.stack(IC_x, axis=0)
  86. return stim, IC_r, IC_x
  87. def main():
  88. args = parse_args()
  89. outdir = Path(args.output_dir); outdir.mkdir(parents=True, exist_ok=True)
  90. save_json(outdir/'config.json', vars(args))
  91. Exp_Data_np, raw = load_exp_data(args.firing_rates_mat)
  92. N = int(Exp_Data_np['FR1'].shape[0])
  93. Inib = load_inhibitory_mask(args.inhibitory_mask_mat)
  94. if Inib.shape[0] != N:
  95. raise ValueError(f'Inhibitory mask length {Inib.shape[0]} != N={N}')
  96. stim_np, IC_r_np, IC_x_np = build_stim_and_IC(raw, N, args.thermal)
  97. Exp_Data = {k: tf.convert_to_tensor(v) for k,v in Exp_Data_np.items()}
  98. stim = tf.convert_to_tensor(stim_np) # [6,10,T_total]
  99. IC_r = tf.convert_to_tensor(IC_r_np) # [12,N,1]
  100. IC_x = tf.convert_to_tensor(IC_x_np) # [12,N,1]
  101. model = RNNRateTF2(N, args.N1, args.N2, args.N3, w_dist='gaus', gain=1.0, apply_dale=True, Inib=Inib)
  102. opt = tf.keras.optimizers.Adam(learning_rate=args.learning_rate)
  103. DeltaT = tf.constant(1.0, tf.float32)
  104. @tf.function
  105. def train_step():
  106. with tf.GradientTape() as tape:
  107. rates = model.forward(stim, IC_r, IC_x, DeltaT)
  108. loss = model.loss(
  109. rates, Exp_Data,
  110. thermal=args.thermal, window_size=4, loss_type=args.loss_fn
  111. )
  112. vars_ = [model.W, model.W_in, model.W_in2, model.I_ext, model.taus_param]
  113. grads = tape.gradient(loss, vars_)
  114. # --- Gradient clipping (recommended default) ---
  115. CLIP_NORM = 1.0
  116. grads, _ = tf.clip_by_global_norm(grads, CLIP_NORM)
  117. opt.apply_gradients(zip(grads, vars_))
  118. # Enforce Dale's law after the update
  119. if model.apply_dale:
  120. model.project_dale()
  121. return loss
  122. @tf.function
  123. def eval_step():
  124. rates = model.forward(stim, IC_r, IC_x, DeltaT)
  125. loss = model.loss(rates, Exp_Data, thermal=args.thermal, window_size=4, loss_type=args.loss_fn)
  126. return loss
  127. ckpt = tf.train.Checkpoint(step=tf.Variable(0), optimizer=opt, model=model)
  128. manager = tf.train.CheckpointManager(ckpt, directory=str(outdir), max_to_keep=3)
  129. if args.mode == 'train':
  130. best = None
  131. # --- Early stopping settings (no CLI flags by design) ---
  132. TARGET_LOSS = 1.00 # stop immediately once we reach this value
  133. PATIENCE = 200 # stop if no improvement for this many steps
  134. patience_left = PATIENCE
  135. for it in range(1, args.n_trials + 1):
  136. l = train_step()
  137. lval = float(l.numpy())
  138. ckpt.step.assign_add(1)
  139. improved = (best is None) or (lval < best - 1e-6)
  140. if improved:
  141. best = lval
  142. patience_left = PATIENCE
  143. # Save occasionally when improving (keeps I/O reasonable)
  144. if it % 50 == 0:
  145. manager.save()
  146. else:
  147. patience_left -= 1
  148. if it % 10 == 0:
  149. print(f"[{it}/{args.n_trials}] loss={lval:.6f} best={best:.6f}", flush=True)
  150. # --- Early stop rules ---
  151. if lval <= TARGET_LOSS:
  152. print(f"Early stop: target loss {TARGET_LOSS} reached at step {it}.")
  153. break
  154. if patience_left <= 0:
  155. print(f"Early stop: no improvement for {PATIENCE} steps (best={best:.6f}).")
  156. break
  157. # Final checkpoint on exit
  158. manager.save()
  159. if __name__ == '__main__':
  160. main()

main_tf2.py at commit 9a38298, under MIT · at the source

Overview

Authors: Luca Guglielmi1,2, Davide Albertini3, Alessandro Vezzani1,2,4, Raffaella Burioni1,2, Luca Bonini3
  1. Department of Mathematical, Physical and Computer Sciences, University of Parma, Parma, Italy
  2. INFN - Parma Unit, Parma, Italy
  3. Department of Medicine and Surgery, University of Parma, Parma, Italy
  4. IMEM-CNR, Parma, Italy
Journal: iScience, volume 29, issue 8, article 116776
Dates: received 24 November 2025; accepted 26 June 2026; published online 17 July 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1016/j.isci.2026.116776 · PMID 42502406 · PMCID PMC13401003 · OpenAlex W7169604007
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: computational modeling (no new data) (modality), computational (subfield)
Methods: Statistics, Graphs, Single-unit activity, calcium imaging, Machine learning
Keywords: recurrent neural network, mirror neuron, action observation, motor system, computational modeling
Topic: Action Observation and Synchronization (Social Psychology, Psychology), according to OpenAlex
Funding: Ministry of University and Research; National Recovery and Resilience Plan; MNESYS (PE0000006); European Research Council (678307); ERC (CoG-2020); EMACTIVE (101002704); MUR “CIRCEM” (R20NJ7BBA7)
Citations: not cited yet (Europe PMC); 95 references in the paper
Research resources: MATLAB R2024a RRID:SCR_001622, Python RRID:SCR_008394, TensorFlow RRID:SCR_016345

Abstract

The action observation network (AON) is a distributed system of brain areas containing mirror neurons (MNs), active during both action execution and observation, as well as purely motor, non-mirror neurons. Here, we present a biologically inspired recurrent neural network (RNN) model trained to reproduce single-neuron activity from three key macaque AON areas—anterior intraparietal area (AIP), areas F5 and F6. The model accurately captured experimental firing patterns and enabled the reconstruction of candidate functional connectivity. Cell-type-specific in silico silencing revealed that inhibitory interneurons exert a strong influence on network function, with those in F5 and F6 contributing to agent identity discrimination. Silencing excitatory non-mirror neurons in F5 and F6 produced larger reductions in self-action decoding performance, whereas silencing excitatory MNs in AIP preferentially impacted the decoding of others’ actions. These findings provide a computational framework for linking cell-type-specific perturbations to population-level action representations in the AON.

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

Repositories

Its files are read in the Code ↔ Paper reader above.

lucaguglielmi97/AON_RNN

License: MIT
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: 9a382989b3121a172550f29c82f9b0059ea511df, 9 October 2025
Languages: Python (2)
Size: 8 files, 2 scripts
Software Heritage: not archived
Found in: “Data and code availability”
Holds: README, license file
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NumPy (2 files), TensorFlow (2 files), SciPy (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
4 files

tensorflow.org/;rrid:scr_016345

License: none: the authors keep all their rights
State: the link is dead, verified on 27 September 2026
Evidence: found in the paper
Software Heritage: not checked
Found in: the text, “Key resources table”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 27 September 2026: the link is dead (HTTP 404)
  • 27 September 2026: the link is dead (HTTP 404)

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 2 scripts, each with its path and the digest of its content;
  • no match between paragraphs and code yet;
  • 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 and code availability

• The experimental dataset used for model training and validation is publicly available in a work by Tili et al.29 • Custom code used to implement, train, and simulate the RNN model in Python using TensorFlow is publicly available on GitHub: https://github.com/lucaguglielmi97/AON_RNN. • Any additional information required to reanalyze the data reported in this paper is available from the lead contact upon request.

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 2, 28 September 2026

  • Authors: added Luca Guglielmi (0000-0002-2905-442X); removed Luca Guglielmi

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 5 authors, 5 keywords, 7 funders, 93 references, 3 RRIDs.

Cite

This paper

Guglielmi, L., Albertini, D., Vezzani, A., Burioni, R., & Bonini, L. (2026). Selective perturbation of mirror and non-mirror neurons in an in silico model of the action observation network. iScience, 29(8), 116776. https://doi.org/10.1016/j.isci.2026.116776

BibTeX

@article{guglielmi2026selective,
author = {Guglielmi, Luca and Albertini, Davide and Vezzani, Alessandro and Burioni, Raffaella and Bonini, Luca},
title = {{Selective perturbation of mirror and non-mirror neurons in an in silico model of the action observation network}},
journal = {iScience},
year = {2026},
month = jul,
volume = {29},
number = {8},
pages = {116776},
publisher = {Elsevier},
issn = {2589-0042},
doi = {10.1016/j.isci.2026.116776},
url = {https://doi.org/10.1016/j.isci.2026.116776},
pmid = {42502406},
pmcid = {PMC13401003}
}

RIS

TY - JOUR
AU - Guglielmi, Luca
AU - Albertini, Davide
AU - Vezzani, Alessandro
AU - Burioni, Raffaella
AU - Bonini, Luca
TI - Selective perturbation of mirror and non-mirror neurons in an in silico model of the action observation network
T2 - iScience
J2 - iScience
PY - 2026
DA - 2026/07/17
VL - 29
IS - 8
SP - 116776
SN - 2589-0042
PB - Elsevier
DO - 10.1016/j.isci.2026.116776
UR - https://doi.org/10.1016/j.isci.2026.116776
LA - en
ER -

CSL-JSON

{
"id": "10.1016/j.isci.2026.116776",
"type": "article-journal",
"title": "Selective perturbation of mirror and non-mirror neurons in an in silico model of the action observation network",
"container-title": "iScience",
"author": [
{
"family": "Guglielmi",
"given": "Luca"
},
{
"family": "Albertini",
"given": "Davide"
},
{
"family": "Vezzani",
"given": "Alessandro"
},
{
"family": "Burioni",
"given": "Raffaella"
},
{
"family": "Bonini",
"given": "Luca"
}
],
"container-title-short": "iScience",
"volume": "29",
"issue": "8",
"page": "116776",
"DOI": "10.1016/j.isci.2026.116776",
"PMID": "42502406",
"PMCID": "PMC13401003",
"ISSN": "2589-0042",
"publisher": "Elsevier",
"URL": "https://doi.org/10.1016/j.isci.2026.116776",
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
17
]
]
}
}

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.1126/sciadv.aed9309 [code]
Dynamic population coding of kinematic structure across executed and observed actions in primate premotor cortex.
Journal: Science advances
In common: 12 references
[2] doi:10.1371/journal.pbio.3003831 [code]
Disinhibitory signaling enables flexible coding of top-down information in cortical networks.
Journal: PLoS biology
In common: TensorFlow, SciPy, NumPy, 9 references
[3] doi:10.1016/j.neuron.2026.07.016 [code]
Inferring brain-wide interactions using data-constrained recurrent neural network models.
Journal: Neuron
In common: NumPy, computational modeling (no new data), 9 references
[4] doi:10.1038/s41467-026-71725-0 [code]
Interactions across hemispheres in prefrontal cortex reflect global cognitive processing.
Journal: Nature communications
In common: SciPy, NumPy, 5 references
[5] doi:10.3390/biomimetics11080569 [code]
Pretraining of Embodied Recurrent Networks Bridges the Gap Between Artificial and Cortical Neural Activities.
Journal: Biomimetics (Basel, Switzerland)
In common: SciPy, NumPy, 5 references
[6] doi:10.1371/journal.pcbi.1014162 [code]
Exploring neural manifolds across a wide range of intrinsic dimensions.
Journal: PLoS computational biology
In common: TensorFlow, SciPy, NumPy, computational, 3 references
[7] doi:10.1038/s41540-026-00727-x [code]
Association-sensory spatiotemporal hierarchy and functional gradient-regularised recurrent neural network with implications for schizophrenia.
Journal: NPJ systems biology and applications
In common: SciPy, NumPy, computational, 4 references
[8] doi:10.1038/s41467-026-75924-7 [code]
Data-driven reduced modeling of neural dynamics.
Journal: Nature communications
In common: SciPy, NumPy, computational modeling (no new data), 4 references
[9] doi:10.1371/journal.pone.0351053 [code]
Distinct roles of neuronal phenotypes during neurofeedback adaptation.
Journal: PloS one
In common: SciPy, NumPy, 4 references
[10] doi:10.7554/elife.107423 [code]
A context-free model of savings in motor learning.
Journal: eLife
In common: SciPy, NumPy, 4 references

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

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.