We develop a method to infer Corpus-Wide Causal Score (CWCS) of a gene-disease (G-D) pair by integrating two pieces of evidence: (i) network-based causal signals in a prior gene regulatory network, quantified as a CWCS-Net score using an existing multilayer network centrality algorithm; and (ii) corpus-wide literature evidence, quantified as a CWCS-TD (TD for Truth Discovery) score using a newly-developed TD algorithm.
CWCS/
├── application/ # Real-world application
│ ├── AD/ # Alzheimer's disease
│ │ ├── run_AD.py # Entry point
│ │ ├── AD_complete_data_with_omim_rich.tsv # Bibliometric + predictions corpus
│ │ └── result_data_v17.csv # Gene scores per disease
│ └── PD/ # Parkinson's disease
│ ├── run_PD.py
│ ├── PD_complete_data_with_omim_rich.tsv
│ └── result_data_v17.csv
│
├── code/ # Source code
│ ├── cwcs_clean.py # Main pipeline (algorithm + evaluation + LLM)
│ ├── calculate_pagerank_rrf.py # Graph building & data loading
│ ├── cwcs_simulation.py # Standalone simulation
│ ├── generating_tables.py # Generate tables of manuscript
│ ├── AD_complete_data_generation.ipynb # Generate AD data (PubMed -> Pubtator -> BioBERT+SVM -> bibliometrics)
│ ├── PD_complete_data_generation.ipynb # Same pipeline for PD
│ ├── CWCS_TD.ipynb # CWCS-TD truth-discovery: learns reliability weights (beta) and per-gene VQ*
│ ├── LLM_Inference_All_disease.ipynb
│
│
├── data/ # Shared input data (OMIM validation corpus)
│ ├── complete_data_bibliometrics_with_all_diseases_biobert_svm_prediction_updated.tsv
│ ├── cred_doc_causality_with_preds.csv # CRED-labeled sentences with BioBERT+SVM predictions (input for CWCS_TD)
│ └── omnipath_gene_regulatory_network.tsv # Originally based on OmniPath data, but here mentioned a simulated network due to OmniPath redistribution restrictions.
│
├── results/ # OMIM validation results (10 diseases)
│ ├── cwcs_output/
│ │ ├── result_data_v17.csv # Gene scores per disease (from main)
│ │ ├── precision_recall_curve.png # PR curve, individual methods (from main)
│ │ ├── recall_at_k_curve.png # Recall@K, individual methods (from main)
│ │ ├── pr_curve_RRF_fusion.png # PR curve, RRF fusion variants (from evaluate)
│ │ ├── recall_at_k_RRF_fusion.png # Recall@K, RRF fusion variants (from evaluate)
│ │ ├── final_results_RRF_fusion.csv # Scaled scores for all methods + RRF variants (from evaluate)
│ │ └── overall_classification_matrix_RRF_fusion.csv # Per-method Precision/Recall/F1/PR-AUC at optimal threshold (from evaluate)
│ └── llm_results/ # GPT-4o and MMedLlama-3 baselines
│ ├── GPT-4o_results.csv # Causal score per gene-disease pair (with-CRED)
│ ├── GPT-4o_logs.jsonl # Raw GPT-4o JSON responses (audit trail)
│ ├── MMedLlama_3_results.csv # MMedLlama-3 causal scores
│ └── MMedLlama_3_logs.jsonl # Raw MMedLlama-3 responses (audit trail)
│
├── requirements.txt
├── LICENSE
└── README.md
git clone https://github.com/BIRDSgroup/CWCS.git
cd CWCS
pip install -r requirements.txtTwo external data sources are used by the pipeline. Neither is redistributed in this repository — data/omnipath_gene_regulatory_network.tsv is shipped as a 3-edge placeholder so the code runs out of the box; reproduce the full pipeline as follows.
The full OmniPath gene-gene network is fetched directly from the OmniPath REST API. The query, filtering, and normalisation logic are encapsulated in fetch_omnipath_network() inside code/calculate_pagerank_rrf.py.
# From the project root, in Python:
import pandas as pd
from code.calculate_pagerank_rrf import fetch_omnipath_network
# Use the gene set from the bibliometric corpus
df = pd.read_csv(
'data/complete_data_bibliometrics_with_all_diseases_biobert_svm_prediction_updated.tsv',
sep='\t'
)
unique_genes = df['Symbol'].dropna().astype(str).unique()
fetch_omnipath_network(unique_genes, 'data/omnipath_gene_regulatory_network.tsv')URL and query parameters used:
https://omnipathdb.org/interactions
?datasets=tf_target,omnipath,pathwayextra,kinaseextra
&directed=1
&genesymbols=1
&fields=sources
&format=tsv
The downloaded interactions are filtered to genes present in unique_genes, and the per-edge n_sources (number of databases agreeing on the interaction) is normalised to a confidence score in (0, 1] via score = n_sources / max(n_sources). The resulting file overwrites the placeholder at data/omnipath_gene_regulatory_network.tsv with three columns: source_gene, target_gene, score.
The OMIM positive labels (the label column in the bibliometric TSVs) come from genemap2.txt, which is access-gated — you must register and obtain download permission at:
https://omim.org/downloads
Once approved, OMIM provides a personalised download link to fetch genemap2.txt. Place the file alongside the bibliometric TSV and merge it as follows:
- Parse
genemap2.txtto extract(MIM Number, Gene Symbol, Phenotype)rows for each of the 10 validation diseases (and for AD/PD in the rich corpora). - For each row in the bibliometric TSV, set
label = 1if the geneSymbolappears in the OMIM gene list for that disease's MIM phenotype, otherwiselabel = 0. - Save the merged TSV. The bibliometric files in
data/andapplication/{AD,PD}/already include the mergedlabelcolumn.
The merge step is documented in code/AD_complete_data_generation.ipynb and code/PD_complete_data_generation.ipynb. The same procedure was applied to all 10 diseases in the OMIM validation corpus.
cd application/AD
python run_AD.pyWrites result_data_v17.csv next to run_AD.py.
cd application/PD
python run_PD.pycd code
python cwcs_clean.pyWrites to results/cwcs_output/:
result_data_v17.csv— per-gene scores (MultiCens, VQ*, Fusion_RRF, labels)precision_recall_curve.png— PR curves comparing individual methods (CWCS-Net, CWCS-TD, Fusion_RRF, Causal_Ratio, GPT-4o, MMedLlama-3)recall_at_k_curve.png— Recall@K for the same set of individual methods
cd code
python cwcs_clean.py evaluateReads results/cwcs_output/result_data_v17.csv (from the previous step), computes four RRF-fusion combinations (CWCS-Net+CWCS-TD, CWCS-Net+CausalRatio, CWCS-Net+GPT-4o, CWCS-Net+MMedLlama-3) after QuantileTransformer/MinMaxScaler normalization, then writes:
pr_curve_RRF_fusion.png— PR curves for the four RRF-fusion variantsrecall_at_k_RRF_fusion.png— Recall@K for the same four variantsfinal_results_RRF_fusion.csv— scaled scores for every method and RRF fusion variantoverall_classification_matrix_RRF_fusion.csv— per-method global Precision, Recall, F1, and PR-AUC at the optimal F1 threshold
export AZURE_OPENAI_API_KEY="your-key"
cd code
python cwcs_clean.py llmfrom cwcs_simulation import run_simulation
scores = run_simulation(
gd_edges=[("GeneA", "Disease1", 0.8), ("GeneB", "Disease1", 0.7)],
gg_edges=[("GeneC", "GeneB", 0.6)],
seed_genes=["GeneA, GeneB"],
omega=0.5, p=0.75,
)GNU General Public License v3.0 - see LICENSE.