HiCool

Processing sequencing Hi-C libraries with HiCool

The HiCool R/Bioconductor package provides an end-to-end interface to process and normalize Hi-C paired-end fastq reads into .(m)cool files.

  1. The heavy lifting (fastq mapping, pairs parsing and pairs filtering) is performed by the underlying lightweight hicstuff python library (https://github.com/koszullab/hicstuff).
  2. Pairs filering is done using the approach described in Cournac et al., 2012 and implemented in hicstuff.
  3. cooler (https://github.com/open2c/cooler) library is used to parse pairs into a multi-resolution, balanced .mcool file. .(m)cool is a compact, indexed HDF5 file format specifically tailored for efficiently storing HiC-based data. The .(m)cool file format was developed by Abdennur and Mirny and published in 2019.
  4. Internally, all these external dependencies are automatically installed and managed in R by a basilisk.utils conda environment.

The main processing function offered in this package is HiCool(). To process .fastq reads into .pairs & .mcool files, one needs to provide:

  • The path to each fastq file (r1 and r2);
  • The genome reference, as a path to a .fasta sequence file, a path to a pre-computed bowtie2 index or a supported ID character (hg38, mm10, dm6, R64-1-1, WBcel235, GRCz10, Galgal4);
  • The restriction enzyme(s) used for Hi-C.
x <- HiCool(
    r1 = '<PATH-TO-R1.fq.gz>', 
    r2 = '<PATH-TO-R2.fq.gz>', 
    restriction = '<RE1(,RE2)>', 
    binning = "<minimum resolution>", 
    genome = '<GENOME_ID>'
)

Here is a concrete example of Hi-C data processing.

  • Example fastq files are retrieved using the HiContactsData package.
  • Two restriction enzymes are used (these are the enzymes used in the Arima Kit).
  • The final .mcool file will have three levels of resolutions, from 1000bp to 8000bp.
  • The data will be mapped on R64-1-1, the yeast genome reference.
  • All output files will be placed in output/ directory.
library(HiCool)
hcf <- HiCool(
    r1 = HiContactsData::HiContactsData(sample = 'yeast_wt', format = 'fastq_R1'), 
    r2 = HiContactsData::HiContactsData(sample = 'yeast_wt', format = 'fastq_R2'), 
    restriction = 'DpnII,HinfI', 
    binning = 1000, 
    genome = 'R64-1-1', 
    output = './HiCool/'
)
#> HiCool :: Parsing HiCool arguments and checking files.
#> see ?HiContactsData and browseVignettes('HiContactsData') for documentation
#> downloading 1 resources
#> retrieving 1 resource
#> loading from cache
#> see ?HiContactsData and browseVignettes('HiContactsData') for documentation
#> downloading 1 resources
#> retrieving 1 resource
#> loading from cache
#> HiCool :: Fetching bowtie genome index files from AWS iGenomes S3 bucket...
#> HiCool :: Recovering bowtie2 genome index from AWS iGenomes...
#> HiCool :: Processing .fastq files to .mcool format. This might take a while.
#> HiCool :: Initializing processing of fastq files [tmp folder: /tmp/Rtmp1t8j2s/68ZMVI]...
#> HiCool :: Mapping fastq files...
#> HiCool :: Tidying up everything for you...
#> HiCool :: .fastq to .mcool processing done!
#> HiCool :: Check ./HiCool/folder to find the generated files
#> HiCool :: Generating HiCool report. This might take a while.
#> HiCool :: Report generated and available @ /tmp/RtmpYEPLZC/Rbuild17f171242510/HiCool/vignettes/HiCool/195e25cc56be_7833^mapped-R64-1-1^68ZMVI.html
#> HiCool :: All processing successfully achieved. Congrats!
hcf
#> CoolFile object
#> .mcool file: ./HiCool//matrices/195e25cc56be_7833^mapped-R64-1-1^68ZMVI.mcool 
#> resolution: 1000 
#> pairs file: ./HiCool//pairs/195e25cc56be_7833^mapped-R64-1-1^68ZMVI.pairs 
#> metadata(3): log args stats
S4Vectors::metadata(hcf)
#> $log
#> [1] "./HiCool//logs/195e25cc56be_7833^mapped-R64-1-1^68ZMVI.log"
#> 
#> $args
#> $args$r1
#> [1] "/github/home/.cache/R/ExperimentHub/195e25cc56be_7833"
#> 
#> $args$r2
#> [1] "/github/home/.cache/R/ExperimentHub/195eb5fcea1_7834"
#> 
#> $args$genome
#> [1] "/tmp/Rtmp1t8j2s/R64-1-1"
#> 
#> $args$binning
#> [1] "1000"
#> 
#> $args$restriction
#> [1] "DpnII,HinfI"
#> 
#> $args$iterative
#> [1] TRUE
#> 
#> $args$balancing_args
#> [1] " --min-nnz 10 --mad-max 5 "
#> 
#> $args$threads
#> [1] 1
#> 
#> $args$output
#> [1] "./HiCool/"
#> 
#> $args$exclude_chr
#> [1] "Mito|chrM|MT"
#> 
#> $args$keep_bam
#> [1] FALSE
#> 
#> $args$scratch
#> [1] "/tmp/Rtmp1t8j2s"
#> 
#> $args$wd
#> [1] "/tmp/RtmpYEPLZC/Rbuild17f171242510/HiCool/vignettes"
#> 
#> 
#> $stats
#> $stats$nFragments
#> [1] 1e+05
#> 
#> $stats$nPairs
#> [1] 64761
#> 
#> $stats$nDangling
#> [1] 9266
#> 
#> $stats$nSelf
#> [1] 1910
#> 
#> $stats$nDumped
#> [1] 32
#> 
#> $stats$nFiltered
#> [1] 53553
#> 
#> $stats$nDups
#> [1] 613
#> 
#> $stats$nUnique
#> [1] 52940
#> 
#> $stats$threshold_uncut
#> [1] 7
#> 
#> $stats$threshold_self
#> [1] 7

Optional parameters

Extra optional arguments can be passed to the hicstuff workhorse library:

  • iterative (default: TRUE): By default, hicstuff first truncates your set of reads to 20bp and attempts to align the truncated reads, then moves on to aligning 40bp-truncated reads for those which could not be mapped, etc. This procedure is longer than a traditional mapping but allows for more pairs to be rescued. Set to FALSE if you want to perform standard alignment of fastq files without iterative alignment;
  • balancing_args (default: " --min-nnz 10 --mad-max 5 "): Specify here any balancing argument to be used by cooler when normalizing the binned contact matrices. Full list of options available at cooler documentation website;
  • threads (default: 1L): Number of CPUs to use to process data;
  • exclude_chr (default: 'Mito|chrM|MT'): List here any chromosome you wish to remove from the final contact matrix file;
  • keep_bam (default: FALSE): Set to TRUE if you wish to keep the pair of .bam files;
  • scratch (default: tempdir()): Points to a temporary directory to be used for processing.

Output files

The important files generated by HiCool are the following:

  • A log file: <output_folder>/logs/<prefix>^mapped-<genome>^<hash>.log
  • A multi-resolution, balanced contact matrix file: <output_folder>/matrices/<prefix>^mapped-<genome>^<hash>.mcool
  • A .pairs file: <output_folder>/pairs/<prefix>^mapped-<genome>^<hash>.pairs
  • Several diagnosis plots: <output_folder>/plots/<prefix>^mapped-<genome>^<hash>_*.pdf.

The diagnosis plots illustrate how pairs were filtered during the processing, using a strategy described in Cournac et al., BMC Genomics 2012. The event_distance chart represents the frequency of ++, +-, -+ and -- pairs in the library, as a function of the number of restriction sites between each end of the pairs, and shows the inferred filtering threshold. The event_distribution chart indicates the proportion of each type of pairs (e.g. dangling, uncut, abnormal, …) and the total number of pairs retained (3D intra + 3D inter).

Notes:

System dependencies

Processing Hi-C sequencing libraries into .pairs and .mcool files requires several dependencies, to (1) align reads to a reference genome, (2) manage alignment files (SAM), (3) filter pairs, (4) bin them to a specific resolution and (5)

All system dependencies are internally managed by basilisk.utils. HiCool maintains a conda environment containing:

  • python 3.12.11
  • numpy 1.26.4
  • pandas 2.3.3
  • bowtie2 2.5.4
  • chromosight 1.6.3
  • cooler 0.10.4
  • hicstuff 3.2.5
  • pairtools 1.1.3
  • samtools 1.22.1

The first time HiCool() is executed, a fresh conda environment will be created and required dependencies automatically installed. This ensures compatibility between the different system dependencies needed to process Hi-C fastq files. The tools of this environment run in a separate process, so their libraries never conflict with those already loaded in the R session.

Session info

sessionInfo()
#> R version 4.6.1 (2026-06-24)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 26.04.1 LTS
#> 
#> Matrix products: default
#> BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so;  LAPACK version 3.12.0
#> 
#> locale:
#>  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
#>  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
#>  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
#>  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
#>  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
#> 
#> time zone: Etc/UTC
#> tzcode source: system (glibc)
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> other attached packages:
#>  [1] HiContactsData_1.15.0 ExperimentHub_3.3.2   AnnotationHub_4.3.2  
#>  [4] BiocFileCache_3.3.0   dbplyr_2.6.0          BiocGenerics_0.59.12 
#>  [7] generics_0.1.4        HiCool_1.13.2         HiCExperiment_1.13.1 
#> [10] BiocStyle_2.41.0     
#> 
#> loaded via a namespace (and not attached):
#>  [1] DBI_1.3.0                   httr2_1.3.0                
#>  [3] rlang_1.3.0                 magrittr_2.0.5             
#>  [5] otel_0.2.0                  matrixStats_1.5.0          
#>  [7] compiler_4.6.1              RSQLite_3.53.3             
#>  [9] dir.expiry_1.21.0           png_0.1-9                  
#> [11] vctrs_0.7.3                 pkgconfig_2.0.3            
#> [13] crayon_1.5.3                fastmap_1.2.0              
#> [15] XVector_0.53.0              rmdformats_1.0.4           
#> [17] rmarkdown_2.32              sessioninfo_1.2.4          
#> [19] tzdb_0.5.0                  strawr_0.0.92              
#> [21] purrr_1.2.2                 bit_4.6.0                  
#> [23] xfun_0.61                   cachem_1.1.0               
#> [25] jsonlite_2.0.0              blob_1.3.0                 
#> [27] rhdf5filters_1.25.4         DelayedArray_0.39.8        
#> [29] Rhdf5lib_2.1.0              BiocParallel_1.47.0        
#> [31] parallel_4.6.1              R6_2.6.1                   
#> [33] bslib_0.12.0                RColorBrewer_1.1-3         
#> [35] GenomicRanges_1.65.4        jquerylib_0.1.4            
#> [37] Rcpp_1.1.2                  Seqinfo_1.3.2              
#> [39] bookdown_0.48               SummarizedExperiment_1.43.0
#> [41] knitr_1.52                  IRanges_2.47.5             
#> [43] BiocBaseUtils_1.15.1        Matrix_1.7-6               
#> [45] tidyselect_1.2.1            abind_1.4-8                
#> [47] yaml_2.3.12                 codetools_0.2-20           
#> [49] curl_8.0.0                  lattice_0.23-1             
#> [51] tibble_3.3.1                InteractionSet_1.41.0      
#> [53] Biobase_2.73.2              basilisk.utils_1.25.0      
#> [55] withr_3.0.3                 KEGGREST_1.53.6            
#> [57] S7_0.2.2                    evaluate_1.0.5             
#> [59] Biostrings_2.81.9           pillar_1.11.1              
#> [61] BiocManager_1.30.27         filelock_1.0.3             
#> [63] MatrixGenerics_1.25.0       stats4_4.6.1               
#> [65] plotly_4.12.1               vroom_1.7.1                
#> [67] BiocVersion_3.24.0          S4Vectors_0.51.10          
#> [69] ggplot2_4.0.3               scales_1.4.0               
#> [71] glue_1.8.1                  maketools_1.3.2            
#> [73] tools_4.6.1                 BiocIO_1.23.3              
#> [75] sys_3.4.3                   data.table_1.18.6.1        
#> [77] buildtools_1.0.0            rhdf5_2.57.18              
#> [79] grid_4.6.1                  tidyr_1.3.2                
#> [81] crosstalk_1.2.2             AnnotationDbi_1.75.2       
#> [83] cli_3.6.6                   rappdirs_0.3.4             
#> [85] S4Arrays_1.13.2             viridisLite_0.4.3          
#> [87] dplyr_1.2.1                 gtable_0.3.6               
#> [89] sass_0.4.10                 digest_0.6.39              
#> [91] SparseArray_1.13.4          htmlwidgets_1.6.4          
#> [93] farver_2.1.2                memoise_2.0.1              
#> [95] htmltools_0.5.9             lifecycle_1.0.5            
#> [97] httr_1.4.9                  bit64_4.8.6