Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ test_scripts/test_unxcounts.log: test_scripts/test_xcounts.log

noinst_LIBRARIES = libdnmtools.a
libdnmtools_a_SOURCES = \
src/common/file_progress.cpp \
src/common/Interval.cpp \
src/common/Interval6.cpp \
src/common/dnmtools_gaussinv.cpp \
Expand All @@ -175,6 +176,7 @@ libdnmtools_a_SOURCES = \

libdnmtools_a_SOURCES += \
src/common/dnmtools_lgamma.hpp \
src/common/file_progress.hpp \
src/common/Interval.hpp \
src/common/Interval6.hpp \
src/common/dnmtools_gaussinv.hpp \
Expand Down
6 changes: 3 additions & 3 deletions src/amrfinder/amrtester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ methylation
static void
backup_to_start_of_current_record(std::ifstream &in) {
static constexpr std::size_t assumed_max_valid_line_width = 10000;
std::size_t count = 0;
std::size_t byte_count = 0;
while (in.tellg() > 0 && in.peek() != '\n' && in.peek() != '\r' &&
count++ < assumed_max_valid_line_width)
byte_count++ < assumed_max_valid_line_width)
in.seekg(-1, std::ios_base::cur);
if (count > assumed_max_valid_line_width)
if (byte_count > assumed_max_valid_line_width)
throw std::runtime_error("file contains a line longer than " +
std::to_string(assumed_max_valid_line_width));
}
Expand Down
3 changes: 2 additions & 1 deletion src/analysis/multimethstat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ process_with_cpgs_loaded(const bool verbose,
throw std::runtime_error("cannot open file: " + cpgs_file);

std::string header;
getline(in, header);
if (!getline(in, header))
throw std::runtime_error("failed to read header");

std::istringstream iss(header);
std::string col_name;
Expand Down
9 changes: 5 additions & 4 deletions src/analysis/pmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -712,11 +712,13 @@ check_if_array_data(const std::string &infile) {
skip_counts_header(in);

std::string line;
getline(in, line);
if (!getline(in, line))
throw std::runtime_error("failed to read line from file: " + infile);

std::istringstream iss(line);
std::string chrom, pos, strand, seq, meth, cov;
iss >> chrom >> pos >> strand >> seq >> meth;
return (!(iss >> cov));
return !(iss >> cov);
}

static void
Expand Down Expand Up @@ -1205,8 +1207,7 @@ main_pmd(int argc, char *argv[]) { // NOLINT(*-avoid-c-arrays)
double confidence_interval = default_confidence_interval;
double prop_accept = default_prop_accept;
for (std::size_t i = 0; i < n_replicates && !insufficient_data; ++i) {
const bool arrayData = check_if_array_data(cpgs_file[i]);
if (!arrayData) {
if (!check_if_array_data(cpgs_file[i])) {
bin_size =
binsize_selection(resolution, min_bin_size, max_bin_size,
confidence_interval, prop_accept, cpgs_file[i]);
Expand Down
16 changes: 10 additions & 6 deletions src/analysis/roimethstat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,9 @@ get_bed_columns(const std::string &regions_file) {
return n_columns;
}

static auto
[[nodiscard]] static auto
get_intervals(const std::string &filename) -> std::vector<Interval6> {
static constexpr auto n_bed6_cols = 6;
const auto field_count = [&] {
bamxx::bgzf_file in(filename, "r");
if (!in)
Expand All @@ -419,13 +420,16 @@ get_intervals(const std::string &filename) -> std::vector<Interval6> {
(std::istream_iterator<std::string>()));
return std::size(v);
}();
if (field_count >= 6)
if (field_count >= n_bed6_cols)
return read_intervals6(filename);

auto without_names = read_intervals(filename);
std::vector<Interval6> intervals;
for (const auto &w : without_names)
intervals.emplace_back(w.chrom, w.start, w.stop, std::string{}, 0, '+');
const auto without_names = read_intervals(filename);
std::vector<Interval6> intervals(std::size(without_names));
std::transform(std::cbegin(without_names), std::cend(without_names),
std::begin(intervals), [&](const auto &w) {
return Interval6(w.chrom, w.start, w.stop, std::string{}, 0,
'+');
});
return intervals;
}

Expand Down
48 changes: 48 additions & 0 deletions src/common/file_progress.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* Copyright (C) 2025 Andrew D Smith
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/

#include "file_progress.hpp"

#include <filesystem>
#include <iomanip>
#include <iostream>
#include <limits>
#include <string>

// NOLINTBEGIN(*-narrowing-conversions)

file_progress::file_progress(const std::string &filename) :
one_thousand_over_filesize{
static_cast<double>(one_thousand) /
static_cast<double>(std::filesystem::file_size(filename))} {}

void
file_progress::operator()(
std::ifstream &in) { // cppcheck-suppress constParameterReference
static constexpr auto ten = 10.0;
const std::size_t curr_offset =
in.eof() ? one_thousand : in.tellg() * one_thousand_over_filesize;
if (curr_offset <= prev_offset)
return;
std::ios old_state(nullptr);
old_state.copyfmt(std::cerr);
std::cerr << "\r[progress: " << std::setw(5) // NOLINT(*-avoid-magic-numbers)
<< std::fixed << std::setprecision(1) << (curr_offset / ten)
<< (curr_offset == one_thousand ? "%]\n" : "%]");
std::cerr.copyfmt(old_state);
prev_offset = curr_offset == one_thousand
? std::numeric_limits<std::size_t>::max()
: curr_offset;
}

// NOLINTEND(*-narrowing-conversions)
32 changes: 32 additions & 0 deletions src/common/file_progress.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* Copyright (C) 2025 Andrew D Smith
*
* Author: Andrew D. Smith
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/

#ifndef SRC_COMMON_FILE_PROGRESS_HPP_
#define SRC_COMMON_FILE_PROGRESS_HPP_

#include <cstddef>
#include <fstream>
#include <string>

struct file_progress {
static constexpr auto one_thousand{1000ul};
double one_thousand_over_filesize{};
std::size_t prev_offset{};
explicit file_progress(const std::string &filename);
void
operator()(std::ifstream &in); // cppcheck-suppress constParameterReference
};

#endif // SRC_COMMON_FILE_PROGRESS_HPP_
6 changes: 2 additions & 4 deletions src/radmeth/radmeth.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
/* Copyright (C) 2013-2025 Andrew D Smith
*
* Author: Andrew D. Smith
* Contributors: Egor Dolzhenko and Guilherme Sena
/* Copyright (C) 2013-2025 Andrew D Smith, Egor Dolzhenko and Guilherme Sena
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
Expand All @@ -14,6 +11,7 @@
* more details.
*/

#include "file_progress.hpp"
#include "radmeth_design.hpp"
#include "radmeth_model.hpp"
#include "radmeth_optimize_params.hpp"
Expand Down
9 changes: 5 additions & 4 deletions src/radmeth/radmeth_nano.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/* Copyright (C) 2025 Andrew D Smith
*
* Author: Andrew D. Smith
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
Expand All @@ -13,6 +11,7 @@
* more details.
*/

#include "file_progress.hpp"
#include "radmeth_design.hpp"
#include "radmeth_model.hpp"
#include "radmeth_optimize_gamma.hpp"
Expand All @@ -36,8 +35,9 @@
#include <utility>
#include <vector>

template <typename RegressionType>
[[nodiscard]] static bool
has_low_coverage(const Regression<double> &reg, const std::size_t test_factor) {
has_low_coverage(const RegressionType &reg, const std::size_t test_factor) {
bool cvrd_in_test_fact_smpls = false;
const auto &tcol = reg.design.tmatrix[test_factor];
for (std::size_t i = 0; i < reg.n_samples() && !cvrd_in_test_fact_smpls; ++i)
Expand All @@ -50,8 +50,9 @@ has_low_coverage(const Regression<double> &reg, const std::size_t test_factor) {
return !cvrd_in_test_fact_smpls || !cvrd_in_other_smpls;
}

template <typename RegressionType>
[[nodiscard]] static bool
has_extreme_counts(const Regression<double> &reg) {
has_extreme_counts(const RegressionType &reg) {
const auto &mc = reg.mc;

bool full_meth = true;
Expand Down
41 changes: 9 additions & 32 deletions src/radmeth/radmeth_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@

#include <chrono>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <iomanip>
#include <iostream>
#include <limits>
#include <sstream>
#include <string>

// NOLINTBEGIN(*-narrowing-conversions,*-avoid-magic-numbers)
// NOLINTBEGIN(*-narrowing-conversions)

[[nodiscard]] std::string
format_duration(const std::chrono::duration<double> elapsed) {
Expand All @@ -39,32 +38,14 @@ format_duration(const std::chrono::duration<double> elapsed) {
const double seconds = tot_s - (hours * s_per_h) - (minutes * s_per_m);

std::ostringstream oss;
// NOLINTBEGIN(*-avoid-magic-numbers)
oss << std::setfill('0') << std::setw(2) << hours << ":" << std::setfill('0')
<< std::setw(2) << minutes << ":" << std::fixed << std::setprecision(2)
<< std::setw(5) << seconds;
// NOLINTEND(*-avoid-magic-numbers)
return oss.str();
}

file_progress::file_progress(const std::string &filename) :
one_thousand_over_filesize{1000.0 / std::filesystem::file_size(filename)} {}

void
file_progress::operator()(
std::ifstream &in) { // cppcheck-suppress constParameterReference
const std::size_t curr_offset =
in.eof() ? 1000 : in.tellg() * one_thousand_over_filesize;
if (curr_offset <= prev_offset)
return;
std::ios old_state(nullptr);
old_state.copyfmt(std::cerr);
std::cerr << "\r[progress: " << std::setw(5) << std::fixed
<< std::setprecision(1) << (curr_offset / 10.0)
<< (curr_offset == 1000 ? "%]\n" : "%]");
std::cerr.copyfmt(old_state);
prev_offset = (curr_offset == 1000) ? std::numeric_limits<std::size_t>::max()
: curr_offset;
}

// Series representation for the lower incomplete gamma P(a,x)
[[nodiscard]] static double
gamma_p_series(const double a, const double x) {
Expand Down Expand Up @@ -113,19 +94,15 @@ gamma_q_contfrac(const double a, const double x) {
// Regularized lower incomplete gamma P(a,x)
[[nodiscard]] static double
gamma_p(const double a, const double x) {
if (x < 0 || a <= 0)
return 0.0;
if (x == 0)
return 0.0;
if (x < a + 1.0)
return gamma_p_series(a, x);
return 1.0 - gamma_q_contfrac(a, x);
return x <= 0.0 || a <= 0 ? 0.0
: (x < a + 1.0 ? gamma_p_series(a, x)
: 1.0 - gamma_q_contfrac(a, x));
}

// chi-square CDF: P(k/2, x/2)
[[nodiscard]] static double
chi_square_cdf(const double x, const double k) {
return gamma_p(k * 0.5, x * 0.5);
return gamma_p(k / 2, x / 2);
}

// Given the maximum likelihood estimates of the full and reduced models, the
Expand All @@ -148,4 +125,4 @@ llr_test(const double null_loglik, const double full_loglik) {
return p_value;
}

// NOLINTEND(*-narrowing-conversions,*-avoid-magic-numbers)
// NOLINTEND(*-narrowing-conversions)
10 changes: 0 additions & 10 deletions src/radmeth/radmeth_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,12 @@
#define RADMETH_UTILS_HPP

#include <chrono>
#include <cstddef>
#include <cstdint>
#include <fstream>
#include <string>

[[nodiscard]] std::string
format_duration(const std::chrono::duration<double> elapsed);

struct file_progress {
double one_thousand_over_filesize{};
std::size_t prev_offset{};
explicit file_progress(const std::string &filename);
void
operator()(std::ifstream &in); // cppcheck-suppress constParameterReference
};

[[nodiscard]] double
llr_test(const double null_loglik, const double full_loglik);

Expand Down
Loading