scran_markers
Marker detection for single-cell data
Loading...
Searching...
No Matches
score_markers_summary.hpp
Go to the documentation of this file.
1#ifndef SCRAN_SCORE_MARKERS_HPP
2#define SCRAN_SCORE_MARKERS_HPP
3
5#include "tatami/tatami.hpp"
6#include "sanisizer/sanisizer.hpp"
7#include "topicks/topicks.hpp"
8
9#include <array>
10#include <map>
11#include <vector>
12
13#include "scan_matrix.hpp"
14#include "cohens_d.hpp"
15#include "simple_diff.hpp"
17#include "average_group_stats.hpp"
18#include "create_combinations.hpp"
19#include "utils.hpp"
20
26namespace scran_markers {
27
37 double threshold = 0;
38
43 int num_threads = 1;
44
49 bool compute_group_mean = true;
50
56
61 bool compute_cohens_d = true;
62
67 bool compute_auc = true;
68
73 bool compute_delta_mean = true;
74
80
85 bool compute_min = true;
86
91 bool compute_mean = true;
92
97 bool compute_median = true;
98
103 bool compute_max = true;
104
109 bool compute_min_rank = true;
110
116 std::size_t min_rank_limit = 500;
117
124
135 scran_blocks::WeightPolicy block_weight_policy = scran_blocks::WeightPolicy::VARIABLE;
136
142};
143
149template<typename Stat_, typename Rank_>
158 std::vector<Stat_*> mean;
159
167 std::vector<Stat_*> detected;
168
176 std::vector<SummaryBuffers<Stat_, Rank_> > cohens_d;
177
185 std::vector<SummaryBuffers<Stat_, Rank_> > auc;
186
194 std::vector<SummaryBuffers<Stat_, Rank_> > delta_mean;
195
203 std::vector<SummaryBuffers<Stat_, Rank_> > delta_detected;
204};
205
211template<typename Stat_, typename Rank_>
217 std::vector<std::vector<Stat_> > mean;
218
223 std::vector<std::vector<Stat_> > detected;
224
232 std::vector<SummaryResults<Stat_, Rank_> > cohens_d;
233
241 std::vector<SummaryResults<Stat_, Rank_> > auc;
242
250 std::vector<SummaryResults<Stat_, Rank_> > delta_mean;
251
259 std::vector<SummaryResults<Stat_, Rank_> > delta_detected;
260};
261
265namespace internal {
266
267template<typename Stat_, typename Index_>
268using MinrankTopQueues = std::vector<std::vector<topicks::TopQueue<Stat_, Index_> > >;
269
270template<typename Stat_, typename Index_, typename Rank_>
271void preallocate_minrank_queues(
272 const std::size_t ngroups,
273 std::vector<MinrankTopQueues<Stat_, Index_> >& all_queues,
274 const std::vector<SummaryBuffers<Stat_, Rank_> >& summaries,
275 const Index_ limit,
276 const bool keep_ties,
277 const int num_threads
278) {
280 qopt.keep_ties = keep_ties;
281 qopt.check_nan = true;
282
283 sanisizer::resize(all_queues, num_threads);
284 for (int t = 0; t < num_threads; ++t) {
285 sanisizer::resize(all_queues[t], ngroups);
286
287 for (decltype(I(ngroups)) g1 = 0; g1 < ngroups; ++g1) {
288 if (summaries[g1].min_rank == NULL) {
289 continue;
290 }
291
292 for (decltype(I(ngroups)) g2 = 0; g2 < ngroups; ++g2) {
293 all_queues[t][g1].emplace_back(limit, true, qopt);
294 }
295 }
296 }
297}
298
299template<typename Stat_, typename Index_, typename Rank_>
300void compute_summary_stats_per_gene(
301 const Index_ gene,
302 const std::size_t ngroups,
303 const Stat_* const pairwise_buffer_ptr,
304 std::vector<Stat_>& summary_buffer,
305 MinrankTopQueues<Stat_, Index_>& minrank_queues,
306 const std::vector<SummaryBuffers<Stat_, Rank_> >& summaries
307) {
308 for (decltype(I(ngroups)) gr = 0; gr < ngroups; ++gr) {
309 auto& cursummary = summaries[gr];
310 const auto in_offset = sanisizer::product_unsafe<std::size_t>(ngroups, gr);
311 summarize_comparisons(ngroups, pairwise_buffer_ptr + in_offset, gr, gene, cursummary, summary_buffer);
312
313 if (cursummary.min_rank) {
314 auto& cur_queues = minrank_queues[gr];
315 for (decltype(I(ngroups)) gr2 = 0; gr2 < ngroups; ++gr2) {
316 if (gr != gr2) {
317 cur_queues[gr2].emplace(pairwise_buffer_ptr[in_offset + gr2], gene);
318 }
319 }
320 }
321 }
322}
323
324template<typename Stat_, typename Index_, typename Rank_>
325void report_minrank_from_queues(
326 const Index_ ngenes,
327 const std::size_t ngroups,
328 std::vector<MinrankTopQueues<Stat_, Index_> >& all_queues,
329 const std::vector<SummaryBuffers<Stat_, Rank_> >& summaries,
330 const int num_threads,
331 const bool keep_ties
332) {
333 tatami::parallelize([&](const int, const std::size_t start, const std::size_t length) -> void {
334 std::vector<Index_> tie_buffer;
335
336 for (decltype(I(ngroups)) gr = start, grend = start + length; gr < grend; ++gr) {
337 const auto mr_out = summaries[gr].min_rank;
338 if (mr_out == NULL) {
339 continue;
340 }
341
342 // Using the maximum possible rank (i.e., 'ngenes') as the default.
343 const auto maxrank_placeholder = sanisizer::cast<Rank_>(ngenes);
344 std::fill_n(mr_out, ngenes, maxrank_placeholder);
345
346 for (decltype(I(ngroups)) gr2 = 0; gr2 < ngroups; ++gr2) {
347 if (gr == gr2) {
348 continue;
349 }
350 auto& current_out = all_queues.front()[gr][gr2];
351
352 const auto num_queues = all_queues.size();
353 for (decltype(I(num_queues)) q = 1; q < num_queues; ++q) {
354 auto& current_in = all_queues[q][gr][gr2];
355 while (!current_in.empty()) {
356 current_out.push(current_in.top());
357 current_in.pop();
358 }
359 }
360
361 // Cast to Rank_ is safe as current_out.size() <= ngenes,
362 // and we already checked that ngenes can fit into Rank_ in report_minrank_from_current_outs().
363 if (!keep_ties) {
364 while (!current_out.empty()) {
365 auto& mr = mr_out[current_out.top().second];
366 mr = std::min(mr, static_cast<Rank_>(current_out.size()));
367 current_out.pop();
368 }
369 } else {
370 while (!current_out.empty()) {
371 tie_buffer.clear();
372 const auto curtop = current_out.top();
373 current_out.pop();
374
375 while (!current_out.empty() && current_out.top().first == curtop.first) {
376 tie_buffer.push_back(current_out.top().second);
377 current_out.pop();
378 }
379
380 // Increment is safe as we already reduced the size at least once.
381 const Rank_ tied_rank = current_out.size() + 1;
382
383 mr_out[curtop.second] = std::min(mr_out[curtop.second], tied_rank);
384 for (const auto t : tie_buffer) {
385 mr_out[t] = std::min(mr_out[t], tied_rank);
386 }
387 }
388 }
389 }
390 }
391 }, ngroups, num_threads);
392}
393
394template<typename Index_, typename Stat_, typename Rank_>
395void process_simple_summary_effects(
396 const Index_ ngenes,
397 const std::size_t ngroups,
398 const std::size_t nblocks,
399 const std::size_t ncombos,
400 const std::vector<Stat_>& combo_means,
401 const std::vector<Stat_>& combo_vars,
402 const std::vector<Stat_>& combo_detected,
403 const ScoreMarkersSummaryBuffers<Stat_, Rank_>& output,
404 const std::vector<Stat_>& combo_weights,
405 const double threshold,
406 const Index_ minrank_limit,
407 const bool minrank_keep_ties,
408 const int num_threads)
409{
410 std::vector<MinrankTopQueues<Stat_, Index_> > cohens_d_minrank_all_queues, delta_mean_minrank_all_queues, delta_detected_minrank_all_queues;
411 if (output.cohens_d.size()) {
412 preallocate_minrank_queues(ngroups, cohens_d_minrank_all_queues, output.cohens_d, minrank_limit, minrank_keep_ties, num_threads);
413 }
414 if (output.delta_mean.size()) {
415 preallocate_minrank_queues(ngroups, delta_mean_minrank_all_queues, output.delta_mean, minrank_limit, minrank_keep_ties, num_threads);
416 }
417 if (output.delta_detected.size()) {
418 preallocate_minrank_queues(ngroups, delta_detected_minrank_all_queues, output.delta_detected, minrank_limit, minrank_keep_ties, num_threads);
419 }
420
421 std::vector<Stat_> total_weights_per_group;
422 auto total_weights_ptr = combo_weights.data();
423 if (!output.mean.empty() || !output.detected.empty()) {
424 if (nblocks > 1) {
425 total_weights_per_group = compute_total_weight_per_group(ngroups, nblocks, combo_weights.data());
426 total_weights_ptr = total_weights_per_group.data();
427 }
428 }
429
430 PrecomputedPairwiseWeights<Stat_> preweights;
431 if (!output.cohens_d.empty() || !output.delta_mean.empty() || !output.delta_detected.empty()) {
432 preweights = PrecomputedPairwiseWeights<Stat_>(ngroups, nblocks, combo_weights.data());
433 }
434
435 const auto ngroups2 = sanisizer::product<typename std::vector<Stat_>::size_type>(ngroups, ngroups);
436 tatami::parallelize([&](const int t, const Index_ start, const Index_ length) -> void {
437 std::vector<Stat_> pairwise_buffer(ngroups2);
438 std::vector<Stat_> summary_buffer(ngroups);
439
440 for (Index_ gene = start, end = start + length; gene < end; ++gene) {
441 const auto in_offset = sanisizer::product_unsafe<std::size_t>(gene, ncombos);
442
443 if (!output.mean.empty()) {
444 const auto tmp_means = combo_means.data() + in_offset;
445 average_group_stats(gene, ngroups, nblocks, tmp_means, combo_weights.data(), total_weights_ptr, output.mean);
446 }
447
448 if (!output.detected.empty()) {
449 const auto tmp_detected = combo_detected.data() + in_offset;
450 average_group_stats(gene, ngroups, nblocks, tmp_detected, combo_weights.data(), total_weights_ptr, output.detected);
451 }
452
453 if (output.cohens_d.size()) {
454 const auto tmp_means = combo_means.data() + in_offset;
455 const auto tmp_variances = combo_vars.data() + in_offset;
456 compute_pairwise_cohens_d(tmp_means, tmp_variances, ngroups, nblocks, preweights, threshold, pairwise_buffer.data());
457 compute_summary_stats_per_gene(gene, ngroups, pairwise_buffer.data(), summary_buffer, cohens_d_minrank_all_queues[t], output.cohens_d);
458 }
459
460 if (output.delta_mean.size()) {
461 const auto tmp_means = combo_means.data() + in_offset;
462 compute_pairwise_simple_diff(tmp_means, ngroups, nblocks, preweights, pairwise_buffer.data());
463 compute_summary_stats_per_gene(gene, ngroups, pairwise_buffer.data(), summary_buffer, delta_mean_minrank_all_queues[t], output.delta_mean);
464 }
465
466 if (output.delta_detected.size()) {
467 const auto tmp_det = combo_detected.data() + in_offset;
468 compute_pairwise_simple_diff(tmp_det, ngroups, nblocks, preweights, pairwise_buffer.data());
469 compute_summary_stats_per_gene(gene, ngroups, pairwise_buffer.data(), summary_buffer, delta_detected_minrank_all_queues[t], output.delta_detected);
470 }
471 }
472 }, ngenes, num_threads);
473
474 if (output.cohens_d.size()) {
475 report_minrank_from_queues(ngenes, ngroups, cohens_d_minrank_all_queues, output.cohens_d, num_threads, minrank_keep_ties);
476 }
477
478 if (output.delta_mean.size()) {
479 report_minrank_from_queues(ngenes, ngroups, delta_mean_minrank_all_queues, output.delta_mean, num_threads, minrank_keep_ties);
480 }
481
482 if (output.delta_detected.size()) {
483 report_minrank_from_queues(ngenes, ngroups, delta_detected_minrank_all_queues, output.delta_detected, num_threads, minrank_keep_ties);
484 }
485}
486
487template<typename Index_, typename Stat_, typename Rank_>
488ScoreMarkersSummaryBuffers<Stat_, Rank_> preallocate_summary_results(
489 const Index_ ngenes,
490 const std::size_t ngroups,
491 ScoreMarkersSummaryResults<Stat_, Rank_>& store,
492 const ScoreMarkersSummaryOptions& options)
493{
494 ScoreMarkersSummaryBuffers<Stat_, Rank_> output;
495
496 if (options.compute_group_mean) {
497 preallocate_average_results(ngenes, ngroups, store.mean, output.mean);
498 }
499
500 if (options.compute_group_detected) {
501 preallocate_average_results(ngenes, ngroups, store.detected, output.detected);
502 }
503
504 if (options.compute_cohens_d) {
505 output.cohens_d = fill_summary_results(
506 ngenes,
507 ngroups,
508 store.cohens_d,
509 options.compute_min,
510 options.compute_mean,
511 options.compute_median,
512 options.compute_max,
513 options.compute_min_rank
514 );
515 }
516
517 if (options.compute_auc) {
518 output.auc = fill_summary_results(
519 ngenes,
520 ngroups,
521 store.auc,
522 options.compute_min,
523 options.compute_mean,
524 options.compute_median,
525 options.compute_max,
526 options.compute_min_rank
527 );
528 }
529
530 if (options.compute_delta_mean) {
531 output.delta_mean = fill_summary_results(
532 ngenes,
533 ngroups,
534 store.delta_mean,
535 options.compute_min,
536 options.compute_mean,
537 options.compute_median,
538 options.compute_max,
539 options.compute_min_rank
540 );
541 }
542
543 if (options.compute_delta_detected) {
544 output.delta_detected = fill_summary_results(
545 ngenes,
546 ngroups,
547 store.delta_detected,
548 options.compute_min,
549 options.compute_mean,
550 options.compute_median,
551 options.compute_max,
552 options.compute_min_rank
553 );
554 }
555
556 return output;
557}
558
559template<
560 bool single_block_,
561 typename Value_,
562 typename Index_,
563 typename Group_,
564 typename Block_,
565 typename Stat_,
566 typename Rank_
567>
569 const tatami::Matrix<Value_, Index_>& matrix,
570 const std::size_t ngroups,
571 const Group_* const group,
572 const std::size_t nblocks,
573 const Block_* const block,
574 const std::size_t ncombos,
575 const std::size_t* const combo,
576 const std::vector<Index_>& combo_sizes,
577 const ScoreMarkersSummaryOptions& options,
578 const ScoreMarkersSummaryBuffers<Stat_, Rank_>& output
579) {
580 const auto ngenes = matrix.nrow();
581 const auto payload_size = sanisizer::product<typename std::vector<Stat_>::size_type>(ngenes, ncombos);
582 std::vector<Stat_> combo_means, combo_vars, combo_detected;
583 if (!output.mean.empty() || !output.cohens_d.empty() || !output.delta_mean.empty()) {
584 combo_means.resize(payload_size);
585 }
586 if (!output.cohens_d.empty()) {
587 combo_vars.resize(payload_size);
588 }
589 if (!output.detected.empty() || !output.delta_detected.empty()) {
590 combo_detected.resize(payload_size);
591 }
592
593 // For a single block, this usually doesn't really matter, but we do it for consistency with the multi-block case,
594 // and to account for variable weighting where non-zero block sizes get zero weight.
595 const auto combo_weights = scran_blocks::compute_weights<Stat_>(
596 combo_sizes,
597 options.block_weight_policy,
598 options.variable_block_weight_parameters
599 );
600
601 const Index_ minrank_limit = sanisizer::cap<Index_>(options.min_rank_limit);
602
603 if (!output.auc.empty()) {
604 std::vector<MinrankTopQueues<Stat_, Index_> > auc_minrank_all_queues;
605 preallocate_minrank_queues(ngroups, auc_minrank_all_queues, output.auc, minrank_limit, options.min_rank_preserve_ties, options.num_threads);
606
607 struct AucResultWorkspace {
608 AucResultWorkspace() = default;
609 AucResultWorkspace(const std::size_t ngroups, MinrankTopQueues<Stat_, Index_>& queues) :
610 pairwise_buffer(sanisizer::product<typename std::vector<Stat_>::size_type>(ngroups, ngroups)),
611 summary_buffer(sanisizer::cast<typename std::vector<Stat_>::size_type>(ngroups)),
612 queue_ptr(&queues)
613 {};
614 std::vector<Stat_> pairwise_buffer;
615 std::vector<Stat_> summary_buffer;
616 MinrankTopQueues<Stat_, Index_>* queue_ptr;
617 };
618
619 scan_matrix_by_row_custom_auc<single_block_>(
620 matrix,
621 ngroups,
622 group,
623 nblocks,
624 block,
625 ncombos,
626 combo,
627 combo_means,
628 combo_vars,
629 combo_detected,
630 /* do_auc = */ true,
631 /* auc_result_initialize = */ [&](const int t) -> AucResultWorkspace {
632 return AucResultWorkspace(ngroups, auc_minrank_all_queues[t]);
633 },
634 /* auc_result_process = */ [&](
635 const Index_ gene,
636 AucScanWorkspace<Value_, Group_, Index_, Stat_>& auc_work,
637 AucResultWorkspace& res_work
638 ) -> void {
639 process_auc_for_rows(auc_work, ngroups, nblocks, options.threshold, res_work.pairwise_buffer.data());
640 compute_summary_stats_per_gene(gene, ngroups, res_work.pairwise_buffer.data(), res_work.summary_buffer, *(res_work.queue_ptr), output.auc);
641 },
642 combo_sizes,
643 combo_weights,
644 options.num_threads
645 );
646
647 report_minrank_from_queues(ngenes, ngroups, auc_minrank_all_queues, output.auc, options.num_threads, options.min_rank_preserve_ties);
648
649 } else if (matrix.prefer_rows()) {
650 scan_matrix_by_row_full_auc<single_block_>(
651 matrix,
652 ngroups,
653 group,
654 nblocks,
655 block,
656 ncombos,
657 combo,
658 combo_means,
659 combo_vars,
660 combo_detected,
661 static_cast<Stat_*>(NULL),
662 combo_sizes,
663 combo_weights,
664 options.threshold,
665 options.num_threads
666 );
667
668 } else {
669 scan_matrix_by_column(
670 matrix,
671 [&]{
672 if constexpr(single_block_) {
673 return ngroups;
674 } else {
675 return ncombos;
676 }
677 }(),
678 [&]{
679 if constexpr(single_block_) {
680 return group;
681 } else {
682 return combo;
683 }
684 }(),
685 combo_means,
686 combo_vars,
687 combo_detected,
688 combo_sizes,
689 options.num_threads
690 );
691 }
692
693 process_simple_summary_effects(
694 matrix.nrow(),
695 ngroups,
696 nblocks,
697 ncombos,
698 combo_means,
699 combo_vars,
700 combo_detected,
701 output,
702 combo_weights,
703 options.threshold,
704 minrank_limit,
705 options.min_rank_preserve_ties,
706 options.num_threads
707 );
708}
709
710}
749template<typename Value_, typename Index_, typename Group_, typename Stat_, typename Rank_>
751 const tatami::Matrix<Value_, Index_>& matrix,
752 const Group_* const group,
753 const ScoreMarkersSummaryOptions& options,
755) {
756 const auto NC = matrix.ncol();
757 const auto group_sizes = tatami_stats::tabulate_groups(group, NC);
758 const auto ngroups = sanisizer::cast<std::size_t>(group_sizes.size());
759
760 internal::score_markers_summary<true>(
761 matrix,
762 ngroups,
763 group,
764 1,
765 static_cast<int*>(NULL),
766 ngroups,
767 static_cast<std::size_t*>(NULL),
768 group_sizes,
769 options,
770 output
771 );
772}
773
802template<typename Value_, typename Index_, typename Group_, typename Block_, typename Stat_, typename Rank_>
804 const tatami::Matrix<Value_, Index_>& matrix,
805 const Group_* const group,
806 const Block_* const block,
807 const ScoreMarkersSummaryOptions& options,
809{
810 const auto NC = matrix.ncol();
811 const auto ngroups = output.mean.size();
812 const auto nblocks = tatami_stats::total_groups(block, NC);
813
814 const auto combinations = internal::create_combinations(ngroups, group, block, NC);
815 const auto combo_sizes = internal::tabulate_combinations<Index_>(ngroups, nblocks, combinations);
816 const auto ncombos = combo_sizes.size();
817
818 internal::score_markers_summary<false>(
819 matrix,
820 sanisizer::cast<std::size_t>(ngroups),
821 group,
822 sanisizer::cast<std::size_t>(nblocks),
823 block,
824 sanisizer::cast<std::size_t>(ncombos),
825 combinations.data(),
826 combo_sizes,
827 options,
828 output
829 );
830}
831
832
850template<typename Stat_ = double, typename Rank_ = int, typename Value_, typename Index_, typename Group_>
852 const tatami::Matrix<Value_, Index_>& matrix,
853 const Group_* const group,
854 const ScoreMarkersSummaryOptions& options)
855{
856 const auto ngroups = tatami_stats::total_groups(group, matrix.ncol());
858 const auto buffers = internal::preallocate_summary_results(matrix.nrow(), ngroups, output, options);
859 score_markers_summary(matrix, group, options, buffers);
860 return output;
861}
862
883template<typename Stat_ = double, typename Rank_ = int, typename Value_, typename Index_, typename Group_, typename Block_>
885 const tatami::Matrix<Value_, Index_>& matrix,
886 const Group_* const group,
887 const Block_* const block,
888 const ScoreMarkersSummaryOptions& options)
889{
890 const auto ngroups = tatami_stats::total_groups(group, matrix.ncol());
892 const auto buffers = internal::preallocate_summary_results(matrix.nrow(), ngroups, output, options);
893 score_markers_summary_blocked(matrix, group, block, options, buffers);
894 return output;
895}
896
897}
898
899#endif
virtual Index_ ncol() const=0
virtual Index_ nrow() const=0
virtual bool prefer_rows() const=0
void compute_weights(const std::size_t num_blocks, const Size_ *const sizes, const WeightPolicy policy, const VariableWeightParameters &variable, Weight_ *const weights)
Marker detection for single-cell data.
Definition score_markers_pairwise.hpp:25
void score_markers_summary(const tatami::Matrix< Value_, Index_ > &matrix, const Group_ *const group, const ScoreMarkersSummaryOptions &options, const ScoreMarkersSummaryBuffers< Stat_, Rank_ > &output)
Definition score_markers_summary.hpp:750
void score_markers_summary_blocked(const tatami::Matrix< Value_, Index_ > &matrix, const Group_ *const group, const Block_ *const block, const ScoreMarkersSummaryOptions &options, const ScoreMarkersSummaryBuffers< Stat_, Rank_ > &output)
Definition score_markers_summary.hpp:803
void parallelize(Function_ fun, const Index_ tasks, const int threads)
Buffers for score_markers_summary() and friends.
Definition score_markers_summary.hpp:150
std::vector< Stat_ * > detected
Definition score_markers_summary.hpp:167
std::vector< SummaryBuffers< Stat_, Rank_ > > delta_detected
Definition score_markers_summary.hpp:203
std::vector< Stat_ * > mean
Definition score_markers_summary.hpp:158
std::vector< SummaryBuffers< Stat_, Rank_ > > delta_mean
Definition score_markers_summary.hpp:194
std::vector< SummaryBuffers< Stat_, Rank_ > > cohens_d
Definition score_markers_summary.hpp:176
std::vector< SummaryBuffers< Stat_, Rank_ > > auc
Definition score_markers_summary.hpp:185
Options for score_markers_summary() and friends.
Definition score_markers_summary.hpp:31
bool compute_group_detected
Definition score_markers_summary.hpp:55
bool compute_max
Definition score_markers_summary.hpp:103
bool compute_delta_detected
Definition score_markers_summary.hpp:79
bool compute_auc
Definition score_markers_summary.hpp:67
bool compute_group_mean
Definition score_markers_summary.hpp:49
bool compute_min
Definition score_markers_summary.hpp:85
bool compute_median
Definition score_markers_summary.hpp:97
bool compute_mean
Definition score_markers_summary.hpp:91
double threshold
Definition score_markers_summary.hpp:37
bool min_rank_preserve_ties
Definition score_markers_summary.hpp:123
scran_blocks::WeightPolicy block_weight_policy
Definition score_markers_summary.hpp:135
bool compute_cohens_d
Definition score_markers_summary.hpp:61
bool compute_min_rank
Definition score_markers_summary.hpp:109
int num_threads
Definition score_markers_summary.hpp:43
bool compute_delta_mean
Definition score_markers_summary.hpp:73
scran_blocks::VariableWeightParameters variable_block_weight_parameters
Definition score_markers_summary.hpp:141
std::size_t min_rank_limit
Definition score_markers_summary.hpp:116
Results for score_markers_summary() and friends.
Definition score_markers_summary.hpp:212
std::vector< SummaryResults< Stat_, Rank_ > > cohens_d
Definition score_markers_summary.hpp:232
std::vector< std::vector< Stat_ > > mean
Definition score_markers_summary.hpp:217
std::vector< SummaryResults< Stat_, Rank_ > > auc
Definition score_markers_summary.hpp:241
std::vector< SummaryResults< Stat_, Rank_ > > delta_detected
Definition score_markers_summary.hpp:259
std::vector< std::vector< Stat_ > > detected
Definition score_markers_summary.hpp:223
std::vector< SummaryResults< Stat_, Rank_ > > delta_mean
Definition score_markers_summary.hpp:250
Pointers to arrays to hold the summary statistics.
Definition summarize_comparisons.hpp:29
Utilities for effect summarization.