OSCR

Causal Dynamics of Social Gaze in Primate Prefrontal-Amygdala Networks Revealed by Dynamic Bayesian Modeling.

Code ↔ Paper

2 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 2 matches
  1. [1] § Methods › Dynamic Bayesian network pipeline › Fitting dynamic Bayesian network models ↔ pgmpy/causal_discovery/HillClimbSearch.py, lines 16–131 · score 0.81 · hill climbing, directed acyclic graph, search algorithm, tabu, history, iterations
  2. [2] § Results › An algorithm for discovering causal dependencies in “super-sessions” ↔ pgmpy/models/LinearGaussianBayesianNetwork.py, lines 20–102 · score 0.52 · Gaussian noise, linear function, Bayesian Network, X3, X1, X2

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 · 259 lines · 10 KB · MIT · 1 match

  1. from collections import deque
  2. from collections.abc import Hashable
  3. import networkx as nx
  4. import pandas as pd
  5. from sklearn.base import clone
  6. from tqdm.auto import trange
  7. from pgmpy import config
  8. from pgmpy.base import DAG
  9. from pgmpy.causal_discovery import ExpertKnowledge
  10. from pgmpy.causal_discovery._base import BaseCausalDiscovery, _ScoreMixin
  11. from pgmpy.structure_score import BaseStructureScore, get_scoring_method
  12. class HillClimbSearch(_ScoreMixin, BaseCausalDiscovery):
  13. """
  14. Score-based causal discovery using hill climbing optimization.
  15. This class implements the HillClimbSearch algorithm [1] for causal discovery.
  16. Given a tabular dataset, the algorithm estimates the causal structure among
  17. the variables in the data as a Directed Acyclic Graph (DAG). The algorithm
  18. works by iteratively making local modifications to the graph structure
  19. (adding, removing, or reversing edges) and keeping changes that improve
  20. the score until a local maximum is reached.
  21. The algorithm is a greedy local search method that:
  22. 1. Starts from an initial graph (empty by default or based on provided expert knowledge).
  23. 2. Evaluates all possible single-edge modifications (add, delete, reverse).
  24. 3. Applies the modification with the highest score improvement.
  25. 4. Repeats until no improvement can be made.
  26. A tabu list is used to prevent the algorithm from immediately undoing recent
  27. changes, which helps avoid getting stuck in local optima.
  28. Parameters
  29. ----------
  30. scoring_method : str or BaseStructureScore instance, default=None
  31. The score to be optimized during structure estimation. Please refer :doc:`/api/structure_score` for a list of
  32. available scoring methods.
  33. If ``None``, the appropriate scoring method is automatically selected based on the data type. If a string is
  34. provided, the corresponding scoring method is instantiated with default parameters. To customize score-specific
  35. parameters, please pass an instance of the scoring class.
  36. start_dag : DAG instance, default=None
  37. The starting point for the local search. By default, a completely
  38. disconnected network (no edges) is used. If provided, the DAG must
  39. contain exactly the same variables as in the data.
  40. tabu_length : int, default=100
  41. The number of recent graph modifications to store in the tabu list.
  42. These modifications cannot be reversed during the search procedure.
  43. This serves to enforce a wider exploration of the search space.
  44. max_indegree : int or None, default=None
  45. If provided, the procedure only searches among models where all nodes
  46. have at most ``max_indegree`` parents. This can significantly reduce
  47. the search space and computation time for large graphs.
  48. expert_knowledge : ExpertKnowledge instance, default=None
  49. Expert knowledge to be used with the algorithm. Expert knowledge
  50. allows specification of:
  51. - Required edges that must be present in the final graph
  52. - Forbidden edges that cannot be present in the final graph
  53. - Temporal ordering of nodes
  54. return_type : str, default='pdag'
  55. The type of graph to return. Options are:
  56. - 'dag': Returns a directed acyclic graph (DAG).
  57. - 'pdag': Returns a partially directed acyclic graph (PDAG) where edges that
  58. could not be oriented are left undirected.
  59. epsilon : float, default=1e-4
  60. Defines the exit condition. If the improvement in score is less
  61. than ``epsilon``, the algorithm terminates and returns the learned model.
  62. max_iter : int, default=1e6
  63. The maximum number of iterations allowed. The algorithm terminates
  64. and returns the learned model when the number of iterations exceeds
  65. ``max_iter``.
  66. show_progress : bool, default=True
  67. If True, shows a progress bar while learning the causal structure.
  68. Attributes
  69. ----------
  70. causal_graph_ : DAG
  71. The learned causal graph as a DAG at a (local) score maximum.
  72. adjacency_matrix_ : pd.DataFrame
  73. Adjacency matrix representation of the learned causal graph.
  74. n_features_in_ : int
  75. The number of features in the data used to learn the causal graph.
  76. feature_names_in_ : np.ndarray
  77. The feature names in the data used to learn the causal graph.
  78. Examples
  79. --------
  80. Simulate some data to use for causal discovery:
  81. >>> from pgmpy.example_models import load_model
  82. >>> model = load_model("bnlearn/alarm")
  83. >>> df = model.simulate(n_samples=1000, seed=42)
  84. Use the HillClimbSearch algorithm to learn the causal structure from data:
  85. >>> from pgmpy.causal_discovery import HillClimbSearch
  86. >>> hc = HillClimbSearch(scoring_method="bic-d")
  87. >>> hc.fit(df)
  88. HillClimbSearch(scoring_method='bic-d')
  89. >>> _ = hc.causal_graph_.edges()
  90. Use expert knowledge to constrain the search:
  91. >>> from pgmpy.causal_discovery import ExpertKnowledge
  92. >>> expert = ExpertKnowledge(forbidden_edges=[("HISTORY", "CVP")])
  93. >>> hc = HillClimbSearch(scoring_method="bic-d", expert_knowledge=expert)
  94. >>> hc.fit(df) # doctest: +ELLIPSIS
  95. HillClimbSearch(expert_knowledge=ExpertKnowledge(...),
  96. scoring_method='bic-d')
  97. References
  98. ----------
  99. - :footcite:t:`koller_friedman_2009`
  100. """
  101. def __init__(
  102. self,
  103. scoring_method: str | BaseStructureScore | None = None,
  104. start_dag: DAG | None = None,
  105. tabu_length: int = 100,
  106. max_indegree: int | None = None,
  107. expert_knowledge: ExpertKnowledge | None = None,
  108. return_type: str = "pdag",
  109. epsilon: float = 1e-4,
  110. max_iter: int = int(1e6),
  111. show_progress: bool = True,
  112. ):
  113. self.scoring_method = scoring_method
  114. self.start_dag = start_dag
  115. self.tabu_length = tabu_length
  116. self.max_indegree = max_indegree
  117. self.expert_knowledge = expert_knowledge
  118. self.return_type = return_type
  119. self.epsilon = epsilon
  120. self.max_iter = max_iter
  121. self.show_progress = show_progress
  122. def _fit(self, X: pd.DataFrame):
  123. """
  124. The fitting procedure for the HillClimbSearch algorithm.
  125. Parameters
  126. ----------
  127. X : pd.DataFrame or np.ndarray
  128. The data to learn the causal structure from. If a numpy array is
  129. passed, then the column names would be integers from 0 to n_features-1.
  130. Returns
  131. -------
  132. self : pgmpy.causal_discovery.HillClimbSearch
  133. Returns the instance with the fitted attributes.
  134. """
  135. self.variables_ = list(X.columns)
  136. # Step 1: Initial checks and setup for arguments
  137. # Step 1.1: Check score
  138. score = get_scoring_method(self.scoring_method, X)
  139. # Step 1.2: Check the start_dag
  140. if self.start_dag is None:
  141. start_dag = DAG()
  142. start_dag.add_nodes_from(self.variables_)
  143. elif not isinstance(self.start_dag, DAG) or not set(self.start_dag.nodes()) == set(self.variables_):
  144. raise ValueError("'start_dag' should be a DAG with the same variables as the data set, or 'None'.")
  145. else:
  146. start_dag = self.start_dag.copy()
  147. # Step 1.3: Check if expert knowledge was specified
  148. if self.expert_knowledge is None:
  149. expert_knowledge = ExpertKnowledge()
  150. else:
  151. # Clone so the fitted (`*_`) attributes land on a fresh copy, not the user's object.
  152. expert_knowledge = clone(self.expert_knowledge)
  153. # Step 1.3.1: Resolve the expert knowledge into its fitted (`*_`) attributes.
  154. expert_knowledge.fit(X)
  155. # Step 1.4: Check if required edges cause a cycle
  156. start_dag.add_edges_from(expert_knowledge.required_edges_)
  157. if not nx.is_directed_acyclic_graph(start_dag):
  158. raise ValueError(
  159. "required_edges create a cycle in start_dag. Please modify either required_edges or start_dag."
  160. )
  161. start_dag.remove_edges_from(expert_knowledge.forbidden_edges_)
  162. # Step 1.5: Initialize max_indegree, tabu_list, and progress bar
  163. max_indegree = self.max_indegree
  164. if max_indegree is None:
  165. max_indegree = float("inf")
  166. tabu_list: deque[tuple[str, tuple[Hashable, Hashable]]] = deque(maxlen=self.tabu_length)
  167. current_model = start_dag
  168. if self.show_progress and config.SHOW_PROGRESS:
  169. iteration = trange(int(self.max_iter))
  170. else:
  171. iteration = range(int(self.max_iter))
  172. # Step 2: For each iteration, find the best scoring operation and
  173. # do that to the current model. If no legal operation is
  174. # possible, sets best_operation=None.
  175. for _ in iteration:
  176. best_operation, best_score_delta = max(
  177. self._legal_operations_dag(
  178. model=current_model,
  179. scoring_method=score,
  180. tabu_list=tabu_list,
  181. max_indegree=max_indegree,
  182. forbidden_edges=expert_knowledge.forbidden_edges_,
  183. required_edges=expert_knowledge.required_edges_,
  184. ),
  185. key=lambda t: t[1],
  186. default=(None, None),
  187. )
  188. if best_operation is None or best_score_delta < self.epsilon:
  189. break
  190. elif best_operation[0] == "+":
  191. current_model.add_edge(*best_operation[1])
  192. tabu_list.append(("-", best_operation[1]))
  193. elif best_operation[0] == "-":
  194. current_model.remove_edge(*best_operation[1])
  195. tabu_list.append(("+", best_operation[1]))
  196. elif best_operation[0] == "flip":
  197. X_node, Y_node = best_operation[1]
  198. current_model.remove_edge(X_node, Y_node)
  199. current_model.add_edge(Y_node, X_node)
  200. tabu_list.append(best_operation)
  201. # Step 3: Store results
  202. if self.return_type.lower() == "dag":
  203. self.causal_graph_ = current_model
  204. elif self.return_type.lower() == "pdag":
  205. self.causal_graph_ = current_model.to_pdag()
  206. else:
  207. raise ValueError(f"return_type must be one of: dag, pdag, or cpdag. Got: {self.return_type}")
  208. self.adjacency_matrix_ = self.causal_graph_.to_adjacency(
  209. encoding="binary", nodelist=list(self.causal_graph_.nodes())
  210. )
  211. return self

