scran_norm
Scaling normalization of single-cell data
Loading...
Searching...
No Matches
choose_pseudo_count.hpp
Go to the documentation of this file.
1#ifndef SCRAN_NORM_CHOOSE_PSEUDO_COUNT_HPP
2#define SCRAN_NORM_CHOOSE_PSEUDO_COUNT_HPP
3
4#include <algorithm>
5#include <vector>
6#include <cstddef>
7
8#include "utils.hpp"
9
15namespace scran_norm {
16
26 double quantile = 0.05;
27
32 double max_bias = 0.1;
33
38 double min_value = 1;
39};
40
44namespace internal {
45
46template<typename Float_>
47Float_ find_quantile(Float_ quantile, std::size_t n, Float_* ptr) {
48 double raw = static_cast<double>(n - 1) * quantile;
49 std::size_t index = std::ceil(raw);
50 std::nth_element(ptr, ptr + index, ptr + n);
51 double upper = *(ptr + index);
52 std::nth_element(ptr, ptr + index - 1, ptr + index);
53 double lower = *(ptr + index - 1);
54 return lower * (index - raw) + upper * (raw - (index - 1));
55}
56
57}
96template<typename Float_>
97Float_ choose_pseudo_count_raw(std::size_t num, Float_* const size_factors, const ChoosePseudoCountOptions& options) {
98 if (num <= 1) {
99 return options.min_value;
100 }
101
102 // Avoid problems with zeros.
103 decltype(I(num)) counter = 0;
104 for (decltype(I(num)) i = 0; i < num; ++i) {
105 const auto val = size_factors[i];
106 if (std::isfinite(val) && val > 0) {
107 if (i != counter) {
108 size_factors[counter] = val;
109 }
110 ++counter;
111 }
112 }
113 num = counter;
114
115 if (num <= 1) {
116 return options.min_value;
117 }
118
119 Float_ lower_sf, upper_sf;
120 if (options.quantile == 0) {
121 lower_sf = *std::min_element(size_factors, size_factors + num);
122 upper_sf = *std::max_element(size_factors, size_factors + num);
123 } else {
124 lower_sf = internal::find_quantile(options.quantile, num, size_factors);
125 upper_sf = internal::find_quantile(1 - options.quantile, num, size_factors);
126 }
127
128 // Very confusing formulation in Equation 3, but whatever.
129 const Float_ pseudo_count = (1.0 / lower_sf - 1.0 / upper_sf) / (8 * options.max_bias);
130
131 return std::max(options.min_value, pseudo_count);
132}
133
146template<typename Float_>
147Float_ choose_pseudo_count(const std::size_t num, const Float_* const size_factors, const ChoosePseudoCountOptions& options) {
148 std::vector<Float_> buffer(size_factors, size_factors + num);
149 return choose_pseudo_count_raw(num, buffer.data(), options);
150}
151
152}
153
154#endif
Scaling normalization of single-cell data.
Definition center_size_factors.hpp:20
Float_ choose_pseudo_count(const std::size_t num, const Float_ *const size_factors, const ChoosePseudoCountOptions &options)
Definition choose_pseudo_count.hpp:147
Float_ choose_pseudo_count_raw(std::size_t num, Float_ *const size_factors, const ChoosePseudoCountOptions &options)
Definition choose_pseudo_count.hpp:97
Options for choose_pseudo_count().
Definition choose_pseudo_count.hpp:20
double quantile
Definition choose_pseudo_count.hpp:26
double max_bias
Definition choose_pseudo_count.hpp:32
double min_value
Definition choose_pseudo_count.hpp:38