Skip to content

Commit 6f11fa1

Browse files
src/analysis/nanopore.cpp: adding a more verbose error message when the modifications are not as expected
1 parent 71bf7c1 commit 6f11fa1

File tree

1 file changed

+30
-7
lines changed

1 file changed

+30
-7
lines changed

src/analysis/nanopore.cpp

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,11 @@ struct mod_prob_buffer {
313313
bam_parse_basemod(aln.b, m.get());
314314
// ADS: or bam_parse_basemod2(aln.b, m, HTS_MOD_REPORT_UNCHECKED)
315315

316+
int n_types{};
317+
const auto types = bam_mods_recorded(m.get(), &n_types);
318+
if (n_types < 2 || (types[h_idx] != 'h' && types[m_idx] != 'm'))
319+
return false;
320+
316321
int pos{};
317322
int n{};
318323
while ((n = bam_next_basemod(aln.b, m.get(), d, max_mods, &pos)) > 0) {
@@ -502,7 +507,7 @@ struct mod_prob_stats {
502507

503508
mod_prob_stats() : m{hts_base_mod_state_alloc(), &hts_base_mod_state_free} {};
504509

505-
[[nodiscard]] auto
510+
auto
506511
operator()(const bamxx::bam_rec &aln) {
507512
static constexpr auto h_idx = 0;
508513
static constexpr auto m_idx = 1;
@@ -514,6 +519,11 @@ struct mod_prob_stats {
514519
bam_parse_basemod(aln.b, m.get());
515520
// ADS: or bam_parse_basemod2(aln.b, m, HTS_MOD_REPORT_UNCHECKED)
516521

522+
int n_types{};
523+
const auto types = bam_mods_recorded(m.get(), &n_types);
524+
if (n_types < 2 || (types[h_idx] != 'h' && types[m_idx] != 'm'))
525+
return;
526+
517527
int pos{};
518528
int n{};
519529
while ((n = bam_next_basemod(aln.b, m.get(), d, max_mods, &pos)) > 0) {
@@ -907,7 +917,8 @@ struct read_processor {
907917

908918
[[nodiscard]] static auto
909919
valid_modification_types(const std::string &infile,
910-
const std::uint32_t n_reads_to_check) -> bool {
920+
const std::uint32_t n_reads_to_check)
921+
-> std::pair<bool, std::string> {
911922
using mstate = hts_base_mod_state;
912923
std::unique_ptr<mstate, void (*)(mstate *)> m(hts_base_mod_state_alloc(),
913924
&hts_base_mod_state_free);
@@ -918,6 +929,8 @@ valid_modification_types(const std::string &infile,
918929
if (!hdr)
919930
throw std::runtime_error("failed to read header");
920931

932+
std::string message;
933+
921934
std::uint32_t read_count{};
922935
bool valid_types{true};
923936
bamxx::bam_rec aln;
@@ -929,9 +942,17 @@ valid_modification_types(const std::string &infile,
929942
// ADS: or bam_parse_basemod2(aln.b, m, HTS_MOD_REPORT_UNCHECKED)
930943
int n_types{};
931944
const auto types = bam_mods_recorded(m.get(), &n_types);
932-
valid_types = n_types >= 2 && types[0] == 'h' && types[1] == 'm';
945+
valid_types = (n_types == 1 && types[0] == 'C') ||
946+
(n_types >= 2 && types[0] == 'h' && types[1] == 'm');
947+
if (!valid_types) {
948+
message = "n_types: " + std::to_string(n_types) + "\n";
949+
for (auto i = 0; i < n_types; ++i) {
950+
message += "type[" + std::to_string(i) +
951+
"]=" + std::to_string(static_cast<char>(types[i])) + "\n";
952+
}
953+
}
933954
}
934-
return valid_types;
955+
return std::make_pair(valid_types, message);
935956
}
936957

937958
[[nodiscard]] static auto
@@ -1053,9 +1074,11 @@ main_nanocount(int argc, char *argv[]) { // NOLINT(*-avoid-c-arrays)
10531074
std::ostringstream cmd;
10541075
std::copy(argv, argv + argc, std::ostream_iterator<const char *>(cmd, " "));
10551076

1056-
if (!valid_modification_types(mapped_reads_file, n_reads_to_check)) {
1057-
std::cerr << "modification types are not valid\n"
1058-
<< "expected h=0 and m=1\n";
1077+
const auto [is_valid, message] =
1078+
valid_modification_types(mapped_reads_file, n_reads_to_check);
1079+
if (!is_valid) {
1080+
std::cerr << "modification types are not valid. Violation:\n"
1081+
<< message << '\n';
10591082
return EXIT_FAILURE;
10601083
}
10611084

0 commit comments

Comments
 (0)