# CraftGRN: inferring gene regulatory networks from ATAC and RNA data

> CraftGRN is an R package that combines chromatin accessibility from ATAC-seq with matched RNA-seq to infer condition-specific transcription factor binding sites and build regulatory networks, organized as three modules ending in topic modeling and differential network comparison. It is a research tool in pre-publication status, not a finished product.

**oncologylab/craftgrn** — Combined RNA and ATAC Footprint Training of Gene Regulatory Network

- Repository: https://github.com/oncologylab/craftgrn
- Website: https://oncologylab.github.io/craftgrn/
- Stars: 583 · Forks: 4
- Language: R
- License: GPL-3.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/oncologylab-craftgrn

## Footprints and expression are combined to place binding sites

CraftGRN is described as a modular framework for integrating chromatin accessibility profiles from ATAC-seq with matched RNA-seq expression data to infer condition-specific transcription factor binding sites and reconstruct dynamic gene regulatory networks.

The word matched is doing the work. The method's core idea is that a footprint in accessible chromatin is weak evidence on its own, because footprints appear wherever a factor happens to bind without necessarily doing anything regulatory. Correlating that footprint with the expression of the factor that put it there is what turns a footprint into a candidate binding site, and correlation with the expression of nearby genes is what turns a binding site into a regulatory link.

The list of what the package helps users do is explicit. Collapse overlapping TF motif footprints into consensus, site- and motif-nonredundant footprint clusters. Infer condition-specific canonical and non-canonical TF binding sites by correlating TF expression with footprint or chromatin accessibility scores. Refine TF to TFBS to gene regulatory priors using enhancer-gene maps, genomic proximity, or user-supplied chromatin interaction data. Extract active regulatory links within each condition and compare links between conditions. Learn regulatory topics from RNA and footprint signals using topic modeling and VAE-based representations. And generate summaries and visualizations for topic- and condition-specific regulatory programs.

The two last items, the topic modeling and the condition comparison, are what make this more than a network inference script. A gene regulatory network on its own is a hairball. Partitioning the links into topics and then comparing which topics are active in which condition is what produces something a biologist can read, and that is also where the choice of algorithm matters most.

## Module 1 predicts binding sites and writes its own QC report

The pipeline is organized as a three-module workflow, and the module boundaries are where the data flow becomes legible.

Module 1, Predict TF Binding Sites, loads matched ATAC, RNA, metadata, and optional footprint score files, then prepares a multiomic data object for downstream regulatory analysis. Three primary functions do the work.

`load_prep_multiomic_data()` loads, filters, aligns, and prepares the multiomic inputs from a YAML configuration file, and when outputs are enabled it also writes `01_fp_scores_qn_<db>.csv`, the quantile-normalized footprint score matrix that is used downstream. So the first function is also the step where footprint scores get normalized, and the normalized matrix is the artifact the rest of the pipeline consumes.

`predict_tfbs()` performs direct-bound footprint filtering and TF binding site prediction across matched conditions. The direct-bound filtering is the gate that removes footprints whose factor is not actually expressed, which is the mechanism described in the introduction as inferring canonical and non-canonical binding sites by correlating TF expression with footprint or accessibility scores.

`build_module1_qc_report()` writes an HTML QC report covering run parameters, input gates, canonical support, correlation diagnostics, predicted TFBS chunk integrity, top TFs and FPs, condition support, warning checks, and related Module 1 artifacts. The report uses multiple static plot types, including processing funnels, density curves, scatter summaries, heatmaps, lollipop rank plots, and cumulative curves.

The existence of a QC report per module is a design decision that says something about the intended audience. The package is built for people running a multi-condition analysis where a silent failure in one condition would be easy to miss, and the report makes the funnel from raw footprints to predicted sites visible rather than leaving it as a log line.

## Module 2 links binding sites to genes, and filters by evidence

Module 2, Connect TFs to Target Genes, is where a binding site becomes a regulatory link. The README says it links TF binding sites to candidate target genes using enhancer-gene maps, genomic distance windows, or 3D chromatin interaction priors, and that candidate TF to TFBS to target links are filtered by condition-specific expression, binding, footprint or peak signal, and cross-condition correlation evidence.

That list of filters is the substance of the module. A candidate link has to survive several independent kinds of evidence, and the sources of that evidence are different in kind: expression, binding, and footprint or peak signal are measured in your own data, while genomic proximity and 3D interactions are priors about where a link is plausible. A prior that comes from an enhancer-gene map is not the same as a footprint that sits in your sample, and a good analysis keeps that distinction visible.

