Skip to content

Commit

Permalink
Convert this to a standalone library with its own namespace.
Browse files Browse the repository at this point in the history
  • Loading branch information
LTLA committed Jul 17, 2024
1 parent 773d3c4 commit 05f21b3
Show file tree
Hide file tree
Showing 17 changed files with 1,040 additions and 838 deletions.
36 changes: 36 additions & 0 deletions .github/workflows/check-install.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
on:
push:
branches:
- master
pull_request:

name: Check CMake install

jobs:
install:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Get latest CMake
uses: lukka/get-cmake@latest

- name: Configure the build
run: cmake -S . -B build -DSCRAN_VARIANCES_TESTS=OFF

- name: Install the library
run: sudo cmake --install build

- name: Test downstream usage
run: |
mkdir _downstream
touch _downstream/source.cpp
cat << EOF > _downstream/CMakeLists.txt
cmake_minimum_required(VERSION 3.24)
project(test_install)
add_executable(whee source.cpp)
find_package(libscran_scran_variances)
target_link_libraries(whee libscran::scran_variances)
EOF
cd _downstream && cmake -S . -B build
4 changes: 2 additions & 2 deletions .github/workflows/doxygenate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:
with:
args: -O docs/tatami.tag https://tatami-inc.github.io/tatami/tatami.tag

- name: Download core utilities tagfile
- name: Download blocks tagfile
uses: wei/wget@v1
with:
args: -O docs/scran_core_utils.tag https://libscran.github.io/core_utils/scran_core_utils.tag
args: -O docs/scran_blocks.tag https://libscran.github.io/scran_blocks/scran_blocks.tag

- name: Doxygen Action
uses: mattnotmitt/doxygen-action@v1
Expand Down
65 changes: 57 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,69 @@
cmake_minimum_required(VERSION 3.14)

project(scran_model_gene_variances
project(scran_variances
VERSION 1.0.0
DESCRIPTION "Aggregate expression values across cells"
DESCRIPTION "Model per-gene variances in single-cell expression"
LANGUAGES CXX)

add_library(scran_model_gene_variances INTERFACE)
target_compile_features(scran_model_gene_variances INTERFACE cxx_std_17)
target_include_directories(scran_model_gene_variances INTERFACE include/scran)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

add_subdirectory(extern)
target_link_libraries(scran_model_gene_variances INTERFACE tatami::tatami tatami::tatami_stats ltla::WeightedLowess scran_core_utils)
# Library
add_library(scran_variances INTERFACE)
add_library(libscran::scran_variances ALIAS scran_variances)

target_include_directories(scran_variances INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/scran_variances>)
target_compile_features(scran_variances INTERFACE cxx_std_17)

# Dependencies
option(SCRAN_VARIANCES_FETCH_EXTERN "Automatically fetch scran_variances's external dependencies." ON)
if(SCRAN_VARIANCES_FETCH_EXTERN)
add_subdirectory(extern)
else()
find_package(tatami_tatami 3.0.0 CONFIG REQUIRED)
find_package(tatami_tatami_stats 1.0.0 CONFIG REQUIRED)
find_package(ltla_WeightedLowess 2.0.0 CONFIG REQUIRED)
find_package(libscran_scran_blocks 1.0.0 CONFIG REQUIRED)
endif()

target_link_libraries(scran_variances INTERFACE tatami::tatami tatami::tatami_stats ltla::WeightedLowess libscran::scran_blocks)

# Tests
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
option(SCRAN_VARIANCES_TESTS "Build scran_variances's test suite." ON)
else()
option(SCRAN_VARIANCES_TESTS "Build scran_variances's test suite." OFF)
endif()

if(SCRAN_VARIANCES_TESTS)
include(CTest)
if(BUILD_TESTING)
add_subdirectory(tests)
endif()
endif()
endif()

# Install
install(DIRECTORY include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/scran_variances)

install(TARGETS scran_variances
EXPORT scran_variancesTargets)

install(EXPORT scran_variancesTargets
FILE libscran_scran_variancesTargets.cmake
NAMESPACE libscran::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libscran_scran_variances)

configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/libscran_scran_variancesConfig.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libscran_scran_variances)

