diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ad18ef..e1f4e8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ find_package(ZLIB REQUIRED) find_package(OpenMP REQUIRED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DXXH_INLINE_ALL -D__STDC_FORMAT_MACROS") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DXXH_INLINE_ALL -D__STDC_FORMAT_MACROS -ftemplate-depth=3000") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unused-function") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprefetch-loop-arrays -funroll-loops") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__XROOT__='\"${CMAKE_SOURCE_DIR}/src\"'") diff --git a/src/assembly/contig_stat.h b/src/assembly/contig_stat.h index 91f20a6..4b859d9 100644 --- a/src/assembly/contig_stat.h +++ b/src/assembly/contig_stat.h @@ -34,9 +34,9 @@ inline ContigStat CalcAndPrintStat(UnitigGraph &graph, bool print = true, bool c if (print) { xinfo(""); for (auto &kv : stat) { - xinfoc("%s: %lu, ", kv.first.c_str(), kv.second); + xinfoc("{}: {}, ", kv.first.c_str(), kv.second); } - xinfoc("\n"); + xinfoc("{}", "\n"); } return stat; } diff --git a/src/assembly/contig_writer.h b/src/assembly/contig_writer.h index a80e604..92bc1df 100644 --- a/src/assembly/contig_writer.h +++ b/src/assembly/contig_writer.h @@ -8,12 +8,13 @@ #include #include #include +#include "utils/utils.h" class UnitigGraph; inline void WriteContig(const std::string &ascii_contig, unsigned k_size, long long id, int flag, double multi, FILE *file) { - fprintf(file, ">k%d_%lld flag=%d multi=%.4lf len=%lu\n%s\n", k_size, id, flag, multi, ascii_contig.length(), + pfprintf(file, ">k{}_{} flag={} multi={.4} len={}\n{}\n", k_size, id, flag, multi, ascii_contig.length(), ascii_contig.c_str()); } diff --git a/src/assembly/sdbg_pruning.cpp b/src/assembly/sdbg_pruning.cpp index b64da58..2f11a51 100644 --- a/src/assembly/sdbg_pruning.cpp +++ b/src/assembly/sdbg_pruning.cpp @@ -164,20 +164,20 @@ uint64_t RemoveTips(SDBG &dbg, int max_tip_len) { } for (int len = 2; len < max_tip_len; len *= 2) { - xinfo("Removing tips with length less than %d; ", len); + xinfo("Removing tips with length less than {}; ", len); timer.reset(); timer.start(); number_tips += Trim(dbg, len, ignored); timer.stop(); - xinfoc("Accumulated tips removed: %lld; time elapsed: %.4f\n", (long long)number_tips, timer.elapsed()); + xinfoc("Accumulated tips removed: {}; time elapsed: {.4}\n", number_tips, timer.elapsed()); } - xinfo("Removing tips with length less than %d; ", max_tip_len); + xinfo("Removing tips with length less than {}; ", max_tip_len); timer.reset(); timer.start(); number_tips += Trim(dbg, max_tip_len, ignored); timer.stop(); - xinfoc("Accumulated tips removed: %lld; time elapsed: %.4f\n", (long long)number_tips, timer.elapsed()); + xinfoc("Accumulated tips removed: {}; time elapsed: {.4}\n", number_tips, timer.elapsed()); return number_tips; } diff --git a/src/assembly/unitig_graph.cpp b/src/assembly/unitig_graph.cpp index 0761fb3..1660d45 100644 --- a/src/assembly/unitig_graph.cpp +++ b/src/assembly/unitig_graph.cpp @@ -75,7 +75,7 @@ UnitigGraph::UnitigGraph(SDBG *sdbg) : sdbg_(sdbg), adapter_impl_(this), sudo_ad } } } - xinfo("Graph size without loops: %lu, palindrome: %lu\n", vertices_.size(), count_palindrome); + xinfo("Graph size without loops: {}, palindrome: {}\n", vertices_.size(), count_palindrome); // assemble looped paths std::mutex loop_lock; @@ -114,9 +114,9 @@ UnitigGraph::UnitigGraph(SDBG *sdbg) : sdbg_(sdbg), adapter_impl_(this), sudo_ad if (vertices_.size() >= kMaxNumVertices) { xfatal( - "Too many vertices in the unitig graph (%llu >= %llu), " + "Too many vertices in the unitig graph ({} >= {}), " "you may increase the kmer size to remove tons of erroneous kmers.\n", - static_cast(vertices_.size()), static_cast(kMaxNumVertices)); + vertices_.size(), kMaxNumVertices); } sdbg_->FreeMultiplicity(); @@ -355,7 +355,7 @@ std::string UnitigGraph::VertexToDNAString(VertexAdapter v) { cur_edge = sdbg_->PrevSimplePathEdge(cur_edge); if (cur_edge == SDBG::kNullID) { - xfatal("%lld, %lld, %lld, %lld, (%lld, %lld), %d, %d\n", v.b(), v.e(), v.rb(), v.re(), + xfatal("{}, {}, {}, {}, ({}, {}), {}, {}\n", v.b(), v.e(), v.rb(), v.re(), sdbg_->EdgeReverseComplement(v.e()), sdbg_->EdgeReverseComplement(v.b()), v.GetLength(), i); } } @@ -364,7 +364,7 @@ std::string UnitigGraph::VertexToDNAString(VertexAdapter v) { label.push_back("ACGT"[cur_char > 4 ? (cur_char - 5) : (cur_char - 1)]); if (cur_edge != v.b()) { - xfatal("fwd: %lld, %lld, rev: %lld, %lld, (%lld, %lld) length: %d\n", v.b(), v.e(), v.rb(), v.re(), + xfatal("fwd: {}, {}, rev: {}, {}, ({}, {}) length: {}\n", v.b(), v.e(), v.rb(), v.re(), sdbg_->EdgeReverseComplement(v.e()), sdbg_->EdgeReverseComplement(v.b()), v.GetLength()); } diff --git a/src/localasm/local_assembler.cpp b/src/localasm/local_assembler.cpp index 2c1b72d..bde690d 100644 --- a/src/localasm/local_assembler.cpp +++ b/src/localasm/local_assembler.cpp @@ -65,7 +65,7 @@ void LocalAssembler::BuildHashMapper(bool show_stat) { } if (show_stat) { - xinfo("Number of contigs: %lu, Mapper size: %lu\n", contigs_.SeqCount(), mapper_.size()); + xinfo("Number of contigs: {}, Mapper size: {}\n", contigs_.SeqCount(), mapper_.size()); } } @@ -292,7 +292,7 @@ void LocalAssembler::EstimateInsertSize(bool show_stat) { insert_sizes_[lib_id] = tlen_t(insert_hist.mean(), insert_hist.sd()); if (show_stat) { - xinfo("Lib %d, insert size: %.2lf sd: %.2lf\n", lib_id, insert_hist.mean(), insert_hist.sd()); + xinfo("Lib {}, insert size: {.2} sd: {.2}\n", lib_id, insert_hist.mean(), insert_hist.sd()); } } } @@ -410,7 +410,7 @@ void LocalAssembler::MapToContigs() { } } - xinfo("Lib %d: total %ld reads, aligned %lu, added %lu reads for local assembly\n", lib_id, + xinfo("Lib {}: total {} reads, aligned {}, added {} reads for local assembly\n", lib_id, lib_info_[lib_id].to - lib_info_[lib_id].from + 1, num_mapped, num_added); } locks_.reset(0); @@ -537,8 +537,7 @@ void LocalAssembler::LocalAssemble() { for (uint64_t j = 0; j < out_contigs.size(); ++j) { if (out_contigs[j].size() > min_contig_len_ && out_contigs[j].size() > local_kmax_) { auto str = out_contigs[j].str(); - fprintf(local_file, ">lc_%llu_strand_%d_id_%llu flag=0 multi=1\n%s\n", static_cast(cid), - strand, static_cast(j), str.c_str()); + pfprintf(local_file, ">lc_{}_strand_{}_id_{} flag=0 multi=1\n{s}\n", cid, strand, j, str.c_str()); num_contigs++; num_bases += out_contigs[j].size(); } @@ -546,7 +545,7 @@ void LocalAssembler::LocalAssemble() { } } - fprintf(local_info, "%lld %lld\n", num_contigs, num_bases); + pfprintf(local_info, "{} {}\n", num_contigs, num_bases); fclose(local_file); fclose(local_info); diff --git a/src/main.cpp b/src/main.cpp index 7e849e2..a111771 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,6 +23,7 @@ #include #include "definitions.h" +#include "utils/utils.h" #include "utils/cpu_dispatch.h" int main_assemble(int argc, char **argv); @@ -41,8 +42,8 @@ int main_filter_by_len(int argc, char **argv); int main_extract_pe(int argc, char **argv); void show_help(const char *program_name) { - fprintf(stderr, - "Usage: %s [sub options]\n" + pfprintf(stderr, + "Usage: {s} [sub options]\n" " sub-programs:\n" " assemble assemble from SdBG\n" " local local asssembly\n" @@ -57,7 +58,7 @@ void show_help(const char *program_name) { " trim trim low quality tail of fastq reads\n" " filterbylen filter contigs by length\n" " extractpe extract pe reads and se reads from fasta/fastq files\n" - " checkcpu check whether the run-time CPU supports POPCNT and BMI2" + " checkcpu check whether the run-time CPU supports POPCNT and BMI2\n" " dumpversion dump version\n" " kmax the largest k value supported\n", program_name); @@ -94,11 +95,11 @@ int main(int argc, char **argv) { } else if (strcmp(argv[1], "extractpe") == 0) { return main_extract_pe(argc - 1, argv + 1); } else if (strcmp(argv[1], "checkcpu") == 0) { - printf("%d\n", HasPopcnt() && HasBmi2()); + pprintf("{}\n", HasPopcnt() && HasBmi2()); } else if (strcmp(argv[1], "dumpversion") == 0) { - printf("%s\n", PACKAGE_VERSION); + pprintf("{s}\n", PACKAGE_VERSION); } else if (strcmp(argv[1], "kmax") == 0) { - printf("%d\n", kMaxK); + pprintf("{}\n", kMaxK); } else { show_help(argv[0]); return 1; diff --git a/src/main_assemble.cpp b/src/main_assemble.cpp index 569c21a..c6cb961 100644 --- a/src/main_assemble.cpp +++ b/src/main_assemble.cpp @@ -107,18 +107,18 @@ int main_assemble(int argc, char **argv) { // graph loading timer.reset(); timer.start(); - xinfo("Loading succinct de Bruijn graph: %s ", opt.sdbg_name.c_str()); + xinfo("Loading succinct de Bruijn graph: {} ", opt.sdbg_name.c_str()); dbg.LoadFromFile(opt.sdbg_name.c_str()); timer.stop(); - xinfoc("Done. Time elapsed: %lf\n", timer.elapsed()); - xinfo("Number of Edges: %lld; K value: %d\n", (long long)dbg.size(), dbg.k()); + xinfoc("Done. Time elapsed: {}\n", timer.elapsed()); + xinfo("Number of Edges: {}; K value: {}\n", dbg.size(), dbg.k()); // set cpu threads if (opt.num_cpu_threads == 0) { opt.num_cpu_threads = omp_get_max_threads(); } omp_set_num_threads(opt.num_cpu_threads); - xinfo("Number of CPU threads: %d\n", opt.num_cpu_threads); + xinfo("Number of CPU threads: {}\n", opt.num_cpu_threads); // set tip len if (opt.max_tip_len == -1) { @@ -127,7 +127,7 @@ int main_assemble(int argc, char **argv) { // set min depth if (opt.min_depth <= 0) { opt.min_depth = sdbg_pruning::InferMinDepth(dbg); - xinfo("min depth set to %.3lf\n", opt.min_depth); + xinfo("min depth set to {.3}\n", opt.min_depth); } // tips removal before building unitig graph @@ -136,7 +136,7 @@ int main_assemble(int argc, char **argv) { timer.start(); sdbg_pruning::RemoveTips(dbg, opt.max_tip_len); timer.stop(); - xinfo("Tips removal done! Time elapsed(sec): %lf\n", timer.elapsed()); + xinfo("Tips removal done! Time elapsed(sec): {.3}\n", timer.elapsed()); } // construct unitig graph @@ -144,7 +144,7 @@ int main_assemble(int argc, char **argv) { timer.start(); UnitigGraph graph(&dbg); timer.stop(); - xinfo("unitig graph size: %u, time for building: %lf\n", graph.size(), timer.elapsed()); + xinfo("unitig graph size: {}, time for building: {.3}\n", graph.size(), timer.elapsed()); CalcAndPrintStat(graph); // set up bubble @@ -167,7 +167,7 @@ int main_assemble(int argc, char **argv) { uint32_t num_tips = RemoveTips(graph, opt.max_tip_len); changed |= num_tips > 0; timer.stop(); - xinfo("Tips removed: %u, time: %lf\n", num_tips, timer.elapsed()); + xinfo("Tips removed: {}, time: {.3}\n", num_tips, timer.elapsed()); } // remove bubbles if (opt.bubble_level >= 1) { @@ -175,7 +175,7 @@ int main_assemble(int argc, char **argv) { timer.start(); uint32_t num_bubbles = naiver_bubble_remover.PopBubbles(graph, true); timer.stop(); - xinfo("Number of bubbles removed: %u, Time elapsed(sec): %lf\n", num_bubbles, timer.elapsed()); + xinfo("Number of bubbles removed: {}, Time elapsed(sec): {.3}\n", num_bubbles, timer.elapsed()); changed |= num_bubbles > 0; } // remove complex bubbles @@ -184,7 +184,7 @@ int main_assemble(int argc, char **argv) { timer.start(); uint32_t num_bubbles = complex_bubble_remover.PopBubbles(graph, true); timer.stop(); - xinfo("Number of complex bubbles removed: %u, Time elapsed(sec): %lf\n", num_bubbles, timer.elapsed()); + xinfo("Number of complex bubbles removed: {}, Time elapsed(sec): {}\n", num_bubbles, timer.elapsed()); changed |= num_bubbles > 0; } @@ -193,7 +193,7 @@ int main_assemble(int argc, char **argv) { timer.start(); uint32_t num_disconnected = DisconnectWeakLinks(graph, 0.1); timer.stop(); - xinfo("Number unitigs disconnected: %u, time: %lf\n", num_disconnected, timer.elapsed()); + xinfo("Number unitigs disconnected: {}, time: {.3}\n", num_disconnected, timer.elapsed()); changed |= num_disconnected > 0; // excessive pruning @@ -207,14 +207,14 @@ int main_assemble(int argc, char **argv) { num_excessive_pruned += complex_bubble_remover.PopBubbles(graph, true); } timer.stop(); - xinfo("Unitigs removed in (more-)excessive pruning: %llu, time: %lf\n", num_excessive_pruned, timer.elapsed()); + xinfo("Unitigs removed in (more-)excessive pruning: {}, time: {.3}\n", num_excessive_pruned, timer.elapsed()); } else if (opt.prune_level >= 2) { timer.reset(); timer.start(); RemoveLocalLowDepth(graph, opt.min_depth, opt.max_tip_len, opt.local_width, std::min(opt.low_local_ratio, 0.1), true, &num_excessive_pruned); timer.stop(); - xinfo("Unitigs removed in excessive pruning: %llu, time: %lf\n", num_excessive_pruned, timer.elapsed()); + xinfo("Unitigs removed in excessive pruning: {}, time: {.3}\n", num_excessive_pruned, timer.elapsed()); } if (!changed) break; } @@ -229,12 +229,12 @@ int main_assemble(int argc, char **argv) { timer.reset(); timer.start(); FILE *out_contig_info = xfopen((opt.contig_file() + ".info").c_str(), "w"); - fprintf(out_contig_info, "%lu %lu\n", graph.size() + bubble_hist.size(), stat["total size"] + bubble_hist.sum()); + pfprintf(out_contig_info, "{} {}\n", graph.size() + bubble_hist.size(), stat["total size"] + bubble_hist.sum()); fclose(out_contig_info); OutputContigs(graph, contig_file, opt.output_standalone ? standalone_file : nullptr, false, opt.min_standalone); timer.stop(); - xinfo("Time to output: %lf\n", timer.elapsed()); + xinfo("Time to output: {}\n", timer.elapsed()); } // remove local low depth & output as contigs @@ -253,7 +253,7 @@ int main_assemble(int argc, char **argv) { n_bubbles = complex_bubble_remover.PopBubbles(graph, false); timer.stop(); } - xinfo("Number of local low depth unitigs removed: %lu, complex bubbles removed: %u, time: %lf\n", num_removed, + xinfo("Number of local low depth unitigs removed: {}, complex bubbles removed: {}, time: {}\n", num_removed, n_bubbles, timer.elapsed()); CalcAndPrintStat(graph); @@ -264,7 +264,7 @@ int main_assemble(int argc, char **argv) { } auto stat_changed = CalcAndPrintStat(graph, false, true); - fprintf(add_contig_info, "%lu %lu\n", stat_changed["number contigs"], stat_changed["total size"]); + pfprintf(add_contig_info, "{} {}\n", stat_changed["number contigs"], stat_changed["total size"]); fclose(add_contig_file); fclose(add_contig_info); diff --git a/src/main_buildlib.cpp b/src/main_buildlib.cpp index 64c9ca6..2dfd20e 100644 --- a/src/main_buildlib.cpp +++ b/src/main_buildlib.cpp @@ -1,7 +1,7 @@ #include "sequence/lib_io.h" #include "utils/utils.h" -void DisplayHelp(const char *program) { fprintf(stderr, "Usage %s \n", program); } +void DisplayHelp(const char *program) { pfprintf(stderr, "Usage {s} \n", program); } int main_build_lib(int argc, char **argv) { AutoMaxRssRecorder recorder; diff --git a/src/main_iterate.cpp b/src/main_iterate.cpp index 30e8fce..73ad379 100644 --- a/src/main_iterate.cpp +++ b/src/main_iterate.cpp @@ -108,7 +108,7 @@ static bool ReadReadsAndProcessKernel(const Option &opt, const IndexType &index) if (KmerType::max_size() < static_cast(opt.kmer_k + opt.step + 1)) { return false; } - xinfo("Selected kmer type size for next k: %u\n", sizeof(KmerType)); + xinfo("Selected kmer type size for next k: {}\n", sizeof(KmerType)); AsyncReadReader reader(opt.read_file); KmerCollector collector(opt.kmer_k + opt.step + 1, opt.output_prefix); int64_t num_aligned_reads = 0; @@ -121,11 +121,11 @@ static bool ReadReadsAndProcessKernel(const Option &opt, const IndexType &index) } num_aligned_reads += index.FindNextKmersFromReads(read_pkg, &collector); num_total_reads += read_pkg.SeqCount(); - xinfo("Processed: %lld, aligned: %lld. Iterative edges: %llu\n", num_total_reads, num_aligned_reads, + xinfo("Processed: {}, aligned: {}. Iterative edges: {}\n", num_total_reads, num_aligned_reads, collector.collection().size()); } collector.FlushToFile(); - xinfo("Total: %lld, aligned: %lld. Iterative edges: %llu\n", num_total_reads, num_aligned_reads, + xinfo("Total: {}, aligned: {}. Iterative edges: {}\n", num_total_reads, num_aligned_reads, collector.collection().size()); return true; } @@ -153,16 +153,16 @@ static void ReadContigsAndBuildIndex(const Option &opt, const std::string &file_ if (contig_pkg.SeqCount() == 0) { break; } - xinfo("Read %lu contigs\n", contig_pkg.SeqCount()); + xinfo("Read {} contigs\n", contig_pkg.SeqCount()); index->FeedBatchContigs(contig_pkg, mul); - xinfo("Number of flank kmers: %lu\n", index->size()); + xinfo("Number of flank kmers: {}\n", index->size()); } } template bool KmerTypeSelectAndRun(const Option &opt) { if (KmerType::max_size() >= static_cast(opt.kmer_k + 1)) { - xinfo("Selected kmer type size for k: %u\n", sizeof(KmerType)); + xinfo("Selected kmer type size for k: {}\n", sizeof(KmerType)); ContigFlankIndex index(opt.kmer_k, opt.step); ReadContigsAndBuildIndex(opt, opt.contig_file, &index); ReadContigsAndBuildIndex(opt, opt.bubble_file, &index); diff --git a/src/main_local_assemble.cpp b/src/main_local_assemble.cpp index d49fdbe..9a1c33f 100644 --- a/src/main_local_assemble.cpp +++ b/src/main_local_assemble.cpp @@ -103,30 +103,30 @@ int main_local(int argc, char **argv) { la.ReadContigs(opt.contig_file); la.BuildHashMapper(); timer.stop(); - xinfo("Hash mapper construction time elapsed: %f\n", timer.elapsed()); + xinfo("Hash mapper construction time elapsed: {}\n", timer.elapsed()); timer.reset(); timer.start(); la.AddReadLib(opt.lib_file_prefix); timer.stop(); - xinfo("Read lib time elapsed: %f\n", timer.elapsed()); + xinfo("Read lib time elapsed: {}\n", timer.elapsed()); timer.reset(); timer.start(); la.EstimateInsertSize(); timer.stop(); - xinfo("Insert size estimation time elapsed: %f\n", timer.elapsed()); + xinfo("Insert size estimation time elapsed: {}\n", timer.elapsed()); timer.reset(); timer.start(); la.MapToContigs(); timer.stop(); - xinfo("Mapping time elapsed: %f\n", timer.elapsed()); + xinfo("Mapping time elapsed: {}\n", timer.elapsed()); timer.reset(); timer.start(); la.LocalAssemble(); timer.stop(); - xinfo("Local assembly time elapsed: %f\n", timer.elapsed()); + xinfo("Local assembly time elapsed: {}\n", timer.elapsed()); return 0; } \ No newline at end of file diff --git a/src/main_sdbg_build.cpp b/src/main_sdbg_build.cpp index 19d3309..2fc4735 100644 --- a/src/main_sdbg_build.cpp +++ b/src/main_sdbg_build.cpp @@ -72,9 +72,6 @@ int main_kmer_count(int argc, char **argv) { exit(1); } - xinfo("Host memory to be used: %lld\n", (long long) opt.host_mem); - xinfo("Number CPU threads: %d\n", opt.n_threads); - KmerCounter runner(opt); runner.Run(); @@ -189,16 +186,13 @@ int main_seq2sdbg(int argc, char **argv) { } catch (std::exception &e) { std::cerr << e.what() << std::endl; std::cerr << "Usage: sdbg_builder seq2sdbg -k kmer_size --contig contigs.fa [--addi_contig " - "add.fa] [--input_prefix " - "input] -o out" + "add.fa] [--input_prefix input] -o out" << std::endl; std::cerr << "Options:" << std::endl; std::cerr << desc << std::endl; exit(1); } - xinfo("Host memory to be used: %lld\n", (long long) opt.host_mem); - xinfo("Number CPU threads: %d\n", opt.n_threads); SeqToSdbg runner(opt); runner.Run(); return 0; diff --git a/src/pprintpp/charlist.hpp b/src/pprintpp/charlist.hpp new file mode 100644 index 0000000..a080751 --- /dev/null +++ b/src/pprintpp/charlist.hpp @@ -0,0 +1,93 @@ +/* + * MIT License + * + * Copyright (c) 2016 Jacek Galowicz + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#pragma once + + +#include "typelist.hpp" + +namespace charlist { + +using namespace typelist; + +template struct char_t { static const constexpr char value {val}; }; + +template +struct char_tl; + +template +struct char_tl { + using type = typelist::tl, typename char_tl::type>; +}; +template +struct char_tl { + using type = typelist::tl, typelist::null_t>; +}; + +template +using char_tl_t = typename char_tl::type; + +template +struct string_list; + +template +struct string_list { + using next_piece = typename string_list< + Str, + Pos + 1, + Str::str()[Pos + 1] + >::type; + using type = typelist::tl, next_piece>; +}; + +template +struct string_list { + using type = typelist::null_t; +}; + +template +using string_list_t = typename string_list::type; + +template +struct tl_to_varlist; + +template +struct tl_to_varlist, restlist>, chars...> + : public tl_to_varlist +{ }; + +template <> +struct tl_to_varlist { + static const char * const str() { return ""; } +}; +template +struct tl_to_varlist { + using list = char_tl; + + static const char * const str() { + static constexpr const char string[] = {chars..., '\0'}; + return string; + } +}; + +} diff --git a/src/pprintpp/pprintpp.hpp b/src/pprintpp/pprintpp.hpp new file mode 100644 index 0000000..072ca07 --- /dev/null +++ b/src/pprintpp/pprintpp.hpp @@ -0,0 +1,180 @@ +/* + * MIT License + * + * Copyright (c) 2016 Jacek Galowicz + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#pragma once + +#include "stl_symbols.hpp" +#include "charlist.hpp" + +namespace pprintpp { + +template struct always_false { static constexpr bool value {false}; }; + +using namespace typelist; +using namespace charlist; + +template struct type2fmt; + +template <> struct type2fmt { using type = char_tl_t<'c'>; }; +template <> struct type2fmt { using type = char_tl_t<'d'>; }; +template <> struct type2fmt { using type = char_tl_t<'d'>; }; +template <> struct type2fmt { using type = char_tl_t<'l', 'd'>; }; +template <> struct type2fmt { using type = char_tl_t<'l', 'l', 'd'>; }; +template <> struct type2fmt { using type = char_tl_t<'u'>; }; +template <> struct type2fmt { using type = char_tl_t<'u'>; }; +template <> struct type2fmt { using type = char_tl_t<'u'>; }; +template <> struct type2fmt { using type = char_tl_t<'l', 'u'>; }; +template <> struct type2fmt { using type = char_tl_t<'l', 'l', 'u'>; }; + +template <> struct type2fmt { using type = char_tl_t<'d'>; }; + +template <> struct type2fmt { using type = char_tl_t<'f'>; }; +template <> struct type2fmt { using type = char_tl_t<'l', 'f'>; }; + +template <> struct type2fmt { using type = char_tl_t<'p'>; }; +template struct type2fmt { using type = char_tl_t<'p'>; }; + +template +struct format_str { + using raw_T = remove_cv_t; + static constexpr bool s_fmt {contains>::value}; + static constexpr bool is_str {is_same::type>>::value}; + + static constexpr bool is_int {is_int_type::value}; + static constexpr bool has_x {contains>::value}; + + using raw_fmt = typename type2fmt::type; + + using uint_x_fmt = typename conditional, char_t<'x'>>, + char_t<'u'>, char_t<'x'>>, + raw_fmt + >::type; + + using fmt_type = typename conditional, char_t<'s'>>, + uint_x_fmt + >::type; + + using filtered_fl = remove_t>, char_t<'s'>>; + + using type = append_t; +}; + +template +struct find_brace; + +template +struct find_brace, InList>, OutList, 1> { + using before = OutList; + using after = InList; +}; + +template +struct find_brace, InList>, OutList, N> + : public find_brace>, N> +{ + static_assert(C != '{', "Found nested braces: {...{...}...}!" + " Maybe you want to mask the outer one?"); +}; + +template +struct find_brace +{ + static_assert(N + 1 == N, "Missing } after {."); +}; + +template +struct autoformat; + +template <> +struct autoformat { using type = null_t; }; + +template +struct autoformat { + using type = null_t; + static_assert(always_false::value, "There are more vars than format tokens!"); +}; + +template +struct autoformat, tl, SL>>, TL> +{ + using type = tl, tl, typename autoformat::type>>; +}; + +template +struct autoformat, SL>, tl> +{ + using type = tl, typename autoformat::type>; +}; + +template +struct autoformat, tl, SL>>, TL> +{ + using type = tl, typename autoformat::type>; +}; + +template +struct autoformat, SL>, TL> +{ + using other_brace = find_brace; + using format_block = typename other_brace::before; + using rest_str = typename other_brace::after; + + static_assert(!is_same::value, "There are more {} than arguments to print"); + using T = typename TL::head; + using fmt_str = typename format_str::type; + + using type = tl, + append_t::type>>; +}; + +template +struct autoformat, TL> { + using type = tl::type>; +}; + + +template +using autoformat_t = + tl_to_varlist< + typename autoformat, PtList>::type + >; + +template +make_t tie_types(Ts...); + +#define AUTOFORMAT(s, ...) \ + ({ \ + struct strprov { static constexpr const char * const str() { return s; } }; \ + using paramtypes = decltype(pprintpp::tie_types(__VA_ARGS__)); \ + using af = pprintpp::autoformat_t; \ + af::str(); \ + }) + +#define pprintf(s, ...) printf(AUTOFORMAT(s, ## __VA_ARGS__), ## __VA_ARGS__) +#define pfprintf(f, s, ...) fprintf(f, AUTOFORMAT(s, ## __VA_ARGS__), ## __VA_ARGS__) +#define psprintf(str, s, ...) sprintf(str, AUTOFORMAT(s, ## __VA_ARGS__), ## __VA_ARGS__) +} diff --git a/src/pprintpp/stl_symbols.hpp b/src/pprintpp/stl_symbols.hpp new file mode 100644 index 0000000..392c9e8 --- /dev/null +++ b/src/pprintpp/stl_symbols.hpp @@ -0,0 +1,105 @@ +/* + * MIT License + * + * Copyright (c) 2017 Jacek Galowicz + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#pragma once + +#ifdef PPRINTPP_AVOID_STL +#include +#else +#include +#include +#endif + + +#ifndef PPRINTPP_AVOID_STL +#endif +#include "typelist.hpp" + +namespace pprintpp { + + +#ifndef PPRINTPP_AVOID_STL + +using nullptr_t = std::nullptr_t; + +template +using remove_cv_t = typename std::remove_cv::type; + +template +using is_same = std::is_same; + +template +using conditional = std::conditional; + +template +using remove_ptr = std::remove_pointer; + +template +using is_int_type = std::is_integral; + +#else + +using nullptr_t = decltype(nullptr); + +template +struct remove_c { using type = T; }; +template +struct remove_c { using type = T; }; + +template +struct remove_v { using type = T; }; +template +struct remove_v { using type = T; }; + +template +using remove_cv_t = typename remove_v< + typename remove_c::type + >::type; + +template +struct is_same { static constexpr bool value {false}; }; + +template +struct is_same { static constexpr bool value {true}; }; + +template +struct conditional { using type = A; }; + +template +struct conditional { using type = B; }; + +template +struct remove_ptr { using type = T; }; + +template +struct remove_ptr { using type = T; }; + +template +struct is_int_type { + using ints = typelist::make_t; + static constexpr bool value {typelist::contains::value}; +}; + +#endif + +} diff --git a/src/pprintpp/typelist.hpp b/src/pprintpp/typelist.hpp new file mode 100644 index 0000000..5900dd5 --- /dev/null +++ b/src/pprintpp/typelist.hpp @@ -0,0 +1,111 @@ +/* + * MIT License + * + * Copyright (c) 2016 Jacek Galowicz + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#pragma once + +namespace typelist { + +struct null_t { + using head = null_t; + using tail = null_t; +}; + +template +struct tl +{ + using head = T; + using tail = U; +}; + +template +using head_t = typename TList::head; + +template +using tail_t = typename TList::tail; + + +template struct make; + +template +struct make { using type = tl::type>; }; +template <> +struct make<> { using type = null_t; }; + +template +using make_t = typename make::type; + + +template +struct append; +template <> +struct append { using type = null_t; }; +template +struct append { using type = make_t; }; +template +struct append> { using type = tl; }; +template +struct append, T> +{ using type = tl::type>; }; + +template +using append_t = typename append::type; + +template +struct contains; + +template +struct contains { static constexpr bool value {false}; }; +template +struct contains, T> { static constexpr bool value {true}; }; +template +struct contains, T> : contains {}; + + +template +struct remove; + +template +struct remove { using type = null_t; }; +template +struct remove, T> { using type = typename remove::type; }; +template +struct remove, T> { using type = tl::type>; }; + +template +using remove_t = typename remove::type; + + +template +struct substitute; + +template +struct substitute { using type = null_t; }; +template +struct substitute, T, TS> { using type = tl::type>; }; +template +struct substitute, T, TS> { using type = tl::type>; }; + +template +using substitute_t = typename substitute::type; + +} // namespace tl diff --git a/src/sequence/lib_io.h b/src/sequence/lib_io.h index 240167f..357d882 100644 --- a/src/sequence/lib_io.h +++ b/src/sequence/lib_io.h @@ -59,7 +59,7 @@ inline void ReadAndWriteMultipleLibs(const std::string &lib_file, const std::str std::ifstream lib_config(lib_file); if (!lib_config.is_open()) { - xfatal("File to open read_lib file: %s\n", lib_file.c_str()); + xfatal("File to open read_lib file: {}\n", lib_file.c_str()); } FILE *bin_file = xfopen((out_prefix + ".bin").c_str(), "wb"); @@ -90,7 +90,7 @@ inline void ReadAndWriteMultipleLibs(const std::string &lib_file, const std::str lib_config >> file_name1; reader.reset(new FastxReader(file_name1)); } else { - xerr("Cannot identify read library type %s\n", type.c_str()); + xerr("Cannot identify read library type {}\n", type.c_str()); xfatal("Valid types: pe, se, interleaved\n"); } @@ -115,16 +115,16 @@ inline void ReadAndWriteMultipleLibs(const std::string &lib_file, const std::str } if (type == "pe" && (total_reads - start) % 2 != 0) { - xerr("PE library number of reads is odd: %lld!\n", total_reads - start); - xfatal("File(s): %s\n", metadata.c_str()); + xerr("PE library number of reads is odd: {}!\n", total_reads - start); + xfatal("File(s): {}\n", metadata.c_str()); } if (type == "interleaved" && (total_reads - start) % 2 != 0) { - xerr("PE library number of reads is odd: %lld!\n", total_reads - start); - xfatal("File(s): %s\n", metadata.c_str()); + xerr("PE library number of reads is odd: {}!\n", total_reads - start); + xfatal("File(s): {}\n", metadata.c_str()); } - xinfo("Lib %d (%s): %s, %lld reads, %d max length\n", lib_info.size(), metadata.c_str(), type.c_str(), + xinfo("Lib {} ({}): {}, {} reads, {} max length\n", lib_info.size(), metadata.c_str(), type.c_str(), total_reads - start, max_read_len); lib_info.emplace_back(&seq_batch, start, total_reads - 1, max_read_len, type != "se", metadata); @@ -132,11 +132,11 @@ inline void ReadAndWriteMultipleLibs(const std::string &lib_file, const std::str } FILE *lib_info_file = xfopen((out_prefix + ".lib_info").c_str(), "w"); - fprintf(lib_info_file, "%zu %zu\n", total_bases, total_reads); + pfprintf(lib_info_file, "{} {}\n", total_bases, total_reads); - for (auto &i : lib_info) { - fprintf(lib_info_file, "%s\n", i.metadata.c_str()); - fprintf(lib_info_file, "%" PRId64 " %" PRId64 " %d %s\n", i.from, i.to, i.max_read_len, i.is_pe ? "pe" : "se"); + for (auto &lib : lib_info) { + pfprintf(lib_info_file, "{}\n", lib.metadata.c_str()); + pfprintf(lib_info_file, "{} {} {} {}\n", lib.from, lib.to, lib.max_read_len, lib.is_pe ? "pe" : "se"); } fclose(lib_info_file); @@ -164,16 +164,16 @@ inline void ReadBinaryLibs(const std::string &file_prefix, SeqPackage &package, std::getline(lib_info_file, metadata); // eliminate the "\n" } - xinfo("Before reserve for %lu reads, %lu bases, sizeof seq_package: %lu\n", num_reads, total_bases, + xinfo("Before reserve for {} reads, {} bases, sizeof seq_package: {}\n", num_reads, total_bases, package.SizeInByte()); package.ReserveSequences(num_reads); package.ReserveBases(total_bases); BinaryReader reader(file_prefix + ".bin"); - xinfo("Before reading, sizeof seq_package: %lld\n", package.SizeInByte()); + xinfo("Before reading, sizeof seq_package: {}\n", package.SizeInByte()); package.Clear(); reader.ReadAll(&package, is_reverse); - xinfo("After reading, sizeof seq_package: %lld\n", package.SizeInByte()); + xinfo("After reading, sizeof seq_package: {}\n", package.SizeInByte()); } #endif \ No newline at end of file diff --git a/src/sequence/readers/edge_io.h b/src/sequence/readers/edge_io.h index 324869b..500d64b 100644 --- a/src/sequence/readers/edge_io.h +++ b/src/sequence/readers/edge_io.h @@ -211,7 +211,7 @@ class MegahitEdgeReader { xfatal("Invalid format: bucket id not matched!\n"); } if (p_rec_[i].thread_id >= num_files_) { - xfatal("Record ID %d is greater than number of files %d\n", p_rec_[i].thread_id, num_files_); + xfatal("Record ID {} is greater than number of files {}\n", p_rec_[i].thread_id, num_files_); } if (p_rec_[i].thread_id >= 0) { file_sizes_[p_rec_[i].thread_id] += p_rec_[i].total_number; diff --git a/src/sorting/base_engine.cpp b/src/sorting/base_engine.cpp index a9abeab..8e69587 100644 --- a/src/sorting/base_engine.cpp +++ b/src/sorting/base_engine.cpp @@ -20,8 +20,8 @@ static std::pair AdjustItemNumbers( while (num_lv2_items >= min_lv2_items) { int64_t mem_for_lv2 = bytes_per_lv2_item * num_lv2_items; - xinfo("Adjusting memory layout: num_lv1_items=%lld, num_lv2_items=%lld, " - "mem_sorting_items=%lld, mem_avail=%lld\n", + xinfo("Adjusting memory layout: num_lv1_items={}, num_lv2_items={}, " + "mem_sorting_items={}, mem_avail={}\n", num_lv1_items, num_lv2_items, mem_for_lv2, mem_avail); if (mem_avail < mem_for_lv2) { @@ -118,8 +118,8 @@ void BaseSequenceSortingEngine::AdjustMemory() { lv1_offsets_.resize(words_required); substr_sort_ = SelectSortingFunc(meta_.words_per_lv2 - meta_.aux_words_per_lv2, meta_.aux_words_per_lv2); - xinfo("Lv1 items: %lld, Lv2 items: %lld\n", n_items.first, n_items.second); - xinfo("Memory of derived class: %lld, Memory for Lv1+Lv2: %lld\n", + xinfo("Lv1 items: {}, Lv2 items: {}\n", n_items.first, n_items.second); + xinfo("Memory of derived class: {}, Memory for Lv1+Lv2: {}\n", meta_.memory_for_data, words_required * kLv1BytePerItem); } @@ -133,7 +133,7 @@ void BaseSequenceSortingEngine::Run() { meta_ = Initialize(); lv0_timer.stop(); - xinfo("Preparing data... Done. Time elapsed: %.4f\n", lv0_timer.elapsed()); + xinfo("Preparing data... Done. Time elapsed: {.4}\n", lv0_timer.elapsed()); lv0_timer.reset(); lv0_timer.start(); xinfo("Preparing partitions and calculating bucket sizes...\n"); @@ -145,7 +145,7 @@ void BaseSequenceSortingEngine::Run() { Lv0ReorderBuckets(); AdjustMemory(); lv0_timer.stop(); - xinfo("Preparing partitions and calculating bucket sizes... Done. Time elapsed: %.4f\n", lv0_timer.elapsed()); + xinfo("Preparing partitions and calculating bucket sizes... Done. Time elapsed: {.4}\n", lv0_timer.elapsed()); lv0_timer.reset(); lv0_timer.start(); @@ -162,31 +162,31 @@ void BaseSequenceSortingEngine::Run() { lv1_timer.reset(); lv1_timer.start(); - xinfo("Lv1 scanning from bucket %d to %d\n", lv1_start_bucket_, lv1_end_bucket_); + xinfo("Lv1 scanning from bucket {} to {}\n", lv1_start_bucket_, lv1_end_bucket_); // --- scan to fill offset --- Lv1FillOffsetsLaunchMt(); lv1_timer.stop(); - xinfo("Lv1 scanning done. Large diff: %lu. Time elapsed: %.4f\n", + xinfo("Lv1 scanning done. Large diff: {}. Time elapsed: {.4}\n", lv1_special_offsets_.size(), lv1_timer.elapsed()); lv1_timer.reset(); lv1_timer.start(); Lv1FetchAndSortLaunchMt(); lv1_timer.stop(); - xinfo("Lv1 fetching & sorting done. Time elapsed: %.4f\n", lv1_timer.elapsed()); + xinfo("Lv1 fetching & sorting done. Time elapsed: {.4}\n", lv1_timer.elapsed()); lv1_start_bucket_ = lv1_end_bucket_; } lv0_timer.stop(); - xinfo("Main loop done. Time elapsed: %.4f\n", lv0_timer.elapsed()); + xinfo("Main loop done. Time elapsed: {.4}\n", lv0_timer.elapsed()); lv0_timer.reset(); lv0_timer.start(); xinfo("Postprocessing...\n"); Lv0Postprocess(); lv0_timer.stop(); - xinfo("Postprocess done. Time elapsed: %.4f\n", lv0_timer.elapsed()); + xinfo("Postprocess done. Time elapsed: {.4}\n", lv0_timer.elapsed()); } void BaseSequenceSortingEngine::Lv0PrepareThreadPartition() { diff --git a/src/sorting/kmer_counter.cpp b/src/sorting/kmer_counter.cpp index a919f69..8191f99 100644 --- a/src/sorting/kmer_counter.cpp +++ b/src/sorting/kmer_counter.cpp @@ -73,11 +73,11 @@ KmerCounter::Meta KmerCounter::Initialize() { seq_pkg_.BuildIndex(); num_reads = seq_pkg_.SeqCount(); - xinfo("%ld reads, %d max read length\n", num_reads, seq_pkg_.MaxSequenceLength()); + xinfo("{} reads, {} max read length\n", num_reads, seq_pkg_.MaxSequenceLength()); words_per_substr_ = DivCeiling((opt_.k + 1) * kBitsPerEdgeChar, kBitsPerEdgeWord); words_per_edge_ = DivCeiling((opt_.k + 1) * kBitsPerEdgeChar + kBitsPerMul, kBitsPerEdgeWord); - xinfo("%d words per substring, %d words per edge\n", words_per_substr_, words_per_edge_); + xinfo("{} words per substring, {} words per edge\n", words_per_substr_, words_per_edge_); // --- malloc read first_in / last_out --- first_0_out_ = std::vector>(seq_pkg_.SeqCount(), 0xFFFFFFFFU); @@ -382,7 +382,7 @@ void KmerCounter::Lv0Postprocess() { fclose(candidate_file); - xinfo("Total number of candidate reads: %lld(%lld)\n", num_candidate_reads, num_has_tips); + xinfo("Total number of candidate reads: {} ({})\n", num_candidate_reads, num_has_tips); // --- stat --- int64_t num_solid_edges = 0; @@ -390,13 +390,13 @@ void KmerCounter::Lv0Postprocess() { for (int i = opt_.solid_threshold; i <= kMaxMul; ++i) { num_solid_edges += edge_counting[i]; } - xinfo("Total number of solid edges: %llu\n", num_solid_edges); + xinfo("Total number of solid edges: {}\n", num_solid_edges); FILE *counting_file = xfopen((opt_.output_prefix + ".counting").c_str(), "w"); for (int64_t i = 1, acc = 0; i <= kMaxMul; ++i) { acc += edge_counting[i]; - fprintf(counting_file, "%lld %lld\n", (long long) i, (long long) acc); + pfprintf(counting_file, "{} {}\n", i, acc); } fclose(counting_file); diff --git a/src/sorting/read_to_sdbg_s1.cpp b/src/sorting/read_to_sdbg_s1.cpp index 86f9ceb..1aeeab8 100644 --- a/src/sorting/read_to_sdbg_s1.cpp +++ b/src/sorting/read_to_sdbg_s1.cpp @@ -97,13 +97,13 @@ Read2SdbgS1::Meta Read2SdbgS1::Initialize() { seq_pkg_->package.BuildIndex(); - xinfo("%lu reads, %d max read length, %lld total bases\n", seq_pkg_->package.SeqCount(), + xinfo("{} reads, {} max read length, {} total bases\n", seq_pkg_->package.SeqCount(), seq_pkg_->package.MaxSequenceLength(), seq_pkg_->package.BaseCount()); words_per_substr_ = DivCeiling((opt_.k - 1) * kBitsPerEdgeChar + 2 * kBWTCharNumBits, kBitsPerEdgeWord); - xinfo("%d words per substring\n", words_per_substr_); + xinfo("{} words per substring\n", words_per_substr_); if (opt_.solid_threshold > 1) { seq_pkg_->is_solid.reset(seq_pkg_->package.BaseCount()); @@ -117,7 +117,7 @@ Read2SdbgS1::Meta Read2SdbgS1::Initialize() { static_cast(seq_pkg_->package.SeqCount()) && seq_pkg_->n_mercy_files < 64) { seq_pkg_->n_mercy_files <<= 1; } - xinfo("Number of files for mercy candidate reads: %d\n", seq_pkg_->n_mercy_files); + xinfo("Number of files for mercy candidate reads: {}\n", seq_pkg_->n_mercy_files); for (int i = 0; i < seq_pkg_->n_mercy_files; ++i) { auto file_name = opt_.output_prefix + ".mercy_cand" + std::to_string(i); @@ -517,13 +517,13 @@ void Read2SdbgS1::Lv0Postprocess() { num_solid_edges += edge_counting[i]; } - xinfo("Total number of solid edges: %llu\n", num_solid_edges); + xinfo("Total number of solid edges: {}\n", num_solid_edges); FILE *counting_file = xfopen((std::string(opt_.output_prefix) + ".counting").c_str(), "w"); for (int64_t i = 1, acc = 0; i <= kMaxMul; ++i) { acc += edge_counting[i]; - fprintf(counting_file, "%lld %lld\n", (long long) i, (long long) acc); + pfprintf(counting_file, "{} {}\n", i, acc); } fclose(counting_file); diff --git a/src/sorting/read_to_sdbg_s2.cpp b/src/sorting/read_to_sdbg_s2.cpp index 9f03630..fe3f88a 100644 --- a/src/sorting/read_to_sdbg_s2.cpp +++ b/src/sorting/read_to_sdbg_s2.cpp @@ -92,7 +92,7 @@ Read2SdbgS2::Meta Read2SdbgS2::Initialize() { words_per_substr_ = DivCeiling(opt_.k * kBitsPerEdgeChar + kBWTCharNumBits + 1, kBitsPerEdgeWord); words_per_dummy_node_ = DivCeiling(opt_.k * kBitsPerEdgeChar, kBitsPerEdgeWord); - xinfo("%d words per substring, words per dummy node ($v): %d\n", words_per_substr_, + xinfo("{} words per substring, words per dummy node ($v): {}\n", words_per_substr_, words_per_dummy_node_); // --- init output --- @@ -139,7 +139,7 @@ Read2SdbgS2::Meta Read2SdbgS2::Initialize() { mercy_cand.insert(mercy_cand.end(), buf, buf + num_read); } - xinfo("Mercy file: %s, %lu\n", file_name.c_str(), mercy_cand.size()); + xinfo("Mercy file: {}, {}\n", file_name.c_str(), mercy_cand.size()); omp_set_num_threads(opt_.n_threads); __gnu_parallel::sort(mercy_cand.begin(), mercy_cand.end()); @@ -241,8 +241,8 @@ Read2SdbgS2::Meta Read2SdbgS2::Initialize() { } timer.stop(); - xinfo("Adding mercy Done. Time elapsed: %.4lf\n", timer.elapsed()); - xinfo("Number mercy: %llu\n", (unsigned long long) num_mercy); + xinfo("Adding mercy Done. Time elapsed: {.4}\n", timer.elapsed()); + xinfo("Number mercy: {}\n", num_mercy); return ret; } @@ -560,11 +560,11 @@ void Read2SdbgS2::Lv0Postprocess() { xinfo("Number of $ A C G T A- C- G- T-:\n"); xinfo(""); for (int i = 0; i < 9; ++i) { - xinfoc("%lld ", (long long) sdbg_writer_.final_meta().w_count(i)); + xinfoc("{} ", sdbg_writer_.final_meta().w_count(i)); } - xinfoc("\n"); - xinfo("Total number of edges: %lld\n", (long long) sdbg_writer_.final_meta().item_count()); - xinfo("Total number of ONEs: %lld\n", (long long) sdbg_writer_.final_meta().ones_in_last()); - xinfo("Total number of $v edges: %lld\n", (long long) sdbg_writer_.final_meta().tip_count()); + xinfoc("{}", "\n"); + xinfo("Total number of edges: {}\n", sdbg_writer_.final_meta().item_count()); + xinfo("Total number of ONEs: {}\n", sdbg_writer_.final_meta().ones_in_last()); + xinfo("Total number of $v edges: {}\n", sdbg_writer_.final_meta().tip_count()); assert(sdbg_writer_.final_meta().w_count(0) == sdbg_writer_.final_meta().tip_count()); } diff --git a/src/sorting/seq_to_sdbg.cpp b/src/sorting/seq_to_sdbg.cpp index ac8d880..97b73c3 100644 --- a/src/sorting/seq_to_sdbg.cpp +++ b/src/sorting/seq_to_sdbg.cpp @@ -176,7 +176,7 @@ void SeqToSdbg::GenMercyEdges() { if (rp.SeqCount() == 0) { break; } - xinfo("Read %u reads to search for mercy k-mers\n", rp.SeqCount()); + xinfo("Read {} reads to search for mercy k-mers\n", rp.SeqCount()); num_mercy_reads += rp.SeqCount(); mercy_edges.clear(); @@ -328,7 +328,7 @@ void SeqToSdbg::GenMercyEdges() { } multiplicity.insert(multiplicity.end(), num_mercy_edges, 1); - xinfo("Number of reads: %ld, Number of mercy edges: %ld\n", num_mercy_reads, num_mercy_edges); + xinfo("Number of reads: {}, Number of mercy edges: {}\n", num_mercy_reads, num_mercy_edges); } SeqToSdbg::Meta SeqToSdbg::Initialize() { @@ -343,7 +343,7 @@ SeqToSdbg::Meta SeqToSdbg::Initialize() { edge_reader.SetFilePrefix(opt_.input_prefix); edge_reader.ReadInfo(); int64_t num_edges = edge_reader.num_edges(); - xinfo("Number edges: %lld\n", (long long) num_edges); + xinfo("Number edges: {}\n", num_edges); if (opt_.need_mercy) { num_edges += num_edges >> 2; // it is rare that # mercy > 25% @@ -356,7 +356,7 @@ SeqToSdbg::Meta SeqToSdbg::Initialize() { if (!opt_.contig.empty()) { long long num_contigs, num_bases; FILE *contig_info = xfopen((opt_.contig + ".info").c_str(), "r"); - if (fscanf(contig_info, "%lld%lld", &num_contigs, &num_bases) != 2) { + if (fscanf(contig_info, "%lld %lld", &num_contigs, &num_bases) != 2) { xfatal("Invalid format\n"); } bases_to_reserve += num_bases; @@ -368,7 +368,7 @@ SeqToSdbg::Meta SeqToSdbg::Initialize() { if (!opt_.addi_contig.empty()) { long long num_contigs, num_bases; FILE *contig_info = xfopen((opt_.addi_contig + ".info").c_str(), "r"); - if (fscanf(contig_info, "%lld%lld", &num_contigs, &num_bases) != 2) { + if (fscanf(contig_info, "%lld %lld", &num_contigs, &num_bases) != 2) { xfatal("Invalid format\n"); } bases_to_reserve += num_bases; @@ -380,7 +380,7 @@ SeqToSdbg::Meta SeqToSdbg::Initialize() { if (!opt_.local_contig.empty()) { long long num_contigs, num_bases; FILE *contig_info = xfopen((opt_.local_contig + ".info").c_str(), "r"); - if (fscanf(contig_info, "%lld%lld", &num_contigs, &num_bases) != 2) { + if (fscanf(contig_info, "%lld %lld", &num_contigs, &num_bases) != 2) { xfatal("Invalid format\n"); } bases_to_reserve += num_bases; @@ -389,14 +389,14 @@ SeqToSdbg::Meta SeqToSdbg::Initialize() { fclose(contig_info); } - xinfo("Bases to reserve: %lld, number contigs: %lld, number multiplicity: %lld\n", bases_to_reserve, + xinfo("Bases to reserve: {}, number contigs: {}, number multiplicity: {}\n", bases_to_reserve, num_contigs_to_reserve, num_multiplicities_to_reserve); seq_pkg_.ReserveSequences(num_contigs_to_reserve); seq_pkg_.ReserveBases(bases_to_reserve); multiplicity.reserve(num_multiplicities_to_reserve); } - xinfo("Before reading, sizeof seq_package: %lld, multiplicity vector: %lld\n", seq_pkg_.SizeInByte(), + xinfo("Before reading, sizeof seq_package: {}, multiplicity vector: {}\n", seq_pkg_.SizeInByte(), multiplicity.capacity()); if (!opt_.input_prefix.empty()) { @@ -416,7 +416,7 @@ SeqToSdbg::Meta SeqToSdbg::Initialize() { GenMercyEdges(); timer.stop(); - xinfo("Done. Time elapsed: %.4lf\n", timer.elapsed()); + xinfo("Done. Time elapsed: {.4}\n", timer.elapsed()); } if (!opt_.contig.empty()) { @@ -445,7 +445,7 @@ SeqToSdbg::Meta SeqToSdbg::Initialize() { reader.ReadAllWithMultiplicity(&seq_pkg_, &multiplicity, contig_reverse); } - xinfo("After reading, sizeof seq_package: %lld, multiplicity vector: %lld\n", seq_pkg_.SizeInByte(), + xinfo("After reading, sizeof seq_package: {}, multiplicity vector: {}\n", seq_pkg_.SizeInByte(), multiplicity.capacity()); seq_pkg_.BuildIndex(); @@ -721,13 +721,13 @@ void SeqToSdbg::Lv0Postprocess() { xinfo("Number of $ A C G T A- C- G- T-:\n"); xinfo(""); for (int i = 0; i < 9; ++i) { - xinfoc("%lld ", (long long) sdbg_writer_.final_meta().w_count(i)); + xinfoc("{} ", sdbg_writer_.final_meta().w_count(i)); } - xinfoc("\n"); - xinfo("Total number of edges: %lld\n", (long long) sdbg_writer_.final_meta().item_count()); - xinfo("Total number of ONEs: %lld\n", (long long) sdbg_writer_.final_meta().ones_in_last()); - xinfo("Total number of $v edges: %lld\n", (long long) sdbg_writer_.final_meta().tip_count()); + xinfoc("{}", "\n"); + xinfo("Total number of edges: {}\n", sdbg_writer_.final_meta().item_count()); + xinfo("Total number of ONEs: {}\n", sdbg_writer_.final_meta().ones_in_last()); + xinfo("Total number of $v edges: {}\n", sdbg_writer_.final_meta().tip_count()); assert(sdbg_writer_.final_meta().w_count(0) == sdbg_writer_.final_meta().tip_count()); } diff --git a/src/tools/contigs_to_fastg.cpp b/src/tools/contigs_to_fastg.cpp index 5d89259..15d3f0f 100644 --- a/src/tools/contigs_to_fastg.cpp +++ b/src/tools/contigs_to_fastg.cpp @@ -25,6 +25,7 @@ #include #include +#include "utils/utils.h" #include "sequence/readers/kseq.h" using namespace std; @@ -69,7 +70,7 @@ string RevComp(const string &s) { string NodeName(int i, int len, double mul, bool is_rc) { static char buf[10240]; - sprintf(buf, "NODE_%d_length_%d_cov_%.4f_ID_%d", i, len, mul, i * 2 - 1); + psprintf(buf, "NODE_{}_length_{}_cov_{.4}_ID_{}", i, len, mul, i * 2 - 1); if (is_rc) return string(buf) + "'"; @@ -79,7 +80,7 @@ string NodeName(int i, int len, double mul, bool is_rc) { int main_contig2fastg(int argc, char **argv) { if (argc < 3) { - fprintf(stderr, "Usage: %s \n", argv[0]); + pfprintf(stderr, "Usage: {s} \n", argv[0]); exit(1); } @@ -140,7 +141,7 @@ int main_contig2fastg(int argc, char **argv) { } header += ";"; - printf("%s\n%s\n", header.c_str(), s.c_str()); + pprintf("{s}\n{s}\n", header.c_str(), s.c_str()); } } diff --git a/src/tools/extract_pe_reads.cpp b/src/tools/extract_pe_reads.cpp index 61a8247..ca18b14 100644 --- a/src/tools/extract_pe_reads.cpp +++ b/src/tools/extract_pe_reads.cpp @@ -25,6 +25,8 @@ #include #include #include + +#include "utils/utils.h" #include "sequence/readers/kseq.h" using namespace std; @@ -48,24 +50,24 @@ void output_seq(kseq_t *seq, FILE *file) { const char *comm = seq->comment.s ? seq->comment.s : ""; const char *qual = seq->qual.s ? seq->qual.s : ""; if (seq->qual.l != 0) { - fprintf(file, "@%s %s\n%s\n+%s\n%s\n", seq->name.s, comm, seq->seq.s, seq->name.s, qual); + pfprintf(file, "@{s} {s}\n{s}\n+{s}\n{s}\n", seq->name.s, comm, seq->seq.s, seq->name.s, qual); } else { - fprintf(file, ">%s %s\n%s\n", seq->name.s, comm, seq->seq.s); + pfprintf(file, ">{s} {s}\n{s}\n", seq->name.s, comm, seq->seq.s); } } void output_seq(const Seq &seq, FILE *file) { if (seq.qual.length() != 0) { - fprintf(file, "@%s %s\n%s\n+%s\n%s\n", seq.name.c_str(), seq.comment.c_str(), seq.seq.c_str(), seq.name.c_str(), + pfprintf(file, "@{s} {s}\n{s}\n+{s}\n{s}\n", seq.name.c_str(), seq.comment.c_str(), seq.seq.c_str(), seq.name.c_str(), seq.qual.c_str()); } else { - fprintf(file, ">%s %s\n%s\n", seq.name.c_str(), seq.comment.c_str(), seq.seq.c_str()); + pfprintf(file, ">{s} {s}\n{s}\n", seq.name.c_str(), seq.comment.c_str(), seq.seq.c_str()); } } int main_extract_pe(int argc, char **argv) { if (argc < 2 || ((string(argv[1]) == "-") && argc < 3)) { - fprintf(stderr, "%s [out_prefix]\n", argv[0]); + pfprintf(stderr, "{s} [out_prefix]\n", argv[0]); exit(1); } diff --git a/src/tools/filter_by_len.cpp b/src/tools/filter_by_len.cpp index d7ac746..6450b6e 100644 --- a/src/tools/filter_by_len.cpp +++ b/src/tools/filter_by_len.cpp @@ -22,6 +22,8 @@ #include #include #include + +#include "utils/utils.h" #include "sequence/readers/kseq.h" #include "utils/histgram.h" @@ -32,7 +34,7 @@ KSEQ_INIT(gzFile, gzread) int main_filter_by_len(int argc, char **argv) { if (argc < 2) { - fprintf(stderr, "Usage: cat contigs.fa | %s \n", argv[0]); + pfprintf(stderr, "Usage: cat contigs.fa | {s} \n", argv[0]); exit(1); } @@ -45,13 +47,13 @@ int main_filter_by_len(int argc, char **argv) { while (kseq_read(seq) >= 0) { if (seq->seq.l >= min_len) { hist.insert(seq->seq.l); - printf(">%s %s\n%s\n", seq->name.s, seq->comment.s, seq->seq.s); + pprintf(">{s} {s}\n{s}\n", seq->name.s, seq->comment.s, seq->seq.s); } } long long total_bases = hist.sum(); - fprintf(stderr, "%d contigs, total %lld bp, min %lld bp, max %lld bp, avg %d bp, N50 %lld bp\n", (int)hist.size(), + pfprintf(stderr, "{} contigs, total {} bp, min {} bp, max {} bp, avg {} bp, N50 {} bp\n", (int)hist.size(), total_bases, hist.minimum(), hist.maximum(), int(hist.mean() + 0.5), hist.Nx(total_bases * 0.5)); kseq_destroy(seq); diff --git a/src/tools/read_stat.cpp b/src/tools/read_stat.cpp index 1db97d8..7ae1855 100644 --- a/src/tools/read_stat.cpp +++ b/src/tools/read_stat.cpp @@ -22,6 +22,8 @@ #include #include #include + +#include "utils/utils.h" #include "sequence/readers/kseq.h" #ifndef KSEQ_INITED @@ -31,7 +33,7 @@ KSEQ_INIT(gzFile, gzread) int main_read_stat(int argc, char **argv) { if (argc > 1) { - fprintf(stderr, "Usage: cat *.fq | %s\n", argv[0]); + pfprintf(stderr, "Usage: cat *.fq | {s}\n", argv[0]); exit(1); } @@ -51,7 +53,7 @@ int main_read_stat(int argc, char **argv) { double avg_len = total_len * 1.0 / num_reads; - printf("number reads: %lld\ntotal size: %lld\nlongest: %d\nshortest: %d\navg: %lf\n", num_reads, total_len, max_len, + pprintf("number reads: {}\ntotal size: {}\nlongest: {}\nshortest: {}\navg: %lf\n", num_reads, total_len, max_len, min_len, avg_len); kseq_destroy(seq); diff --git a/src/tools/trim_low_qual_tail.cpp b/src/tools/trim_low_qual_tail.cpp index 599f11c..f98ea76 100644 --- a/src/tools/trim_low_qual_tail.cpp +++ b/src/tools/trim_low_qual_tail.cpp @@ -21,6 +21,8 @@ #include #include #include + +#include "utils/utils.h" #include "sequence/readers/kseq.h" #ifndef KSEQ_INITED @@ -30,7 +32,7 @@ KSEQ_INIT(gzFile, gzread) int main_trim_lowq_tail(int argc, char **argv) { if (argc < 4) { - fprintf(stderr, "Usage: cat *.fq | %s \n", argv[0]); + pfprintf(stderr, "Usage: cat *.fq | {s} \n", argv[0]); exit(1); } @@ -52,13 +54,13 @@ int main_trim_lowq_tail(int argc, char **argv) { if (i >= min_len) { seq->qual.s[i] = 0; seq->seq.s[i] = 0; - printf("@%s", seq->name.s); + pprintf("@{s}", seq->name.s); if (seq->comment.s != NULL) { - printf("%s", seq->comment.s); + pprintf("{s}", seq->comment.s); } - printf("\n%s\n+\n%s\n", seq->seq.s, seq->qual.s); + pprintf("\n{s}\n+\n{s}\n", seq->seq.s, seq->qual.s); } } diff --git a/src/utils/safe_open.h b/src/utils/safe_open.h index 2070bdb..332c76f 100644 --- a/src/utils/safe_open.h +++ b/src/utils/safe_open.h @@ -27,7 +27,7 @@ inline FILE *xfopen(const char *filename, const char *mode) { FILE *fp; if ((fp = fopen(filename, mode)) == nullptr) { - fprintf(stderr, "[ERROR] Cannot open %s. Now exit to system...\n", filename); + pfprintf(stderr, "[ERROR] Cannot open {s}. Now exit to system...\n", filename); exit(-1); } return fp; diff --git a/src/utils/utils.h b/src/utils/utils.h index 63d5fc6..b20ece3 100644 --- a/src/utils/utils.h +++ b/src/utils/utils.h @@ -29,6 +29,9 @@ #include #include #include +#include + +#include "pprintpp/pprintpp.hpp" template inline T1 DivCeiling(T1 a, T2 b) { @@ -46,12 +49,7 @@ inline void DecomposeUint64(RandomIt dst, uint64_t x) { dst[1] = x & 0xFFFFFFFFllu; } -inline void megahit_log__(const char *format, ...) { - va_list args; - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); -} +#define megahit_log__(str, args...) pfprintf(stderr, str, ##args) #ifndef __XFILE__ #include @@ -135,8 +133,8 @@ struct AutoMaxRssRecorder { double stime = 1e-6 * usage.ru_stime.tv_usec + usage.ru_stime.tv_sec; long long real_time = static_cast(tv2.tv_sec - tv1.tv_sec) * 1000000 + tv2.tv_usec - tv1.tv_usec; - xinfo("Real: %.4lf", real_time / 1000000.0); - xinfoc("\tuser: %.4lf\tsys: %.4lf\tmaxrss: %ld\n", utime, stime, usage.ru_maxrss); + xinfo("Real: {.4}", real_time / 1000000.0); + xinfoc("\tuser: {.4}\tsys: {.4}\tmaxrss: {}\n", utime, stime, usage.ru_maxrss); #endif } };