Skip to content

Commit 8bd6d51

Browse files
src/utils/xcounts.cpp: adding better error reporting
1 parent 52bc666 commit 8bd6d51

1 file changed

Lines changed: 52 additions & 62 deletions

File tree

src/utils/xcounts.cpp

Lines changed: 52 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,41 @@
1-
/* xcounts: reformat counts so they only give the m and u counts in a
2-
* dynamic step wig format
1+
/* xcounts: reformat counts so they only give the m and u counts in a dynamic
2+
* step wig format
33
*
44
* Copyright (C) 2023 Andrew D. Smith
55
*
66
* Authors: Andrew D. Smith
77
*
8-
* This program is free software: you can redistribute it and/or
9-
* modify it under the terms of the GNU General Public License as
10-
* published by the Free Software Foundation, either version 3 of the
11-
* License, or (at your option) any later version.
8+
* This program is free software: you can redistribute it and/or modify it
9+
* under the terms of the GNU General Public License as published by the Free
10+
* Software Foundation, either version 3 of the License, or (at your option)
11+
* any later version.
1212
*
13-
* This program is distributed in the hope that it will be useful, but
14-
* WITHOUT ANY WARRANTY; without even the implied warranty of
15-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16-
* General Public License for more details.
13+
* This program is distributed in the hope that it will be useful, but WITHOUT
14+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16+
* more details.
1717
*/
1818

19+
#include "MSite.hpp"
20+
#include "counts_header.hpp"
21+
#include "dnmt_error.hpp"
22+
1923
#include <bamxx.hpp>
2024

25+
// from smithlab_cpp
26+
#include "OptionParser.hpp"
27+
#include "smithlab_os.hpp"
28+
#include "smithlab_utils.hpp"
29+
2130
#include <charconv>
31+
#include <cstdint>
2232
#include <iostream>
2333
#include <stdexcept>
2434
#include <string>
2535
#include <system_error>
2636
#include <type_traits> // std::underlying_type_t
2737
#include <vector>
2838