HillClimbSearch.py at commit fa42ee2, under MIT · at the source

Overview

Authors: Feng Xing1,2, Siqi Fan3,4, Olga Dal Monte3,5, Monika P. Jadi2,6,7, Steve W. C. Chang2,3,7,8, Anirvan S. Nandy2,3,7,8
  1. Inderdepartmental Neuroscience Program, Yale University,New Haven, CT USA
  2. Department of Neuroscience, Yale University,New Haven, CT USA
  3. Department of Psychology, Yale University,New Haven, CT USA
  4. The Rockefeller University,New York, NY USA
  5. Department of Psychology, University of Turin,Torino, Italy
  6. Department of Psychiatry, Yale University,New Haven, CT USA
  7. Wu Tsai Institute, Yale University,New Haven, CT USA
  8. Kavli Institute for Neuroscience, Yale University,New Haven, CT USA
Institutions: Yale University (United States); Rockefeller University (United States); University of Turin (Italy)
Journal: Nature communications, volume 17, issue 1, article 8306
Dates: received 8 August 2025; accepted 22 June 2026; published online 4 July 2026
Type: Research article · Language: English
License: CC BY-NC-ND
Identifiers: DOI 10.1038/s41467-026-75220-4 · PMID 42401542 · PMCID PMC13469456 · OpenAlex W4413109497
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: non-human primate (organism), systems (subfield)
Methods: Statistics, Single-unit activity, calcium imaging, Physiology & signal measures, Connectivity
Keywords: Social neuroscience, Social behaviour
MeSH: Amygdala*, Fixation, Ocular*, Prefrontal Cortex*, Social Behavior*, Algorithms, Animals, Bayes Theorem, Behavior, Animal, Macaca mulatta, Male (* major topic)
Topic: Memory and Neural Mechanisms (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Citations: not cited yet (Europe PMC); 65 references in the paper

Abstract

The abstract is not reproduced here: the paper's license (CC BY-NC-ND) does not allow it. Read it in the paper, at the publisher or on Europe PMC.

Repositories

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

pgmpy/pgmpy

License: MIT
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: fa42ee20e09488b10f9f556abed8ad415658ed05, 26 September 2026
Languages: Python (636), Jupyter (19), R (1)
Size: 828 files, 656 scripts
Software Heritage: archived
Found in: the text, “Fitting dynamic Bayesian network models”
Holds: README, license file, CITATION.cff, environment (pyproject.toml), tests, continuous integration, documentation, 19 notebooks
Tools: NumPy (165 files), pandas (149 files), NetworkX (58 files), scikit-learn (40 files), SciPy (22 files), PyTorch (9 files), Matplotlib (3 files), statsmodels (2 files), Pyro (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
658 files
At the source: github.com/pgmpy/pgmpy

Zenodo 20055775

License: CC-BY-4.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Languages: Jupyter (2), MATLAB (1)
Size: 6 files, 3 scripts
Software Heritage: not checked
Found in: “Code availability”
Holds: 2 notebooks
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Matplotlib (2 files), NumPy (2 files)
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)
3 files

Code availability statement

The paper has a code availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:

Read it in the paper: doi.org/10.1038/s41467-026-75220-4.

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

The paper has a data availability statement. Its license (CC BY-NC-ND) does not allow reproducing it here; in short, from what the harvester recognized in it:

  • no repository, dataset or request procedure was recognized in it

Read it in the paper: doi.org/10.1038/s41467-026-75220-4.

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, 10 MeSH terms, 3 funders, 60 references.

Cite

This paper

Xing, F., Fan, S., Dal Monte, O., Jadi, M. P., Chang, S. W. C., & Nandy, A. S. (2026). Causal Dynamics of Social Gaze in Primate Prefrontal-Amygdala Networks Revealed by Dynamic Bayesian Modeling. Nature communications, 17(1), 8306. https://doi.org/10.1038/s41467-026-75220-4

BibTeX

@article{xing2026causal,
author = {Xing, Feng and Fan, Siqi and Dal Monte, Olga and Jadi, Monika P. and Chang, Steve W. C. and Nandy, Anirvan S.},
title = {{Causal Dynamics of Social Gaze in Primate Prefrontal-Amygdala Networks Revealed by Dynamic Bayesian Modeling}},
journal = {Nature communications},
year = {2026},
month = jul,
volume = {17},
number = {1},
pages = {8306},
publisher = {Nature Publishing Group},
issn = {2041-1723},
doi = {10.1038/s41467-026-75220-4},
url = {https://doi.org/10.1038/s41467-026-75220-4},
pmid = {42401542},
pmcid = {PMC13469456}
}

RIS

TY - JOUR
AU - Xing, Feng
AU - Fan, Siqi
AU - Dal Monte, Olga
AU - Jadi, Monika P.
AU - Chang, Steve W. C.
AU - Nandy, Anirvan S.
TI - Causal Dynamics of Social Gaze in Primate Prefrontal-Amygdala Networks Revealed by Dynamic Bayesian Modeling
T2 - Nature communications
J2 - Nat Commun
PY - 2026
DA - 2026/07/04
VL - 17
IS - 1
SP - 8306
SN - 2041-1723
PB - Nature Publishing Group
DO - 10.1038/s41467-026-75220-4
UR - https://doi.org/10.1038/s41467-026-75220-4
LA - en
ER -

CSL-JSON

{
"id": "10.1038/s41467-026-75220-4",
"type": "article-journal",
"title": "Causal Dynamics of Social Gaze in Primate Prefrontal-Amygdala Networks Revealed by Dynamic Bayesian Modeling",
"container-title": "Nature communications",
"author": [
{
"family": "Xing",
"given": "Feng"
},
{
"family": "Fan",
"given": "Siqi"
},
{
"family": "Dal Monte",
"given": "Olga"
},
{
"family": "Jadi",
"given": "Monika P."
},
{
"family": "Chang",
"given": "Steve W. C."
},
{
"family": "Nandy",
"given": "Anirvan S."
}
],
"container-title-short": "Nat Commun",
"volume": "17",
"issue": "1",
"page": "8306",
"DOI": "10.1038/s41467-026-75220-4",
"PMID": "42401542",
"PMCID": "PMC13469456",
"ISSN": "2041-1723",
"publisher": "Nature Publishing Group",
"URL": "https://doi.org/10.1038/s41467-026-75220-4",
"language": "en",
"issued": {
"date-parts": [
[
2026,
7,
4
]
]
}
}

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/s41467-026-74347-8 [code]
Compositionality of social gaze in the prefrontal-amygdala circuits.
Journal: Nature communications
In common: statsmodels, scikit-learn, pandas, 3 other tools, non-human primate, systems, 7 references, author Steve W. C. Chang
[2] doi:10.1523/eneuro.0362-25.2026 [code]
Similarities between &lt;i&gt;Ciona&lt;/i&gt; Dorsal Motor Ganglion and Vertebrate Cerebellum: Did a Chordate Ancestor Already Show D/V Subdivision within a Hindbrain Precursor?
Journal: eNeuro
In common: Pyro, statsmodels, PyTorch, 5 other tools
[3] doi:10.1038/s41467-026-74694-6 [code]
Semi-supervised Omics Factor Analysis (SOFA) disentangles known and latent sources of variation in multi-omic data.
Journal: Nature communications
In common: Pyro, statsmodels, PyTorch, 5 other tools
[4] doi:10.1093/bioinformatics/btag652 [code]
mmVelo: a deep generative model for estimating cell state-dependent dynamics across multiple modalities.
Journal: Bioinformatics (Oxford, England)
In common: Pyro, statsmodels, PyTorch, 5 other tools
[5] doi:10.1038/s41593-026-02205-3 [code]
Competitive interactions shape mammalian brain network dynamics and computation.
Journal: Nature neuroscience
In common: NetworkX, PyTorch, scikit-learn, 4 other tools, non-human primate, 1 reference
[6] doi:10.1038/s42003-026-09794-6 [code]
The role of dorsal anterior cingulate cortex in dynamic attitude changes in naturalistic settings.
Journal: Communications biology
In common: NetworkX, statsmodels, scikit-learn, 4 other tools, systems, 1 reference
[7] doi:10.17879/freeneuropathology-2026-9413 [code]
Mass spectrometry imaging-based explainable machine learning reveals the biochemical landscapes of the mouse brain.
Journal: Free neuropathology
In common: Pyro, NetworkX, PyTorch, 4 other tools
[8] doi:10.1038/s41467-026-72057-9 [code]
Sex-specific behavioral feedback modulates sensorimotor processing and drives flexible social behavior.
Journal: Nature communications
In common: statsmodels, PyTorch, scikit-learn, 4 other tools, systems, 1 reference
[9] doi:10.1016/j.isci.2026.117375 [code]
Motor priming is associated with widespread recruitment into neural ensembles and more rapid ensemble transitions.
Journal: iScience
In common: NetworkX, statsmodels, PyTorch, 5 other tools, systems
[10] doi:10.1016/j.isci.2026.116825 [code]
Social hierarchy shapes behavioral and transcriptional responses to chronic stress and ketamine in male mice.
Journal: iScience
In common: NetworkX, statsmodels, PyTorch, 5 other tools, systems

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.