write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/libscran_scran_variancesConfigVersion.cmake"
COMPATIBILITY SameMajorVersion)

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libscran_scran_variancesConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/libscran_scran_variancesConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libscran_scran_variances)
74 changes: 53 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Model per-gene variance in expression

![Unit tests](https://github.com/libscran/model_gene_variances/actions/workflows/run-tests.yaml/badge.svg)
![Documentation](https://github.com/libscran/model_gene_variances/actions/workflows/doxygenate.yaml/badge.svg)
[![Codecov](https://codecov.io/gh/libscran/model_gene_variances/graph/badge.svg?token=JWV0I4WJX2)](https://codecov.io/gh/libscran/model_gene_variances)
![Unit tests](https://github.com/libscran/scran_variances/actions/workflows/run-tests.yaml/badge.svg)
![Documentation](https://github.com/libscran/scran_variances/actions/workflows/doxygenate.yaml/badge.svg)
[![Codecov](https://codecov.io/gh/libscran/scran_variances/graph/badge.svg?token=JWV0I4WJX2)](https://codecov.io/gh/libscran/scran_variances)

## Overview

Expand All @@ -13,15 +13,16 @@ factored out into a separate C++ library for easier re-use.

## Quick start

Given a [`tatami::Matrix`](https://github.com/tatami-inc/tatami), the `model_gene_variances::compute()` function will compute several variance-related statistics for each gene:
Given a [`tatami::Matrix`](https://github.com/tatami-inc/tatami) of log-expression values for each gene in each cell,
we can compute the per-gene variances and model the trend with respect to the mean across genes:

```cpp
#include "scran/model_gene_variances.hpp"
#include "scran_variances/scran_variances.hpp"

tatami::Matrix<double, int>* ptr = some_data_source();
std::shared_ptr<tatami::Matrix<double, int> > mat = some_data_source();

scran::model_gene_variances::Options opt;
auto res = scran::model_gene_variances::compute(ptr, opt);
scran_variances::ModelGeneVariancesOptions opt;
auto res = scran_variances::model_gene_variances(*mat, opt);

res.means; // vector of means across genes.
res.variances; // vector of variances across genes.
Expand All @@ -32,48 +33,79 @@ res.residuals; // vector of residuals from the trend.
Typically, the residuals are used for feature selection, as these account for non-trivial mean-variance trends in transformed count data.

```cpp
scran::choose_highly_variable_genes::Options copt;
scran_variances::ChooseHighlyVariableGenesOptions copt;
copt.top = 5000;
auto chosen = scran::choose_highly_variable_genes::compute_index(
auto chosen = scran_variances::choose_highly_variable_genes_index(
res.residuals.size(),
res.residuals.data(),
copt
);

// Create the HVG submatrix for downstream analysis.
auto hvg_subset = tatami::make_DelayedSubset(mat, chosen, /* by_row = */ true);
```

Users can also fit a trend directly to their own statistics.

```cpp
scran::fit_variance_trend::Options fopt;
scran_variances::FitVarianceTrendOptions fopt;
fopt.span = 0.5;
fopt.minimum_mean = 1;
auto fit = scran::fit_variance_trend::compute(100, means, variances, fopt);
auto fit = scran_variances::fit_variance_trend(100, means, variances, fopt);
fit.fitted; // fitted values for all genes.
fit.residuals; // residuals values for all genes.
```

Check out the [reference documentation](https://libscran.github.io/model_gene_variances) for more details.
Check out the [reference documentation](https://libscran.github.io/scran_variances) for more details.

## Building projects

This repository is part of the broader [**libscran**](https://github.com/libscran/libscran) library,
so users are recommended to use the latter in their projects.
**libscran** developers should just use CMake with `FetchContent`:
### CMake with `FetchContent`

If you're using CMake, you just need to add something like this to your `CMakeLists.txt`:

```cmake
include(FetchContent)
FetchContent_Declare(
scran_model_gene_variances
GIT_REPOSITORY https://github.com/libscran/model_gene_variances
scran_variances
GIT_REPOSITORY https://github.com/libscran/scran_variances
GIT_TAG master # or any version of interest
)
FetchContent_MakeAvailable(scran_model_gene_variances)
FetchContent_MakeAvailable(scran_variances)
```

Then you can link to **scran_variances** to make the headers available during compilation:

```cmake
# For executables:
target_link_libraries(myexe scran_model_gene_variances)
target_link_libraries(myexe libscran::scran_variances)
# For libaries
target_link_libraries(mylib INTERFACE scran_model_gene_variances)
target_link_libraries(mylib INTERFACE libscran::scran_variances)
```

### CMake with `find_package()`

```cmake
find_package(libscran_scran_variances CONFIG REQUIRED)
target_link_libraries(mylib INTERFACE libscran::scran_variances)
```

To install the library, use:

```sh
mkdir build && cd build
cmake .. -DSCRAN_VARIANCES_TESTS=OFF
cmake --build . --target install
```

By default, this will use `FetchContent` to fetch all external dependencies.
If you want to install them manually, use `-DSCRAN_VARIANCES_FETCH_EXTERN=OFF`.
See the tags in [`extern/CMakeLists.txt`](extern/CMakeLists.txt) to find compatible versions of each dependency.

### Manual

If you're not using CMake, the simple approach is to just copy the files in `include/` - either directly or with Git submodules - and include their path during compilation with, e.g., GCC's `-I`.
This requires the external dependencies listed in [`extern/CMakeLists.txt`](extern/CMakeLists.txt), which also need to be made available during compilation.
9 changes: 9 additions & 0 deletions cmake/Config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@PACKAGE_INIT@

include(CMakeFindDependencyMacro)
find_dependency(tatami_tatami 3.0.0 CONFIG REQUIRED)
find_dependency(tatami_tatami_stats 1.0.0 CONFIG REQUIRED)
find_dependency(ltla_WeightedLowess 2.0.0 CONFIG REQUIRED)
find_dependency(libscran_scran_blocks 1.0.0 CONFIG REQUIRED)

include("${CMAKE_CURRENT_LIST_DIR}/libscran_scran_variancesTargets.cmake")
4 changes: 2 additions & 2 deletions docs/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places.
# The default value is: My Project.

PROJECT_NAME = scran_model_gene_variances
PROJECT_NAME = scran_variances

# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
Expand Down Expand Up @@ -2324,7 +2324,7 @@ SKIP_FUNCTION_MACROS = YES
# run, you must also specify the path to the tagfile here.

TAGFILES = tatami.tag=https://tatami-inc.github.io/tatami \
scran_core_utils.tag=https://libscran.github.io/core_utils
scran_blocks.tag=https://libscran.github.io/scran_blocks

# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
# tag file that is based on the input files it reads. See section "Linking to
Expand Down
8 changes: 4 additions & 4 deletions extern/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ FetchContent_Declare(
)

FetchContent_Declare(
scran_core_utils
GIT_REPOSITORY https://github.com/libscran/core_utils
GIT_TAG master
scran_blocks
GIT_REPOSITORY https://github.com/libscran/scran_blocks
GIT_TAG master # ^1.0.0
)

FetchContent_MakeAvailable(tatami)
FetchContent_MakeAvailable(tatami_stats)
FetchContent_MakeAvailable(WeightedLowess)
FetchContent_MakeAvailable(scran_core_utils)
FetchContent_MakeAvailable(scran_blocks)
Loading

0 comments on commit 05f21b3

Please sign in to comment.