# How To Create a Mask File

    library(smer)

The Sparse Marginal Epistasis test (SME) requires a HDF5 file containing binary masking data. The effectiveness of the test relies on how informative the mask is for a specific trait. For instance, to test for marginal epistasis related to transcriptional activity, DNase I hypersensitivity sites data can be used to condition the detection on accessible chromatin regions.

Figure 1. The illustration shows open chromatin data. DNase I hypersensitive sites indicate transcriptional activity. The DNase-seq signal is converted to a binary mask, where genetic variants in inaccessible chromatin regions are excluded from the covariance matrix for marginal epistasis.

## Mask File Format

The `sme()` function expects the mask data to be in an HDF5 file. The HDF5 format includes two primary object types:

- Datasets - typed multidimensional arrays
- Groups - container structures that can hold datasets and other groups

## Mask Format Requirements

The mask data should be organized into the following groups and datasets:

Groups:

- `ld`: Contains SNPs in linkage disequilibrium (LD) with the focal SNP, which will be excluded.
- `gxg`: Contains indices of SNPs used to condition the marginal epistasis test, which will be included.

The required group names can be configured as input parameters of `sme()`. The defaults are `ld` and `gxg`.

Datasets:

- `ld/<j>`: For each focal SNP `<j>`, this dataset contains indices of SNPs in the same LD block as that SNP. These SNPs will be excluded from the gene-by-gene interaction covariance matrix.
- `gxg/<j>`: For each focal SNP `<j>`, this dataset contains indices of SNPs to include in the the gene-by-gene interaction covariance matrix for focal SNP `<j>`.

Important: All indices in the mask file must be zero-based and should correspond to the zero-based row indices of the PLINK `.bim` file. This includes the dataset index (`<j>` in `gxg/<j>`) and the data itself. This zero-based indexing is necessary because the mask data is read by a C++ subroutine in `sme()`, which uses zero-based indexing, unlike R’s one-based indexing for SNP indices in the function call.

## Creating and Using Mask Files

The package provides utility functions to create, write, and read valid mask files for `sme()`.

    hdf5_file <- tempfile()

    # Group names
    gxg_h5_group <- "gxg"
    ld_h5_group <- "ld"

    # Data (still in 1-based R indexing)
    include_gxg_snps <- 1:10
    exclude_ld_snps <- 5:6

    # Focal SNP (still in 1-based R indexing)
    focal_snp <- 4

    # Dataset names
    dataset_name_pattern <- "%s/%s"
    # 0-based index!
    gxg_dataset <- sprintf(dataset_name_pattern, gxg_h5_group, focal_snp - 1)
    ld_dataset <- sprintf(dataset_name_pattern, ld_h5_group, focal_snp - 1)

    # Create an empty HDF5 file
    create_hdf5_file(hdf5_file)

    # Write LD data
    write_hdf5_dataset(hdf5_file, ld_dataset, exclude_ld_snps - 1) # 0-based index!

    # Write GXG data
    write_hdf5_dataset(hdf5_file, gxg_dataset, include_gxg_snps - 1)

We can check that the data was written correctly.

    ld_read <- read_hdf5_dataset(hdf5_file, ld_dataset)
    gxg_read <- read_hdf5_dataset(hdf5_file, gxg_dataset)

    print(sprintf("Zero-based indices of SNPs to exclude: %s", str(ld_read)))
    #>  int [1:2] 4 5
    #> character(0)
    print(sprintf("Zero-based indices of SNPs to include: %s", str(gxg_read)))
    #>  int [1:10] 0 1 2 3 4 5 6 7 8 9
    #> character(0)

## SessionInfo

    sessionInfo()
    #> R version 4.5.1 (2025-06-13)
    #> Platform: aarch64-apple-darwin24.5.0
    #> Running under: macOS Sequoia 15.6.1
    #>
    #> Matrix products: default
    #> BLAS:   /opt/homebrew/Cellar/openblas/0.3.30/lib/libopenblasp-r0.3.30.dylib
    #> LAPACK: /opt/homebrew/Cellar/r/4.5.1/lib/R/lib/libRlapack.dylib;  LAPACK version 3.12.1
    #>
    #> locale:
    #> [1] C/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
    #>
    #> time zone: Europe/Berlin
    #> tzcode source: internal
    #>
    #> attached base packages:
    #> [1] stats4    stats     graphics  grDevices utils     datasets  methods
    #> [8] base
    #>
    #> other attached packages:
    #> [1] GenomicRanges_1.60.0 GenomeInfoDb_1.44.0  IRanges_2.42.0
    #> [4] S4Vectors_0.46.0     BiocGenerics_0.54.0  generics_0.1.4
    #> [7] ggplot2_3.5.2        dplyr_1.1.4          smer_0.0.2
    #>
    #> loaded via a namespace (and not attached):
    #>  [1] sass_0.4.10             tidyr_1.3.1             digest_0.6.37
    #>  [4] magrittr_2.0.3          evaluate_1.0.4          grid_4.5.1
    #>  [7] RColorBrewer_1.1-3      iterators_1.0.14        CompQuadForm_1.4.4
    #> [10] mvtnorm_1.3-3           fastmap_1.2.0           foreach_1.5.2
    #> [13] genio_1.1.2             jsonlite_2.0.0          backports_1.5.0
    #> [16] httr_1.4.7              purrr_1.1.0             UCSC.utils_1.4.0
    #> [19] scales_1.4.0            codetools_0.2-20        jquerylib_0.1.4
    #> [22] cli_3.6.5               rlang_1.1.6             XVector_0.48.0
    #> [25] withr_3.0.2             cachem_1.1.0            yaml_2.3.10
    #> [28] FMStable_0.1-4          tools_4.5.1             parallel_4.5.1
    #> [31] checkmate_2.3.2         GenomeInfoDbData_1.2.14 vctrs_0.6.5
    #> [34] R6_2.6.1                lifecycle_1.0.4         mvMAPIT_2.0.3
    #> [37] pkgconfig_2.0.3         pillar_1.11.0           bslib_0.9.0
    #> [40] gtable_0.3.6            glue_1.8.0              Rcpp_1.1.0
    #> [43] harmonicmeanp_3.0.1     xfun_0.52               tibble_3.3.0
    #> [46] tidyselect_1.2.1        knitr_1.50              farver_2.1.2
    #> [49] htmltools_0.5.8.1       rmarkdown_2.29          labeling_0.4.3
    #> [52] compiler_4.5.1