`predict_tf_targets()` does the work, taking predicted TFBS, TF-target correlations, FP-target correlations, genomic proximity, and optional regulatory priors. The mention of FP is worth pausing on. In this pipeline a footprint is a candidate factor binding, so an FP is a footprint whose factor is not confirmed, and the module computes correlations for both confirmed TFs and footprints, which means a link can be supported by the footprint evidence even where the TF assignment is less certain.

`build_module2_qc_report()` writes a compact HTML review with Module 1-style navigation and tabs for handoff checks, per-condition QC, TF-target and FP-target evidence, candidate source and distance-to-TSS evidence, final-link integrity, and top TF and target-gene summaries. The README notes that detailed values, manifests, warnings, and related reports remain available in a technical appendix, which is the right way to keep the summary readable and the detail retrievable.

## Module 3 turns links into topics, then compares conditions

Module 3 is where the output stops being a network. It compares condition-specific regulatory links, builds joint RNA and footprint document-term matrices, trains topic models, assigns regulatory links to topics, and summarizes pathway and master TF programs.

The functions are broken into small steps on purpose. `module3_prepare_differential_links()` prepares filtered differential links from Module 2 predicted links and condition comparisons. `module3_construct_docs()` builds reusable topic-document, document-term, and sparse matrix caches for step-by-step inspection. `module3_train_topic_models()` trains regulatory topic models across a user-defined topic number. And `run_topic_modeling()` runs one selected Module 3 topic-document method with a flat standard output layout, compact topic-link outputs, and a QC report.

The existence of a caching step with an explicit purpose of step-by-step inspection is a strong hint about who this is for. A topic model over regulatory links is the kind of analysis where you will want to look at the document-term matrix before trusting the topics, and to rerun the training with a different K without rebuilding the caches. The README says the selected method, K value or K grid, WarpLDA iterations, and topic-link output mode can all be stored in the project YAML config, so those choices are recorded with the project rather than buried in a script.

The presence of WarpLDA in that list is worth a reader's attention. Topic modeling on regulatory links is close to the classic document-word problem, and WarpLDA is a scalable variant of LDA, so the method is a reasonable fit for a matrix of this shape. The README does not describe the alternative methods in detail, so the choice of algorithm is one the user has to make from the documentation site rather than from the README.

## Installation from GitHub, with a YAML file as the project contract

CraftGRN is not on CRAN in this README's account of itself, so the install path is from source.

```r
# Using remotes
remotes::install_github("oncologylab/craftgrn")

# or using pak
pak::pak("oncologylab/craftgrn")
```

And the dependencies come from CRAN and Bioconductor separately:

```r
install.packages(c("igraph", "ggplot2", "data.table", "BiocManager"))
BiocManager::install(c("DESeq2", "GenomicRanges", "SummarizedExperiment"))
```

The Bioconductor split is meaningful for what the package does. DESeq2 for differential expression, GenomicRanges and SummarizedExperiment for genomic intervals and the data structures the footprint scores live in. igraph for the network representation, data.table for the tabular work, ggplot2 for the plots.

The interesting part is the demo data, and the way the README handles it. CraftGRN keeps demo datasets outside the source package so installation remains small and CRAN-friendly, and a package helper reports any configured external demo bundles:

```r
craftgrn::craftgrn_demo_data_info()
```

It then states plainly that no external demo bundle is currently configured. That is a candid thing to see in a README, and the troubleshooting section repeats it. If the helper returns zero rows, no public demo bundle is currently advertised by this package version.

So there is no one-command demo to run today. What there is instead is the project-level config, and that is the real interface to the package. You point CraftGRN at a `project.yaml` in your project directory and call the pipeline functions yourself:

```r
config <- "project.yaml"
module1_dir <- file.path(tempdir(), "predict_tf_binding_sites")

omics <- craftgrn::load_prep_multiomic_data(
  config = config,
  label_col = "strict_match_rna",
  do_preprocess = FALSE,
  verbose = TRUE
)

module1 <- craftgrn::predict_tfbs(
  omics_data = omics,
  out_dir = module1_dir,
  output_format = "auto",
  write_outputs = TRUE,
  write_stats = FALSE,
  verbose = TRUE
)
```

The troubleshooting notes are practical. If paths fail after moving a project folder, keep `project.yaml` in the project directory and pass that config path explicitly, and a portable project config should use `base_dir: "."`. If memory is limited, start with `load_prep_multiomic_data()` and Module 1 before running Module 2. The `label_col = "strict_match_rna"` argument is the sample matching column, and the strictness is a policy the user picks when the RNA and ATAC samples have to be paired.

