Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a48b5d3
src/quality_score.hcpp: renaming the to_string function because the a…
andrewdavidsmith Sep 1, 2026
3697635
.cppcheck_suppress: ignoring fmt and ignoring constStatement which se…
andrewdavidsmith Sep 1, 2026
6633d46
src/samrec.cpp: adding missing include
andrewdavidsmith Sep 1, 2026
c256b39
src/tile_processor.cpp: renaming variables to avoid shadowing
andrewdavidsmith Sep 1, 2026
7e962a2
src/bam_file.hcpp: headers and formatting for new clang-tidy
andrewdavidsmith Sep 1, 2026
d9a4f45
src/base_groups.hpp: removing nodiscard on void functions
andrewdavidsmith Sep 1, 2026
4a8c6f0
src/sam_file.cpp: adding includes and initializing cursor and last in…
andrewdavidsmith Sep 1, 2026
cd9127e
src/kmer_counter.hcpp: removing the apply_groups function which isn't…
andrewdavidsmith Sep 1, 2026
a39a7c8
src/original_duplicates.cpp: changed loop to alg
andrewdavidsmith Sep 1, 2026
5396c2e
src/falco_utils.hcpp: fixing nodiscards and an include
andrewdavidsmith Sep 1, 2026
d39f1df
src/falco_analyzer.cpp: adding an include for iwyu that seems wrong a…
andrewdavidsmith Sep 1, 2026
8cc60aa
src/bgzf_reader.cpp: static analysis
andrewdavidsmith Sep 1, 2026
646cd9c
src/falco_grade.hcpp: making a member function get_tile static and re…
andrewdavidsmith Sep 1, 2026
e79f931
src/adapter_set.cpp: iterating using itr = next(itr) for now when cle…
andrewdavidsmith Sep 1, 2026
0f5e495
src/html.cpp: headers and nolint on optin.cplusplus.UninitObj
andrewdavidsmith Sep 1, 2026
2163c8f
src/fastq_gz_file.cpp: header and nolint on pointer arithmetic
andrewdavidsmith Sep 1, 2026
e3fb8ce
src/falco_config.cpp: loop to alg
andrewdavidsmith Sep 1, 2026
77235a3
src/fastq_bgzf_file.cpp: loop to alg
andrewdavidsmith Sep 1, 2026
9320554
src/falco_word.hpp: nolint on array bound
andrewdavidsmith Sep 1, 2026
7524af5
src/contaminants.cpp: iterating using itr = next(itr) for now when cl…
andrewdavidsmith Sep 1, 2026
ea20a1b
src/contaminants.hpp: adding a header
andrewdavidsmith Sep 1, 2026
2d181f8
src/fastq_file.cpp: adding headers
andrewdavidsmith Sep 1, 2026
badab36
src/adapter_matcher.cpp: nolint and fixing the number of positions ou…
andrewdavidsmith Sep 1, 2026
37d4a61
src/falco_file_format.hcpp: includes
andrewdavidsmith Sep 1, 2026
4ce3f0e
src/duplication_results.hpp: explicit on single param constructor
andrewdavidsmith Sep 1, 2026
dcd8535
src/duplication_results.cpp: nolint on optin.cplusplus.UninitObj
andrewdavidsmith Sep 1, 2026
cadffe0
src/results_collector.hpp: casting in an assert to avoid side effect …
andrewdavidsmith Sep 1, 2026
c26cde0
src/results_summary.cpp: fixing var name to avoid shadowing
andrewdavidsmith Sep 1, 2026
089c478
src/report.cpp: removing include and fixing to_string for encoding to…
andrewdavidsmith Sep 1, 2026
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
3 changes: 3 additions & 0 deletions .cppcheck_suppress
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,12 @@ missingInclude
*:*CLI11.hpp
*:*json.hpp
*:*boost_unordered.hpp
*:fmt/*.h
# Problem caused by external files
toomanyconfigs
# More problems caused by external files -- with too many ifdefs
normalCheckLevelMaxBranches
# This seems not to work with the designs used here
duplInheritedMember
# Seems like iterator variables for std::views disagree with this
constStatement
15 changes: 9 additions & 6 deletions src/adapter_matcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ y: {},
type: "line",
name: "{}",
}})";
// NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject)
assert(std::size(groups) == std::size(adap_counts));
// calcualte the x axis first
const auto x = groups | std::views::transform([&](const auto &g) {
Expand All @@ -146,9 +147,9 @@ name: "{}",
std::ranges::transform(cumulative[curr], cumulative[prev],
std::begin(cumulative[curr]), std::plus{});
#endif
const auto n_pos = max_read_len + 1 >= adapter_size
? max_read_len - adapter_size + 1
: max_read_len;
// NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject)
const auto n_pos =
max_read_len + 1 > adapter_size ? (max_read_len + 1) - adapter_size : 0U;
const auto last_group_to_keep = std::ranges::find_if(
groups, [&](const auto &g) { return n_pos <= g.first; });
cumulative.resize(std::distance(std::cbegin(groups), last_group_to_keep));
Expand All @@ -164,13 +165,15 @@ name: "{}",
return pct_of_reads(cumul[adap_id]);
};
const auto y = cumulative | std::views::transform(make_y);
// NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject)
html_by_adapter.emplace_back(fmt::format(adapter_fmt, x, y, adap_name));
}
const auto grade = grades.grade(label);
const auto title = grades.get_title(label);
return fmt::format(
html_module_fmt, grade, label, title, grade,
std::format(plot_fmt, fmt::format("[{:n:}]", html_by_adapter)));
const auto the_plot =
// NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject)
std::format(plot_fmt, fmt::format("[{:n:}]", html_by_adapter));
return fmt::format(html_module_fmt, grade, label, title, grade, the_plot);
}

auto
Expand Down
3 changes: 2 additions & 1 deletion src/adapter_set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ load_adapters(const std::string &filename) {
// ADS: need to make sure this can't fail
line.remove_suffix(std::size(line) - to_keep_suffix - 1);
std::string cleaned_line;
for (auto itr = std::cbegin(line); itr != std::cend(line); ++itr)
for (auto itr = std::cbegin(line); itr != std::cend(line);
itr = std::next(itr))
if (!std::isblank(*itr) ||
(std::next(itr) != std::cend(line) && *itr != *std::next(itr)))
cleaned_line += *itr;
Expand Down
6 changes: 4 additions & 2 deletions src/bam_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
#include <stdexcept>
#include <string>
#include <system_error>
#include <tuple>
#include <utility>
#include <vector>

[[nodiscard]] auto
estimate_n_reads_bam(const std::string &filename)
Expand Down Expand Up @@ -63,8 +65,8 @@ estimate_n_reads_bam(const std::string &filename)
}

[[nodiscard]] auto
init_dups(const std::string &filename,
const std::uint64_t n_unique) -> dups_map_t {
init_dups(const std::string &filename, const std::uint64_t n_unique)
-> dups_map_t {
static constexpr auto complem = [](const auto x) {
return "TNGNNNCNNNNNNNNNNNNA"[x - 'A'];
};
Expand Down
9 changes: 6 additions & 3 deletions src/bam_file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ class bam_file {
~bam_file() = default;
// clang-format on

[[nodiscard]] operator bool() const { return !had_last_chunks; }
[[nodiscard]]
operator bool() const {
return !had_last_chunks;
}

friend auto
reset(bam_file &reads_file) -> void;
Expand Down Expand Up @@ -121,8 +124,8 @@ estimate_n_reads_bam(const std::string &filename)
-> std::tuple<std::uint64_t, std::uint64_t, std::int64_t>;

[[nodiscard]] auto
init_dups(const std::string &filename,
const std::uint64_t n_unique) -> dups_map_t;
init_dups(const std::string &filename, const std::uint64_t n_unique)
-> dups_map_t;

inline auto
make_tasks(bam_file &reads_file, //
Expand Down
8 changes: 4 additions & 4 deletions src/base_groups.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ make_base_groups(const std::uint64_t n_bases, const std::uint64_t n_initial,
const std::uint64_t n_groups_target) -> base_group_vec;

[[nodiscard]] auto
get_default_base_groups(const std::uint64_t n_bases,
const bool make_groups) -> base_group_vec;
get_default_base_groups(const std::uint64_t n_bases, const bool make_groups)
-> base_group_vec;

[[nodiscard]] auto
make_group_tag(const base_group_t g) -> std::string;

[[nodiscard]] auto
make_group_tag_quoted(const base_group_t g) -> std::string;

[[nodiscard]] auto
void
apply_base_groups(const base_group_vec &groups, auto &rows) {
assert(std::size(rows) <= groups.back().second);
auto group_itr = std::cbegin(groups);
Expand All @@ -50,7 +50,7 @@ apply_base_groups(const base_group_vec &groups, auto &rows) {
rows.resize(current_row);
}

[[nodiscard]] auto
void
apply_base_groups(const base_group_vec &groups, auto &rows, const auto &adder) {
assert(std::size(rows) <= groups.back().second);
auto group_itr = std::cbegin(groups);
Expand Down
5 changes: 4 additions & 1 deletion src/bgzf_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <cassert>
#include <cerrno>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <filesystem>
#include <memory>
Expand All @@ -28,6 +29,7 @@ get_unaligned_le32(const auto p) -> std::int32_t {
get_isize(const auto data, const auto data_size) {
static constexpr decltype(data_size) isize_size = 4;
assert(data_size > isize_size);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
const auto data_isize = data + data_size - isize_size;
return data_size < isize_size ? 0 : get_unaligned_le32(data_isize);
}
Expand All @@ -50,7 +52,8 @@ bgzf_reader::bgzf_reader(const std::string &filename,
next_in{inbuf.get()}, //
end_in{inbuf.get()}, //
next_out{outbuf.get()}, //
end_out{outbuf.get() + buf_size} //
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
end_out{outbuf.get() + buf_size} //
{}

[[nodiscard]] auto
Expand Down
4 changes: 3 additions & 1 deletion src/contaminants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <stdexcept>
#include <string>
#include <string_view>
#include <tuple> // for std::get
#include <utility>
#include <vector>

Expand Down Expand Up @@ -197,7 +198,8 @@ load_contaminants(const std::string &filename) -> void {
continue;
line.remove_suffix(std::size(line) - to_keep_suffix - 1);
std::string cleaned_line;
for (auto itr = std::cbegin(line); itr != std::cend(line); ++itr)
for (auto itr = std::cbegin(line); itr != std::cend(line);
itr = std::next(itr))
if (!std::isblank(*itr) ||
(std::next(itr) != std::cend(line) && *itr != *std::next(itr)))
cleaned_line += *itr;
Expand Down
1 change: 1 addition & 0 deletions src/contaminants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#define SRC_CONTAMINANTS_HPP_

#include <cstdint>
#include <ranges> // for std::pair
#include <string>
#include <utility> // IWYU pragma: keep
#include <vector>
Expand Down
25 changes: 14 additions & 11 deletions src/duplication_results.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "run_mode.hpp"

#define FMT_HEADER_ONLY
#include "fmt/base.h"
#include "fmt/format.h"
#include "fmt/ranges.h"

Expand Down Expand Up @@ -124,8 +125,8 @@ duplication_results::get_overrepresented(const std::uint64_t n_reads) const
}

auto
duplication_results::initialize(const run_mode &mode,
const file_info &info) -> void {
duplication_results::initialize(const run_mode &mode, const file_info &info)
-> void {
read_skip =
info.n_reads_est < max_n_reads_total
? 0
Expand Down Expand Up @@ -282,8 +283,8 @@ get_grade_duplication(const dup_summary_t &summary) -> std::string {
}

[[nodiscard]] auto
duplication_report(const dup_summary_t &summary,
const file_grades &grades) -> std::string {
duplication_report(const dup_summary_t &summary, const file_grades &grades)
-> std::string {
static constexpr auto label = "duplication";
static constexpr auto start_tag = ">>Sequence Duplication Levels\t{}\n"
"#Total Deduplicated Percentage\t{:.6f}\n";
Expand All @@ -305,9 +306,10 @@ duplication_report(const dup_summary_t &summary,
std::max(static_cast<std::uint64_t>(1), reduce(summary.hist_mass)));
auto r = std::format(start_tag, grades.grade(label), pct(frac_dedup));
r += header;
for (const auto [label, mass] :
for (const auto [bin_label, mass] :
std::views::zip(bin_labels, binned_mass_pct) | std::views::drop(1))
r += std::format("{}\t{:.3g}\n", label, mass); // Percentage format is .3g
r +=
std::format("{}\t{:.3g}\n", bin_label, mass); // Percentage format is .3g
return r + end_module_tag;
}

Expand Down Expand Up @@ -345,8 +347,8 @@ overrepresented_html(const std::vector<overrep_t> &overrep,
}

[[nodiscard]] auto
duplication_html(const dup_summary_t &summary,
const file_grades &grades) -> std::string {
duplication_html(const dup_summary_t &summary, const file_grades &grades)
-> std::string {
static constexpr auto label = "duplication";
static constexpr auto plot_format = R"(<div id="duplication_plot"></div>
<script>Plotly.newPlot("duplication_plot",
Expand Down Expand Up @@ -389,11 +391,12 @@ yaxis: {{title: "% of sequences"}},
};
const auto grade = grades.grade(label);
const auto title = grades.get_title(label);
return fmt::format(
html_module_fmt, grade, label, title, grade,
const auto the_plot =
// NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject)
fmt::format(plot_format, //
x, to_pct(summary.hist_mass) | std::views::drop(1), // y_tot,
x, to_pct(summary.hist_dedup) | std::views::drop(1), // y_dedup
x, x_text | std::views::drop(1) // tickvals
));
);
return fmt::format(html_module_fmt, grade, label, title, grade, the_plot);
}
10 changes: 5 additions & 5 deletions src/duplication_results.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ struct dups_init_t {
std::int64_t count_at_limit{};
dups_map_t dups_zero;
dups_init_t() = default;
dups_init_t(const dups_map_t &dups) {
explicit dups_init_t(const dups_map_t &dups) {
const auto vals = dups | std::views::values;
count_at_limit = static_cast<std::int64_t>(
std::reduce(std::cbegin(vals), std::cend(vals)));
Expand Down Expand Up @@ -113,12 +113,12 @@ struct duplication_results {
get_grade_duplication(const dup_summary_t &summary) -> std::string;

[[nodiscard]] auto
duplication_report(const dup_summary_t &summary,
const file_grades &grades) -> std::string;
duplication_report(const dup_summary_t &summary, const file_grades &grades)
-> std::string;

[[nodiscard]] auto
duplication_html(const dup_summary_t &summary,
const file_grades &grades) -> std::string;
duplication_html(const dup_summary_t &summary, const file_grades &grades)
-> std::string;

[[nodiscard]] auto
get_grade_overrepresented(const std::uint64_t n_reads,
Expand Down
3 changes: 2 additions & 1 deletion src/falco_analyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <mutex>
#include <ranges>
#include <thread>
#include <tuple> // for std::get (iwyu fp)
#include <utility>
#include <variant>
#include <vector>
Expand All @@ -34,7 +35,6 @@ analyze(const std::uint32_t n_threads, const run_mode &mode,
const std::int32_t n_files = static_cast<std::int32_t>(std::size(infos));
if (dups_init.empty())
dups_init.resize(n_files);
std::vector<std::atomic_int32_t> n_tasks(n_files);
std::atomic_uint32_t n_active_files{static_cast<std::uint32_t>(n_files)};
auto results =
std::vector(n_threads, std::vector<results_collector>(n_files));
Expand All @@ -45,6 +45,7 @@ analyze(const std::uint32_t n_threads, const run_mode &mode,
tq.push(file_id, std::monostate{});

{ // scope to join jthreads
std::vector<std::atomic_int32_t> n_tasks(n_files);
std::vector<std::jthread> workers;
for (const auto th_id : std::views::iota(0u, n_threads))
workers.emplace_back([&, n_threads, th_id] {
Expand Down
18 changes: 10 additions & 8 deletions src/falco_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ split(const std::string &s) {
}

auto
load_config_and_set_graders(const std::string &filename,
run_mode &mode) -> void {
load_config_and_set_graders(const std::string &filename, run_mode &mode)
-> void {
// ADS: (todo) handle carriage returns and other control chars
std::ifstream in(filename);
if (!in)
Expand All @@ -61,9 +61,10 @@ load_config_and_set_graders(const std::string &filename,
}

// modes
for (const auto &label : run_mode::get_labels())
std::ranges::for_each(run_mode::get_labels(), [&](const auto &label) {
if (json_in.contains(label) && !json_in[label].contains("ignore"))
throw std::runtime_error("invalid config: " + to_string(json_in[label]));
});

std::unordered_map<std::string, bool> modes_in;
try {
Expand All @@ -83,11 +84,12 @@ load_config_and_set_graders(const std::string &filename,
mode.assign(modes_in);

// grades
for (const auto &label : grade_labels)
if (json_in.contains(label) &&
!(json_in[label].contains("error") && json_in[label].contains("warn")))
throw std::runtime_error("missing config value for: " +
std::string(label));
std::ranges::for_each(grade_labels, [&](const auto &l) {
if (json_in.contains(l) &&
!(json_in[l].contains("error") && json_in[l].contains("warn")))
throw std::runtime_error("missing config value for: " + std::string(l));
});

std::unordered_map<std::string, grader> graders;
try {
for (const auto &label : grade_labels) {
Expand Down
4 changes: 4 additions & 0 deletions src/falco_file_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
#include <array>
#include <cstdlib>
#include <filesystem>
#include <iterator>
#include <memory>
#include <stdexcept>
#include <string>
#include <tuple>

[[nodiscard]] auto
get_file_format(const std::string &filename)
Expand Down
2 changes: 0 additions & 2 deletions src/falco_file_format.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

#include <cstdint>
#include <format>
#include <iterator>
#include <memory>
#include <string>
#include <thread>
#include <tuple>
Expand Down
Loading