29-
// from smithlab_cpp
30-
#include "OptionParser.hpp"
31-
#include "smithlab_os.hpp"
32-
#include "smithlab_utils.hpp"
33-
34-
#include "MSite.hpp"
35-
#include "counts_header.hpp"
36-
#include "dnmt_error.hpp"
37-
38-
using std::cerr;
39-
using std::cout;
40-
using std::endl;
41-
using std::runtime_error;
42-
using std::string;
43-
using std::to_chars;
44-
using std::to_string;
45-
using std::vector;
46-
47-
using bamxx::bgzf_file;
48-
4939
enum class xcounts_err {
5040
// clang-format off
5141
ok = 0,
@@ -92,14 +82,14 @@ make_error_code(xcounts_err e) {
9282
}
9383

9484
template <typename T>
95-
static inline uint32_t
96-
fill_output_buffer(const uint32_t offset, const MSite &s, T &buf) {
85+
static inline std::uint32_t
86+
fill_output_buffer(const std::uint32_t offset, const MSite &s, T &buf) {
9787
auto buf_end = buf.data() + buf.size();
98-
auto res = to_chars(buf.data(), buf_end, s.pos - offset);
88+
auto res = std::to_chars(buf.data(), buf_end, s.pos - offset);
9989
*res.ptr++ = '\t';
100-
res = to_chars(res.ptr, buf_end, s.n_meth());
90+
res = std::to_chars(res.ptr, buf_end, s.n_meth());
10191
*res.ptr++ = '\t';
102-
res = to_chars(res.ptr, buf_end, s.n_unmeth());
92+
res = std::to_chars(res.ptr, buf_end, s.n_unmeth());
10393
*res.ptr++ = '\n';
10494
return std::distance(buf.data(), res.ptr);
10595
}
@@ -111,12 +101,12 @@ main_xcounts(int argc, char *argv[]) {
111101
bool gzip_output = false;
112102
bool keep_all_sites = false;
113103
bool require_coverage = false;
114-
size_t n_threads = 1;
115-
string genome_file;
116-
string header_file;
104+
std::size_t n_threads = 1;
105+
std::string genome_file;
106+
std::string header_file;
117107

118-
string outfile{"-"};
119-
const string description =
108+
std::string outfile{"-"};
109+
const std::string description =
120110
"compress counts files by removing context information";
121111

122112
/****************** COMMAND LINE OPTIONS ********************/
@@ -138,30 +128,30 @@ main_xcounts(int argc, char *argv[]) {
138128
"gzip compress output (automatic if input is gzip)",
139129
false, gzip_output);
140130
opt_parse.add_opt("verbose", 'v', "print more run info", false, verbose);
141-
std::vector<string> leftover_args;
131+
std::vector<std::string> leftover_args;
142132
opt_parse.parse(argc, argv, leftover_args);
143133
if (argc == 1 || opt_parse.help_requested()) {
144-
cerr << opt_parse.help_message() << endl
145-
<< opt_parse.about_message() << endl;
134+
std::cerr << opt_parse.help_message() << '\n'
135+
<< opt_parse.about_message() << '\n';
146136
return EXIT_SUCCESS;
147137
}
148138
if (opt_parse.about_requested()) {
149-
cerr << opt_parse.about_message() << endl;
139+
std::cerr << opt_parse.about_message() << '\n';
150140
return EXIT_SUCCESS;
151141
}
152142
if (opt_parse.option_missing()) {
153-
cerr << opt_parse.option_missing_message() << endl;
143+
std::cerr << opt_parse.option_missing_message() << '\n';
154144
return EXIT_SUCCESS;
155145
}
156146
if (leftover_args.size() != 1) {
157-
cerr << opt_parse.help_message() << endl;
147+
std::cerr << opt_parse.help_message() << '\n';
158148
return EXIT_SUCCESS;
159149
}
160-
const string filename(leftover_args.front());
150+
const std::string filename(leftover_args.front());
161151
/****************** END COMMAND LINE OPTIONS *****************/
162152

163-
vector<string> chrom_names;
164-
vector<uint64_t> chrom_sizes;
153+
std::vector<std::string> chrom_names;
154+
std::vector<std::uint64_t> chrom_sizes;
165155
if (!genome_file.empty()) {
166156
const int ret = get_chrom_sizes_for_counts_header(
167157
n_threads, genome_file, chrom_names, chrom_sizes);
@@ -170,13 +160,13 @@ main_xcounts(int argc, char *argv[]) {
170160
}
171161

172162
bamxx::bam_tpool tpool(n_threads);
173-
bgzf_file in(filename, "r");
163+
bamxx::bgzf_file in(filename, "r");
174164
if (!in)
175165
throw dnmt_error{"could not open file: " + filename};
176166

177167
const auto outfile_mode = (gzip_output || in.is_compressed()) ? "w" : "wu";
178168

179-
bgzf_file out(outfile, outfile_mode);
169+
bamxx::bgzf_file out(outfile, outfile_mode);
180170
if (!out)
181171
throw dnmt_error{"error opening output file: " + outfile};
182172

@@ -186,7 +176,7 @@ main_xcounts(int argc, char *argv[]) {
186176
tpool.set_io(out);
187177
}
188178

189-
std::unordered_map<string, uint32_t> chrom_order;
179+
std::unordered_map<std::string, std::uint32_t> chrom_order;
190180
if (!header_file.empty())
191181
chrom_order = write_counts_header_from_file(header_file, out);
192182
else if (!genome_file.empty())
@@ -199,23 +189,23 @@ main_xcounts(int argc, char *argv[]) {
199189
if (ret)
200190
throw dnmt_error("failed to acquire buffer");
201191

202-
vector<char> buf(128);
192+
std::vector<char> buf(128);
203193

204-
uint32_t offset = 0;
205-
string prev_chrom;
194+
std::uint32_t offset = 0;
195+
std::string prev_chrom;
206196
bool found_header = (!genome_file.empty() || !header_file.empty());
207197

208198
std::error_code ec{};
209199

210-
uint32_t chrom_counter = 0;
200+
std::uint32_t chrom_counter = 0;
211201

212202
MSite site;
213203
while (ec == std::errc{} && bamxx::getline(in, line)) {
214204
if (is_counts_header_line(line.s)) {
215205
if (!genome_file.empty() || !header_file.empty())
216206
continue;
217207
found_header = true;
218-
const string header_line{line.s};
208+
const std::string header_line{line.s};
219209
write_counts_header_line(header_line, out);
220210
continue;
221211
}
@@ -231,7 +221,7 @@ main_xcounts(int argc, char *argv[]) {
231221

232222
if (site.chrom != prev_chrom) {
233223
if (verbose)
234-
cerr << "processing: " << site.chrom << endl;
224+
std::cerr << "processing: " << site.chrom << '\n';
235225

236226
if (!chrom_order.empty()) {
237227
const auto expected_chrom_counter = chrom_order.find(site.chrom);
@@ -245,7 +235,7 @@ main_xcounts(int argc, char *argv[]) {
245235
}
246236
}
247237

248-
chrom_counter++;
238+
++chrom_counter;
249239

250240
prev_chrom = site.chrom;
251241
offset = 0;
@@ -265,13 +255,13 @@ main_xcounts(int argc, char *argv[]) {
265255
ks_free(&line);
266256

267257
if (ec) {
268-
cerr << "failed converting " << filename << " to " << outfile << endl
269-
<< ec << endl;
258+
std::cerr << "failed converting " << filename << " to " << outfile << '\n'
259+
<< ec.message() << '\n';
270260
return EXIT_FAILURE;
271261
}
272262
}
273263
catch (const std::exception &e) {
274-
cerr << e.what() << endl;
264+
std::cerr << e.what() << '\n';
275265
return EXIT_FAILURE;
276266
}
277267
return EXIT_SUCCESS;

0 commit comments

Comments
 (0)