@@ -100,11 +100,12 @@ inline const char* cyan() {
100100} // namespace color
101101
102102enum class PipelineStage {
103- Index, // Build index only
104- Place, // Placement only
105- Align, // Placement + Alignment
106- Genotype, // Placement + Alignment + Genotyping
107- Full // Full pipeline including assembly
103+ Index, // Build index only
104+ Place, // Placement only
105+ Align, // Placement + Alignment
106+ Genotype, // Placement + Alignment + Genotyping
107+ Consensus, // + Consensus FASTA generation
108+ Full // Full pipeline
108109};
109110
110111struct Config {
@@ -1194,6 +1195,7 @@ int runAlignment(const Config& cfg,
11941195 const placement::PlacementResult& placement,
11951196 panmanUtils::Tree* preloadedTree = nullptr );
11961197int runGenotyping (const Config& cfg);
1198+ int runConsensus (const Config& cfg);
11971199
11981200int runBatchPlacement (const Config& cfg) {
11991201 // Parse batch file
@@ -1669,11 +1671,27 @@ int runGenotyping(const Config& cfg) {
16691671 return 0 ;
16701672}
16711673
1674+ int runConsensus (const Config& cfg) {
1675+ std::string refFileName = cfg.output + " .ref.fa" ;
1676+ std::string vcfFileName = cfg.output + " .vcf" ;
1677+ std::string consensusFileName = cfg.output + " .consensus.fa" ;
1678+
1679+ auto start = std::chrono::high_resolution_clock::now ();
1680+
1681+ createConsensus (vcfFileName, refFileName, consensusFileName);
1682+
1683+ auto elapsed =
1684+ std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now () - start);
1685+
1686+ logging::msg (" Consensus complete in {}ms -> {}" , elapsed.count (), consensusFileName);
1687+ return 0 ;
1688+ }
1689+
16721690void printUsage () {
16731691 std::cout << color::bold () << " panmap" << color::reset () << " v" << VERSION << " \n " ;
16741692 std::cout << " Pangenome-based sequence placement, alignment, and genotyping\n\n " ;
16751693 std::cout << color::bold () << " Usage:" << color::reset () << " panmap [options] <panman> [reads.fq] [reads2.fq]\n " ;
1676- std::cout << color::bold () << " Output:" << color::reset () << " <prefix>.vcf, <prefix>.bam, <prefix>.placement.tsv \n "
1694+ std::cout << color::bold () << " Output:" << color::reset () << " <prefix>.vcf, <prefix>.bam, <prefix>.consensus.fa, ... \n "
16771695 << " (prefix defaults to reads filename, or use -o)\n\n " ;
16781696}
16791697
@@ -1690,7 +1708,7 @@ int main(int argc, char** argv) {
16901708 (" version,V" , " Show version" )
16911709 (" output,o" , po::value<std::string>(&cfg.output ), " Output prefix" )
16921710 (" threads,t" , po::value<int >(&cfg.threads )->default_value (1 ), " Threads" )
1693- (" stop" , po::value<std::string>()->default_value (" place" ), " Stop after: index|place|align|genotype" )
1711+ (" stop" , po::value<std::string>()->default_value (" place" ), " Stop after: index|place|align|genotype|consensus " )
16941712 (" meta" , po::bool_switch (&cfg.metagenomic ), " Metagenomic mode (for more options, see --help-all)" )
16951713 (" aligner,a" , po::value<std::string>(&cfg.aligner )->default_value (" minimap2" ), " Aligner: minimap2|bwa" )
16961714 (" verbose,v" , po::bool_switch (&cfg.verbose ), " Verbose output" )
@@ -1860,6 +1878,8 @@ int main(int argc, char** argv) {
18601878 cfg.stopAfter = PipelineStage::Align;
18611879 else if (stopStr == " genotype" )
18621880 cfg.stopAfter = PipelineStage::Genotype;
1881+ else if (stopStr == " consensus" )
1882+ cfg.stopAfter = PipelineStage::Consensus;
18631883 else {
18641884 output::error (" Invalid stage '{}'" , stopStr);
18651885 return 1 ;
@@ -2064,13 +2084,29 @@ int main(int argc, char** argv) {
20642084 return 1 ;
20652085 }
20662086 if (signals::check_interrupted ()) return 130 ;
2087+ if (cfg.stopAfter == PipelineStage::Genotype) {
2088+ output::done (" Variants: " + cfg.output + " .vcf" );
2089+ output::info (" " );
2090+ output::info (" {}Next steps:{}" , color::dim (), color::reset ());
2091+ output::info (" {} View variants: bcftools view {}.vcf | head" , color::dim (), cfg.output );
2092+ output::info (" {} Consensus: panmap {} {} --stop consensus" , color::dim (), cfg.panman , cfg.reads1 );
2093+ return 0 ;
2094+ }
2095+
2096+ // Stage 5: Consensus
2097+ if (runConsensus (cfg) != 0 ) {
2098+ output::error (" Consensus generation failed" );
2099+ return 1 ;
2100+ }
2101+ if (signals::check_interrupted ()) return 130 ;
20672102
20682103 output::info (" " );
20692104 output::info (" {}Pipeline complete.{}" , color::green (), color::reset ());
20702105 output::info (" Placement: {}.placement.tsv" , cfg.output );
20712106 output::info (" Reference: {}.ref.fa" , cfg.output );
20722107 output::info (" Alignment: {}.bam" , cfg.output );
20732108 output::info (" Variants: {}.vcf" , cfg.output );
2109+ output::info (" Consensus: {}.consensus.fa" , cfg.output );
20742110 output::info (" " );
20752111 output::info (" {}Next steps:{}" , color::dim (), color::reset ());
20762112 output::info (" {} View variants: bcftools view {}.vcf | head" , color::dim (), cfg.output );
0 commit comments