123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- /*
- *
- * Copyright (c) 2011, Jue Ruan <ruanjue@gmail.com>
- *
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "wtpoa.h"
- #ifndef VERSION
- #define VERSION 0.0
- #endif
- #ifndef RELEASE
- #define RELEASE 19830203
- #endif
- int usage(){
- printf(
- "WTPOA-CNS: Consensuser for wtdbg using PO-MSA\n"
- "Author: Jue Ruan <ruanjue@gmail.com>\n"
- "Version: %s (%s)\n"
- "Usage: wtpoa-cns [options]\n"
- "Options:\n"
- " -t <int> Number of threads, [4]\n"
- " -d <string> Reference sequences for SAM input, will invoke sorted-SAM input mode\n"
- " -u <int> XORed flags to handle SAM input. [0]\n"
- " 0x1: Only process reference regions present in/between SAM alignments\n"
- " 0x2: Don't fileter secondary/supplementary SAM records with flag (0x100 | 0x800)\n"
- " -r Force to use reference mode\n"
- " -p <string> Similar with -d, but translate SAM into wtdbg layout file\n"
- " -i <string> Input file(s) *.ctg.lay from wtdbg, +, [STDIN]\n"
- " Or sorted SAM files when having -d/-p\n"
- " -o <string> Output files, [STDOUT]\n"
- " -f Force overwrite\n"
- " -j <int> Expected max length of node, or say the overlap length of two adjacent units in layout file, [1500] bp\n"
- " overlap will be default to 1500(or 150 for sam-sr) when having -d/-p, block size will be 2.5 * overlap\n"
- " -b <int> Bonus for tri-bases match, [0]\n"
- " -M <int> Match score, [2]\n"
- " -X <int> Mismatch score, [-5]\n"
- " -I <int> Insertion score, [-2]\n"
- " -D <int> Deletion score, [-4]\n"
- " -H <float> Homopolymer merge score used in dp-call-cns mode, [-3]\n"
- " -B <expr> Bandwidth in POA, [Wmin[,Wmax[,mat_rate]]], mat_rate = matched_bases/total_bases [64,1024,0.92]\n"
- " Program will double bandwidth from Wmin to Wmax when mat_rate is lower than setting\n"
- " -W <int> Window size in the middle of the first read for fast align remaining reads, [200]\n"
- " If $W is negative, will disable fast align, but use the abs($W) as Band align score cutoff\n"
- " -w <int> Min size of aligned size in window, [$W * 0.5]\n"
- " -A Abort TriPOA when any read cannot be fast aligned, then try POA\n"
- " -S <int> Shuffle mode, 0: don't shuffle reads, 1: by shared kmers, 2: subsampling. [1]\n"
- " -R <int> Realignment bandwidth, 0: disable, [16]\n"
- " -c <int> Consensus mode: 0, run-length; 1, dp-call-cns, [0]\n"
- " -C <int> Min count of bases to call a consensus base, [3]\n"
- " -F <float> Min frequency of non-gap bases to call a consensus base, [0.5]\n"
- " -N <int> Max number of reads in PO-MSA [20]\n"
- " Keep in mind that I am not going to generate high accurate consensus sequences here\n"
- " -x <string> Presets, []\n"
- " sam-sr: polishs contigs from short reads mapping, accepts sorted SAM files\n"
- " shorted for '-j 50 -W 0 -R 0 -b 1 -c 1 -N 50 -rS 2'\n"
- " -q Quiet\n"
- " -v Verbose\n"
- " -V Print version information and then exit\n"
- "\n", TOSTR(VERSION), TOSTR(RELEASE));
- return 1;
- }
- int main(int argc, char **argv){
- POGPar par;
- CTGCNS *cc;
- ctg_cns_t *ctg;
- SeqBank *refs;
- FileReader *fr, *db;
- cplist *infs, *dbfs;
- FILE *out;
- char *outf;
- u4i i;
- int reglen, shuffle, winlen, winmin, fail_skip;
- int seqmax, wsize, print_lay, flags;
- int c, ncpu, overwrite, quiet;
- par = DEFAULT_POG_PAR;
- ncpu = 4;
- quiet = 0;
- shuffle = 1;
- seqmax = 20;
- winlen = 200;
- winmin = 0;
- fail_skip = 1;
- reglen = 0;
- infs = init_cplist(4);
- dbfs = init_cplist(4);
- outf = NULL;
- overwrite = 0;
- print_lay = 0;
- flags = 0;
- while((c = getopt(argc, argv, "hqvVt:d:rp:u:i:o:fj:S:B:W:w:Ab:M:X:I:D:E:H:R:c:C:F:N:x:")) != -1){
- switch(c){
- case 'h': return usage();
- case 't': ncpu = atoi(optarg); break;
- case 'p': print_lay = 1;
- case 'd': push_cplist(dbfs, optarg); break;
- case 'u': flags = atoi(optarg); break;
- case 'r': par.refmode = 1; break;
- case 'i': push_cplist(infs, optarg); break;
- case 'o': outf = optarg; break;
- case 'f': overwrite = 1; break;
- case 'j': reglen = atoi(optarg); break;
- case 'S': shuffle = atoi(optarg); break;
- case 'B':
- {
- char *ptr;
- par.W = strtol(optarg, &ptr, 10);
- if(ptr && ptr[0] == ','){
- par.Wmax = strtol(ptr + 1, &ptr, 10);
- if(ptr && ptr[0] == ','){
- par.W_mat_rate = atof(ptr + 1);
- }
- }
- }
- break;
- case 'W': winlen = atoi(optarg); break;
- case 'w': winmin = atoi(optarg); break;
- case 'A': fail_skip = 0; break;
- case 'b': par.tribase = atoi(optarg); break;
- case 'M': par.M = atoi(optarg); break;
- case 'X': par.X = atoi(optarg); break;
- case 'I': par.I = atoi(optarg); break;
- case 'D': par.D = atoi(optarg); break;
- case 'E': par.E = atoi(optarg); break;
- case 'H': par.H = atof(optarg); break;
- case 'R': par.rW = atoi(optarg); break;
- case 'c': par.cnsmode = atoi(optarg); break;
- case 'C': par.msa_min_cnt = atoi(optarg); break;
- case 'F': par.msa_min_freq = atof(optarg); break;
- case 'N': seqmax = atoi(optarg); break;
- case 'x':
- if(strcasecmp(optarg, "sam-sr") == 0){
- winlen = 0;
- reglen = 150;
- par.rW = 0;
- par.tribase = 1;
- par.cnsmode = 1;
- seqmax = 50;
- par.refmode = 1;
- shuffle = 2;
- } else {
- fprintf(stderr, "Unknown preset[%s]\n", optarg);
- return 1;
- }
- break;
- case 'q': quiet = 1; break;
- case 'v': cns_debug ++; break;
- case 'V': fprintf(stdout, "wtpoa-cns %s\n", TOSTR(VERSION)); return 0;
- default: return usage();
- }
- }
- if(quiet){
- int devnull;
- devnull = open("/dev/null", O_WRONLY);
- dup2(devnull, STDERR_FILENO);
- }
- BEG_STAT_PROC_INFO(stderr, argc, argv);
- //SET_PROC_LIMIT(10 * 1024 * 1024 * 1024ULL, 0); // TODO: remove it after debug
- if(reglen == 0){
- reglen = 1500;
- }
- wsize = 2.5 * reglen;
- if(winlen < 0){
- par.W_score = - winlen;
- winlen = 0;
- }
- if(winmin <= 0){
- winmin = winlen * 0.5;
- }
- if(seqmax <= 0 || seqmax >= POG_RDCNT_MAX){
- seqmax = POG_RDCNT_MAX;
- }
- if(ncpu <= 0 && _sig_proc_deamon) ncpu = _sig_proc_deamon->ncpu;
- if(ncpu <= 0){
- fprintf(stderr, " -- Invalid cpu number '%d' in %s -- %s:%d --\n", ncpu, __FUNCTION__, __FILE__, __LINE__); fflush(stderr);
- return 1;
- }
- if(outf && !overwrite && file_exists(outf)){
- fprintf(stderr, "File exists! '%s'\n\n", outf);
- return usage();
- }
- if(infs->size) fr = open_all_filereader(infs->size, infs->buffer, 1);
- else fr = open_filereader(NULL, 1);
- if(outf){
- out = open_file_for_write(outf, NULL, 1);
- } else out = stdout;
- if(shuffle == 2){
- srand48(13);
- }
- if(dbfs->size == 0){
- WTLAYBlock *wb;
- wb = init_wtlayblock(fr);
- cc = init_ctgcns(wb, iter_wtlayblock, info_wtlayblock, ncpu, shuffle, seqmax, winlen, winmin, fail_skip, reglen, &par);
- cc->print_progress = 100;
- if(print_lay){
- print_lays_ctgcns(cc, out);
- } else {
- while((ctg = iter_ctgcns(cc))){
- fprintf(out, ">%s len=%d\n", ctg->tag->string, (u4i)ctg->cns->size);
- for(i=0;i<ctg->cns->size;i+=100){
- if(i + 100 <= ctg->cns->size){
- println_seq_basebank(ctg->cns, i, 100, out);
- } else {
- println_seq_basebank(ctg->cns, i, ctg->cns->size - i, out);
- }
- }
- fflush(out);
- if(cc->cycs->size){ // keep only one for reuse
- free_ctg(ctg);
- } else {
- repay_ctgcns(cc, ctg);
- }
- }
- }
- free_ctgcns(cc);
- free_wtlayblock(wb);
- } else {
- SAMBlock *sb;
- BioSequence *seq;
- if(2 * reglen >= wsize){
- fprintf(stderr, " -- SAM Input mode: -w wsize(%d), -j reglen(%d), MUST has 2 * reglen >= wsize in %s -- %s:%d --\n", wsize, reglen, __FUNCTION__, __FILE__, __LINE__); fflush(stderr);
- return 1;
- }
- refs = init_seqbank();
- db = open_all_filereader(dbfs->size, dbfs->buffer, 1);
- seq = init_biosequence();
- while(readseq_filereader(db, seq)){
- push_seqbank(refs, seq->tag->string, seq->tag->size, seq->seq->string, seq->seq->size);
- }
- free_biosequence(seq);
- close_filereader(db);
- sb = init_samblock(refs, fr, wsize, reglen * 2 / 3, flags);
- cc = init_ctgcns(sb, iter_samblock, info_samblock, ncpu, shuffle, seqmax, winlen, winmin, fail_skip, reglen, &par);
- cc->print_progress = 100;
- if(print_lay){
- print_lays_ctgcns(cc, out);
- } else {
- while((ctg = iter_ctgcns(cc))){
- fprintf(out, ">%s len=%d\n", ctg->tag->string, (u4i)ctg->cns->size);
- for(i=0;i<ctg->cns->size;i+=100){
- if(i + 100 <= ctg->cns->size){
- println_seq_basebank(ctg->cns, i, 100, out);
- } else {
- println_seq_basebank(ctg->cns, i, ctg->cns->size - i, out);
- }
- }
- fflush(out);
- if(cc->cycs->size){ // keep only one for reuse
- free_ctg(ctg);
- } else {
- repay_ctgcns(cc, ctg);
- }
- }
- }
- free_ctgcns(cc);
- free_samblock(sb);
- free_seqbank(refs);
- }
- close_filereader(fr);
- if(outf) fclose(out);
- free_cplist(infs);
- free_cplist(dbfs);
- END_STAT_PROC_INFO(stderr);
- return 0;
- }
|