## A package in pre-publication status with a research group behind it

The badges at the top of the README tell you the state of the project. The documentation badge points to a pkgdown site at oncologylab.github.io/craftgrn, the pkgdown workflow badge tracks the docs build, and there is a version badge pointing at the R package release, which is the `r-package/v` endpoint rather than a CRAN version badge, consistent with a package that is not on CRAN.

The badge that matters most is the publication one, which reads publication in prep. That is a direct statement that the method is not yet in a paper, and it tells you how to read the API. A research group publishes the analysis pipeline before or alongside the paper so that reviewers and early users can run it, and the function names, the QC reports and the YAML config are all shaped by that goal.

The repository layout is a full R package with the usual parts, `R/` for the source, `man/` for the documentation, `tests/`, `vignettes/`, `inst/`, `src/` for compiled code, a `DESCRIPTION` file, a `NAMESPACE`, a `NEWS.md` and a `cran-comments.md`, which suggests the package is being prepared for a CRAN submission. There is also a `dev/` directory, a `presentation/` directory, a `pkgdown/` directory and a `_pkgdown.yml` for the site, plus `figures/` holding the pipeline diagrams.

The only release listed is demo data, `demo-data-v0.1.0` for CraftGRN chr22 processed demo data, dated 2026-05-29. So there is demo data published as a release artifact even though no demo bundle is configured inside the package. The last push was on 2026-09-04 and the repository is not archived.

The licence is GPL-3.0, with the terms in `LICENSE.md`. For a research package in R, that is the conventional choice and it is a copyleft licence, so if you redistribute a modified version you carry the obligation. This is not legal advice, and for most academic users the practical point is simply that the licence is GPL rather than permissive, which matters if you intend to fold the code into a commercial pipeline.

## Conclusion

Adopt CraftGRN if you have matched ATAC-seq and RNA-seq for the same conditions and you want a documented, modular pipeline that ends in interpretable regulatory topics rather than a bare network. Do not adopt it if you need a stable released package, since the README badges the publication as in prep and the only release listed is demo data. Verify first that your footprint scores, enhancer-gene maps and metadata match the file layout the YAML config expects, and start with Module 1 only, since the README's own troubleshooting advice for limited memory is to run the first two modules before Module 2.

## FAQ

### What is CraftGRN and what data does it need?

It is a modular R framework that integrates chromatin accessibility profiles from ATAC-seq with matched RNA-seq expression data to infer condition-specific transcription factor binding sites and reconstruct dynamic gene regulatory networks. Module 1 loads matched ATAC, RNA, metadata and optional footprint score files from a YAML configuration.

### How do I install CraftGRN?

The README documents installing from GitHub with `remotes::install_github("oncologylab/craftgrn")` or `pak::pak("oncologylab/craftgrn")`. The common CRAN and Bioconductor dependencies are installed with `install.packages(c("igraph", "ggplot2", "data.table", "BiocManager"))` and `BiocManager::install(c("DESeq2", "GenomicRanges", "SummarizedExperiment"))`.

### Is there demo data available for CraftGRN?

Not currently in the package. CraftGRN keeps demo datasets outside the source package to keep installation small, and `craftgrn::craftgrn_demo_data_info()` reports configured external demo bundles. The README states that no external demo bundle is currently configured, and the troubleshooting section says zero rows means none is advertised by this package version.

### What are the three modules in the CraftGRN pipeline?

Module 1 predicts TF binding sites from matched ATAC, RNA, metadata and optional footprint scores. Module 2 connects TFs to target genes using enhancer-gene maps, genomic distance windows or 3D chromatin interaction priors. Module 3 learns regulatory topics from RNA and footprint signals with topic modeling and compares condition-specific regulatory links.

### What licence is CraftGRN released under and is it on CRAN?

The licence is GPL-3.0, with the terms in the LICENSE.md file at the repository root. The package is installed from GitHub rather than CRAN, and the README carries a publication badge reading in prep, with a demo data release for chr22 as the only listed release.

## Sources

- [License: GPL-3.0](https://github.com/oncologylab/craftgrn/blob/main/LICENSE)
- [oncologylab/craftgrn on GitHub](https://github.com/oncologylab/craftgrn)
- [Project website](https://oncologylab.github.io/craftgrn/)
- [README](https://github.com/oncologylab/craftgrn/blob/main/README.md)
- [Releases](https://github.com/oncologylab/craftgrn/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/oncologylab-craftgrn
