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
12namespace scran_norm {
13
23 double quantile = 0.05;
24
28 double max_bias = 0.1;
29
34 double min_value = 1;
35};
36
40namespace internal {
41
42template<typename Float_>
43Float_ find_quantile(Float_ quantile, size_t n, Float_* ptr) {
44 double raw = static_cast<double>(n - 1) * quantile;
45 size_t index = std::ceil(raw);
46 std::nth_element(ptr, ptr + index, ptr + n);
47 double upper = *(ptr + index);
48 std::nth_element(ptr, ptr + index - 1, ptr + index);
49 double lower = *(ptr + index - 1);
50 return lower * (index - raw) + upper * (raw - (index - 1));
51}
52
53}
86template<typename Float_>
87Float_ choose_pseudo_count_raw(size_t num, Float_* size_factors, const ChoosePseudoCountOptions& options) {
88 if (num <= 1) {
89 return options.min_value;
90 }
91
92 // Avoid problems with zeros.
93 size_t counter = 0;
94 for (size_t i = 0; i < num; ++i) {
95 auto val = size_factors[i];
96 if (std::isfinite(val) && val > 0) {
97 if (i != counter) {
98 size_factors[counter] = val;
99 }
100 ++counter;
101 }
102 }
103 num = counter;
104
105 if (num <= 1) {
106 return options.min_value;
107 }
108
109 double lower_sf, upper_sf;
110 if (options.quantile == 0) {
111 lower_sf = *std::min_element(size_factors, size_factors + num);
112 upper_sf = *std::max_element(size_factors, size_factors + num);
113 } else {
114 lower_sf = internal::find_quantile(options.quantile, num, size_factors);
115 upper_sf = internal::find_quantile(1 - options.quantile, num, size_factors);
116 }
117
118 // Very confusing formulation in Equation 3, but whatever.
119 Float_ pseudo_count = (1.0 / lower_sf - 1.0 / upper_sf) / (8 * options.max_bias);
120
121 return std::max(options.min_value, pseudo_count);
122}
123
134template<typename Float_>
135Float_ choose_pseudo_count(size_t num, const Float_* size_factors, const ChoosePseudoCountOptions& options) {
136 std::vector<Float_> buffer(size_factors, size_factors + num);
137 return choose_pseudo_count_raw(num, buffer.data(), options);
138}
139
140}
141
142#endif
Scaling normalization of single-cell data.
Definition center_size_factors.hpp:18
Float_ choose_pseudo_count(size_t num, const Float_ *size_factors, const ChoosePseudoCountOptions &options)
Definition choose_pseudo_count.hpp:135
Float_ choose_pseudo_count_raw(size_t num, Float_ *size_factors, const ChoosePseudoCountOptions &options)
Definition choose_pseudo_count.hpp:87
Options for choose_pseudo_count().
Definition choose_pseudo_count.hpp:17
double quantile
Definition choose_pseudo_count.hpp:23
double max_bias
Definition choose_pseudo_count.hpp:28
double min_value
Definition choose_pseudo_count.hpp:34