wtdbg.c 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271
  1. /*
  2. *
  3. * Copyright (c) 2011, Jue Ruan <ruanjue@gmail.com>
  4. *
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "wtdbg.h"
  20. #include "wtdbg-graph.h"
  21. #include <getopt.h>
  22. #include <regex.h>
  23. #ifndef VERSION
  24. #define VERSION 0.0
  25. #endif
  26. #ifndef RELEASE
  27. #define RELEASE 19830203
  28. #endif
  29. static struct option prog_opts[] = {
  30. {"cpu", 1, 0, 't'},
  31. {"input", 1, 0, 'i'},
  32. {"err-free-seq", 1, 0, 'I'},
  33. {"force", 0, 0, 'f'},
  34. {"prefix", 1, 0, 'o'},
  35. {"preset", 1, 0, 'x'},
  36. {"kmer-fsize", 1, 0, 'k'},
  37. {"kmer-psize", 1, 0, 'p'},
  38. {"kmer-depth-max", 1, 0, 'K'},
  39. {"kmer-depth-min", 1, 0, 'E'},
  40. {"genome-size", 1, 0, 'g'},
  41. {"rdcov-cutoff", 1, 0, 'X'},
  42. {"rdname-filter", 1, 0, 3007},
  43. {"rdname-includeonly", 1, 0, 3008},
  44. {"rdcov-filter", 1, 0, 2009},
  45. //{"kmer-depth-min-filter", 0, 0, 'F'},
  46. {"kmer-subsampling", 1, 0, 'S'},
  47. {"kbm-parts", 1, 0, 1035},
  48. {"dp-max-gap", 1, 0, 2005},
  49. {"dp-max-var", 1, 0, 2006},
  50. {"dp-penalty-gap", 1, 0, 2007},
  51. {"dp-penalty-var", 1, 0, 2008},
  52. {"aln-min-length", 1, 0, 'l'},
  53. {"aln-min-match", 1, 0, 'm'},
  54. {"aln-min-similarity", 1, 0, 's'},
  55. {"aln-max-var", 1, 0, 2004},
  56. {"realign", 0, 0, 'R'},
  57. {"realn-kmer-psize", 1, 0, 3001},
  58. {"realn-kmer-subsampling", 1, 0, 3002},
  59. {"realn-min-length", 1, 0, 3003},
  60. {"realn-min-match", 1, 0, 3004},
  61. {"realn-min-similarity", 1, 0, 3005},
  62. {"realn-max-var", 1, 0, 3006},
  63. //{"corr-mode", 1, 0, 2010},
  64. //{"corr-min", 1, 0, 2012},
  65. //{"corr-max", 1, 0, 2013},
  66. //{"corr-cov", 1, 0, 2014},
  67. //{"corr-block-size", 1, 0, 2015},
  68. //{"corr-block-step", 1, 0, 2016},
  69. {"keep-multiple-alignment-parts", 1, 0, 2011},
  70. {"verbose", 0, 0, 'v'},
  71. {"quiet", 0, 0, 'q'},
  72. {"version", 0, 0, 'V'},
  73. {"help", 0, 0, 1000}, // detailed document
  74. {"tidy-reads", 1, 0, 'L'},
  75. {"tidy-name", 0, 0, 1001},
  76. {"err-free-nodes", 0, 0, 1002},
  77. {"limit-input", 1, 0, 1003},
  78. {"node-len", 1, 0, 1004},
  79. {"node-ovl", 1, 0, 1005},
  80. {"node-drop", 1, 0, 1006},
  81. {"edge-min", 1, 0, 'e'},
  82. {"edge-max-span", 1, 0, 3009},
  83. {"node-min", 1, 0, 1007},
  84. {"node-max", 1, 0, 1008},
  85. {"ttr-cutoff-depth", 1, 0, 1009},
  86. {"ttr-cutoff-ratio", 1, 0, 1010},
  87. {"dump-seqs", 1, 0, 1036},
  88. {"dump-kbm", 1, 0, 1011},
  89. {"load-seqs", 1, 0, 2002},
  90. {"load-kbm", 1, 0, 1012},
  91. {"load-alignments", 1, 0, 1013},
  92. {"load-nodes", 1, 0, 2000},
  93. {"load-clips", 1, 0, 2001},
  94. {"aln-strand", 1, 0, 1014},
  95. {"bubble-step", 1, 0, 1015},
  96. {"tip-step", 1, 0, 1016},
  97. {"ctg-min-length", 1, 0, 1017},
  98. {"ctg-min-nodes", 1, 0, 1018},
  99. {"minimal-output", 0, 0, 1019},
  100. {"bin-complexity-cutoff", 1, 0, 1020},
  101. {"aln-dovetail", 1, 0, 1021},
  102. {"no-local-graph-analysis", 0, 0, 1022},
  103. {"no-read-length-sort", 0, 0, 1023},
  104. {"keep-isolated-nodes", 0, 0, 1024},
  105. {"no-read-clip", 0, 0, 1025},
  106. {"no-chainning-clip", 0, 0, 1026},
  107. {"aln-bestn", 1, 0, 1027},
  108. {"aln-maxhit", 1, 0, 1028},
  109. {"aln-kmer-sampling", 1, 0, 1029},
  110. {"aln-noskip", 0, 0, 'A'},
  111. {"node-matched-bins", 1, 0, 1031},
  112. {"rescue-low-cov-edges", 0, 0, 1032},
  113. {"drop-low-cov-edges", 0, 0, 1033},
  114. {"mem-stingy", 0, 0, 1034},
  115. {0, 0, 0, 0}
  116. };
  117. int usage(int level){
  118. printf(
  119. "WTDBG: De novo assembler for long noisy sequences\n"
  120. "Author: Jue Ruan <ruanjue@gmail.com>\n"
  121. "Version: %s (%s)\n"
  122. "Usage: wtdbg2 [options] -i <reads.fa> -o <prefix> [reads.fa ...]\n"
  123. "Options:\n"
  124. " -i <string> Long reads sequences file (REQUIRED; can be multiple), []\n"
  125. " -o <string> Prefix of output files (REQUIRED), []\n"
  126. " -t <int> Number of threads, 0 for all cores, [4]\n"
  127. " -f Force to overwrite output files\n"
  128. " -x <string> Presets, comma delimited, []\n"
  129. " preset1/rsII/rs: -p 21 -S 4 -s 0.05 -L 5000\n"
  130. " preset2: -p 0 -k 15 -AS 2 -s 0.05 -L 5000\n"
  131. " preset3: -p 19 -AS 2 -s 0.05 -L 5000\n"
  132. " sequel/sq\n"
  133. " nanopore/ont:\n"
  134. " (genome size < 1G: preset2) -p 0 -k 15 -AS 2 -s 0.05 -L 5000\n"
  135. " (genome size >= 1G: preset3) -p 19 -AS 2 -s 0.05 -L 5000\n"
  136. " preset4/corrected/ccs: -p 21 -k 0 -AS 4 -K 0.05 -s 0.5\n"
  137. " -g <number> Approximate genome size (k/m/g suffix allowed) [0]\n"
  138. " -X <float> Choose the best <float> depth from input reads(effective with -g) [50.0]\n"
  139. " -L <int> Choose the longest subread and drop reads shorter than <int> (5000 recommended for PacBio) [0]\n"
  140. " Negative integer indicate tidying read names too, e.g. -5000.\n"
  141. " -k <int> Kmer fsize, 0 <= k <= 23, [0]\n"
  142. " -p <int> Kmer psize, 0 <= p <= 23, [21]\n"
  143. " k + p <= 25, seed is <k-mer>+<p-homopolymer-compressed>\n"
  144. " -K <float> Filter high frequency kmers, maybe repetitive, [1000.05]\n"
  145. " >= 1000 and indexing >= (1 - 0.05) * total_kmers_count\n"
  146. " -S <float> Subsampling kmers, 1/(<-S>) kmers are indexed, [4.00]\n"
  147. " -S is very useful in saving memeory and speeding up\n"
  148. " please note that subsampling kmers will have less matched length\n"
  149. " -l <float> Min length of alignment, [2048]\n"
  150. " -m <float> Min matched length by kmer matching, [200]\n"
  151. " -R Enable realignment mode\n"
  152. " -A Keep contained reads during alignment\n"
  153. " -s <float> Min similarity, calculated by kmer matched length / aligned length, [0.05]\n"
  154. " -e <int> Min read depth of a valid edge, [3]\n"
  155. " -q Quiet\n"
  156. " -v Verbose (can be multiple)\n"
  157. " -V Print version information and then exit\n"
  158. " --help Show more options\n"
  159. , TOSTR(VERSION), TOSTR(RELEASE)
  160. );
  161. if(level > 0){
  162. printf(
  163. " ** more options **\n"
  164. " --cpu <int>\n"
  165. " See -t 0, default: all cores\n"
  166. " --input <string> +\n"
  167. " See -i\n"
  168. //" --err-free-seq <string> +\n"
  169. //" See -I. Error-free sequences will be firstly token for nodes, if --err-free-nodes is specified, only select nodes from those sequences\n"
  170. " --force\n"
  171. " See -f\n"
  172. " --prefix <string>\n"
  173. " See -o\n"
  174. " --preset <string>\n"
  175. " See -x\n"
  176. " --kmer-fsize <int>\n"
  177. " See -k 0\n"
  178. " --kmer-psize <int>\n"
  179. " See -p 21\n"
  180. " --kmer-depth-max <float>\n"
  181. " See -K 1000.05\n"
  182. " -E, --kmer-depth-min <int>\n"
  183. " Min kmer frequency, [2]\n"
  184. //" --kmer-depth-min-filter\n"
  185. //" See -F\n"
  186. //" `wtdbg` uses a 4 Gbytes array to counting the occurence (0-3) of kmers in the way of counting-bloom-filter. It will reduce memory space largely\n"
  187. //" Orphaned kmers won't appear in building kbm-index\n"
  188. " --kmer-subsampling <float>\n"
  189. " See -S 4.0\n"
  190. " --kbm-parts <int>\n"
  191. " Split total reads into multiple parts, index one part by one to save memory, [1]\n"
  192. " --aln-kmer-sampling <int>\n"
  193. " Select no more than n seeds in a query bin, default: 256\n"
  194. " --dp-max-gap <int>\n"
  195. " Max number of bin(256bp) in one gap, [4]\n"
  196. " --dp-max-var <int>\n"
  197. " Max number of bin(256bp) in one deviation, [4]\n"
  198. " --dp-penalty-gap <int>\n"
  199. " Penalty for BIN gap, [-7]\n"
  200. " --dp-penalty-var <int>\n"
  201. " Penalty for BIN deviation, [-21]\n"
  202. " --aln-min-length <int>\n"
  203. " See -l 2048\n"
  204. " --aln-min-match <int>\n"
  205. " See -m 200. Here the num of matches counting basepair of the matched kmer's regions\n"
  206. " --aln-min-similarity <float>\n"
  207. " See -s 0.05\n"
  208. " --aln-max-var <float>\n"
  209. " Max length variation of two aligned fragments, default: 0.25\n"
  210. " --aln-dovetail <int>\n"
  211. " Retain dovetail overlaps only, the max overhang size is <--aln-dovetail>, the value should be times of 256, -1 to disable filtering, default: 256\n"
  212. " --aln-strand <int>\n"
  213. " 1: forward, 2: reverse, 3: both. Please don't change the deault vaule 3, unless you exactly know what you are doing\n"
  214. " --aln-maxhit <int>\n"
  215. " Max n hits for each read in build graph, default: 1000\n"
  216. " --aln-bestn <int>\n"
  217. " Use best n hits for each read in build graph, 0: keep all, default: 500\n"
  218. " <prefix>.alignments always store all alignments\n"
  219. " -R, --realign\n"
  220. " Enable re-alignment, see --realn-kmer-psize=15, --realn-kmer-subsampling=1, --realn-min-length=2048, --realn-min-match=200, --realn-min-similarity=0.1, --realn-max-var=0.25\n"
  221. " --realn-kmer-psize <int>\n"
  222. " Set kmer-psize in realignment, (kmer-ksize always eq 0), default:15\n"
  223. " --realn-kmer-subsampling <int>\n"
  224. " Set kmer-subsampling in realignment, default:1\n"
  225. " --realn-min-length <int>\n"
  226. " Set aln-min-length in realignment, default: 2048\n"
  227. " --realn-min-match <int>\n"
  228. " Set aln-min-match in realignment, default: 200\n"
  229. " --realn-min-similarity <float>\n"
  230. " Set aln-min-similarity in realignment, default: 0.1\n"
  231. " --realn-max-var <float>\n"
  232. " Set aln-max-var in realignment, default: 0.25\n"
  233. " -A, --aln-noskip\n"
  234. " Even a read was contained in previous alignment, still align it against other reads\n"
  235. //" --corr-mode <float>\n"
  236. //" Default: 0.0. If set > 0 and set --g <genome_size>, will turn on correct-align mode.\n"
  237. //" Wtdbg will select <genome_size> * <corr-mode> bases from reads of middle length, and align them aginst all reads.\n"
  238. //" Then, wtdbg will correct them using POACNS, and query corrected sequences against all reads again\n"
  239. //" In correct-align mode, --aln-bestn = unlimited, --no-read-clip, --no-chaining-clip. Will support those features in future\n"
  240. //" --corr-min <int>\n"
  241. //" --corr-max <int>\n"
  242. //" For each read to be corrected, uses at least <corr-min> alignments, and at most <corr-max> alignments\n"
  243. //" Default: --corr_min = 5, --corr-max = 10\n"
  244. //" --corr-cov <float>\n"
  245. //" Default: 0.75. When aligning reads to be corrected, the alignments should cover at least <corr-cov> of read length\n"
  246. //" --corr-block-size <int>\n"
  247. //" Default: 2048. MUST be times of 256bp. Used in POACNS\n"
  248. //" --corr-block-step <int>\n"
  249. //" Default: 1536. MUST be times of 256bp. Used in POACNS\n"
  250. " --keep-multiple-alignment-parts\n"
  251. " By default, wtdbg will keep only the best alignment between two reads after chainning. This option will disable it, and keep multiple\n"
  252. " --verbose +\n"
  253. " See -v. -vvvv will display the most detailed information\n"
  254. " --quiet\n"
  255. " See -q\n"
  256. " --limit-input <int>\n"
  257. " Limit the input sequences to at most <int> M bp. Usually for test\n"
  258. " -L <int>, --tidy-reads <int>\n"
  259. " Default: 0. Pick longest subreads if possible. Filter reads less than <--tidy-reads>. Please add --tidy-name or set --tidy-reads to nagetive value\n"
  260. " if want to rename reads. Set to 0 bp to disable tidy. Suggested value is 5000 for pacbio RSII reads\n"
  261. " --tidy-name\n"
  262. " Rename reads into 'S%%010d' format. The first read is named as S0000000001\n"
  263. " --rdname-filter <string>\n"
  264. " A file contains lines of reads name to be discarded in loading. If you want to filter reads by yourself, please also set -X 0\n"
  265. " --rdname-includeonly <string>\n"
  266. " Reverse manner with --rdname-filter\n"
  267. //" --keep-name\n"
  268. //" Keep orignal read names even with --tidy-reads, '-L 5000 --keep-name' equals '-L -5000'\n"
  269. " -g <number>, --genome-size <number>\n"
  270. " Provide genome size, e.g. 100.4m, 2.3g. In this version, it is used with -X/--rdcov-cutoff in selecting reads just after readed all.\n"
  271. " -X <float>, --rdcov-cutoff <float>\n"
  272. " Default: 50.0. Retaining 50.0 folds of genome coverage, combined with -g and --rdcov-filter.\n"
  273. " --rdcov-filter [0|1]\n"
  274. " Default 0. Strategy 0: retaining longest reads. Strategy 1: retaining medain length reads. \n"
  275. " --err-free-nodes\n"
  276. " Select nodes from error-free-sequences only. E.g. you have contigs assembled from NGS-WGS reads, and long noisy reads.\n"
  277. " You can type '--err-free-seq your_ctg.fa --input your_long_reads.fa --err-free-nodes' to perform assembly somehow act as long-reads scaffolding\n"
  278. " --node-len <int>\n"
  279. " The default value is 1024, which is times of KBM_BIN_SIZE(always equals 256 bp). It specifies the length of intervals (or call nodes after selecting).\n"
  280. " kbm indexs sequences into BINs of 256 bp in size, so that many parameter should be times of 256 bp. There are: --node-len, --node-ovl, --aln-min-length, --aln-dovetail ."
  281. " Other parameters are counted in BINs, --dp-max-gap, --dp-max-var .\n"
  282. " --node-matched-bins <int>\n"
  283. " Min matched bins in a node, default:1\n"
  284. " --node-ovl <int>\n"
  285. " Default: 256. Max overlap size between two adjacent intervals in any read. It is used in selecting best nodes representing reads in graph\n"
  286. " --node-drop <float>\n"
  287. " Default: 0.25. Will discard an node when has more this ratio intervals are conflicted with previous generated node\n"
  288. " -e <int>, --edge-min=<int>\n"
  289. " Default: 3. The minimal depth of a valid edge is set to 3. In another word, Valid edges must be supported by at least 3 reads\n"
  290. " When the sequence depth is low, have a try with --edge-min 2. Or very high, try --edge-min 4\n"
  291. " --edge-max-span <int>\n"
  292. " Default: 1024 BINs. Program will build edges of length no large than 1024\n"
  293. " --drop-low-cov-edges\n"
  294. " Don't attempt to rescue low coverage edges\n"
  295. " --node-min <int>\n"
  296. " Min depth of an interval to be selected as valid node. Defaultly, this value is automaticly the same with --edge-min.\n"
  297. " --node-max <int>\n"
  298. " Nodes with too high depth will be regarded as repetitive, and be masked. Default: 200, more than 200 reads contain this node\n"
  299. " --ttr-cutoff-depth <int>, 0\n"
  300. " --ttr-cutoff-ratio <float>, 0.5\n"
  301. " Tiny Tandom Repeat. A node located inside ttr will bring noisy in graph, should be masked. The pattern of such nodes is:\n"
  302. " depth >= <--ttr-cutoff-depth>, and none of their edges have depth greater than depth * <--ttr-cutoff-ratio 0.5>\n"
  303. " set --ttr-cutoff-depth 0 to disable ttr masking\n"
  304. " --dump-kbm <string>\n"
  305. " Dump kbm index into file for loaded by `kbm` or `wtdbg`\n"
  306. " --dump-seqs <string>\n"
  307. " Dump kbm index (only sequences, no k-mer index) into file for loaded by `kbm` or `wtdbg`\n"
  308. " Please note: normally load it with --load-kbm, not with --load-seqs\n"
  309. " --load-kbm <string>\n"
  310. " Instead of reading sequences and building kbm index, which is time-consumed, loading kbm-index from already dumped file.\n"
  311. " Please note that, once kbm-index is mmaped by kbm -R <kbm-index> start, will just get the shared memory in minute time.\n"
  312. " See `kbm` -R <your_seqs.kbmidx> [start | stop]\n"
  313. " --load-seqs <string>\n"
  314. " Similar with --load-kbm, but only use the sequences in kbmidx, and rebuild index in process's RAM.\n"
  315. " --load-alignments <string> +\n"
  316. " `wtdbg` output reads' alignments into <--prefix>.alignments, program can load them to fastly build assembly graph. Or you can offer\n"
  317. " other source of alignments to `wtdbg`. When --load-alignment, will only reading long sequences but skip building kbm index\n"
  318. " You can type --load-alignments <file> more than once to load alignments from many files\n"
  319. " --load-clips <string>\n"
  320. " Combined with --load-nodes. Load reads clips. You can find it in `wtdbg`'s <--prefix>.clps\n"
  321. " --load-nodes <sting>\n"
  322. " Load dumped nodes from previous execution for fast construct the assembly graph, should be combined with --load-clips. You can find it in `wtdbg`'s <--prefix>.1.nodes\n"
  323. " --bubble-step <int>\n"
  324. " Max step to search a bubble, meaning the max step from the starting node to the ending node. Default: 40\n"
  325. " --tip-step <int>\n"
  326. " Max step to search a tip, 10\n"
  327. " --ctg-min-length <int>\n"
  328. " Min length of contigs to be output, 5000\n"
  329. " --ctg-min-nodes <int>\n"
  330. " Min num of nodes in a contig to be ouput, 3\n"
  331. " --minimal-output\n"
  332. " Will generate as less output files (<--prefix>.*) as it can\n"
  333. " --bin-complexity-cutoff <int>\n"
  334. " Used in filtering BINs. If a BIN has less indexed valid kmers than <--bin-complexity-cutoff 2>, masks it.\n"
  335. " --no-local-graph-analysis\n"
  336. " Before building edges, for each node, local-graph-analysis reads all related reads and according nodes, and builds a local graph to judge whether to mask it\n"
  337. " The analysis aims to find repetitive nodes\n"
  338. " --no-read-length-sort\n"
  339. " Defaultly, `wtdbg` sorts input sequences by length DSC. The order of reads affects the generating of nodes in selecting important intervals\n"
  340. " --keep-isolated-nodes\n"
  341. " In graph clean, `wtdbg` normally masks isolated (orphaned) nodes\n"
  342. " --no-read-clip\n"
  343. " Defaultly, `wtdbg` clips a input sequence by analyzing its overlaps to remove high error endings, rolling-circle repeats (see PacBio CCS), and chimera.\n"
  344. " When building edges, clipped region won't contribute. However, `wtdbg` will use them in the final linking of unitigs\n"
  345. " --no-chainning-clip\n"
  346. " Defaultly, performs alignments chainning in read clipping\n"
  347. " ** If '--aln-bestn 0 --no-read-clip', alignments will be parsed directly, and less RAM spent on recording alignments\n"
  348. "\n"
  349. );
  350. }
  351. return (level < 0)? 1 : 0;
  352. }
  353. static inline int64_t mm_parse_num(const char *str)
  354. {
  355. double x;
  356. char *p;
  357. x = strtod(str, &p);
  358. if (*p == 'G' || *p == 'g') x *= 1e9;
  359. else if (*p == 'M' || *p == 'm') x *= 1e6;
  360. else if (*p == 'K' || *p == 'k') x *= 1e3;
  361. return (int64_t)(x + .499);
  362. }
  363. int main(int argc, char **argv){
  364. Graph *g;
  365. KBMPar *par, *rpar;
  366. KBM *kbm;
  367. FileReader *fr;
  368. BioSequence *seqs[2], *seq;
  369. chash *rdtaghash[2];
  370. cplist *pbs, *ngs, *pws;
  371. FILE *evtlog;
  372. char *prefix, *rdtag_filter[2], *dump_seqs, *load_seqs, *dump_kbm, *load_kbm, *load_nodes, *load_clips;
  373. char regtag[14];
  374. int len, tag_size, asyn_read, preset;
  375. u8i tot_bp, cnt, bub, tip, rep, yarn, max_bp, max_idx_bp, nfix, opt_flags;
  376. uint32_t i, j, k;
  377. int c, opt_idx, ncpu, only_fix, realign, node_cov, max_node_cov, exp_node_cov, min_bins, edge_cov, edge_span, store_low_cov_edge, reglen, regovl, bub_step, tip_step, rep_step;
  378. int frgtip_len, ttr_n_cov;
  379. int quiet, tidy_reads, filter_rd_strategy, tidy_rdtag, less_out, tip_like, cut_tip, rep_filter, out_alns, cnn_filter, log_rep, rep_detach, del_iso, rdclip, chainning, uniq_hit, bestn, rescue_low_edges;
  380. int min_ctg_len, min_ctg_nds, max_trace_end, max_overhang, overwrite, node_order, fast_mode, corr_min, corr_max, corr_bsize, corr_bstep, mem_stingy, num_index;
  381. double genome_size, genome_depx;
  382. float node_drop, node_mrg, ttr_e_cov, fval, cut_low_edges, corr_mode, corr_cov;
  383. pbs = init_cplist(4);
  384. ngs = init_cplist(4);
  385. pws = init_cplist(4);
  386. asyn_read = 1;
  387. ncpu = 4;
  388. mem_stingy = 0;
  389. tidy_reads = 0;
  390. tidy_rdtag = -1;
  391. preset = 0;
  392. genome_size = 0;
  393. genome_depx = 50.0;
  394. num_index = 1;
  395. filter_rd_strategy = 0;
  396. fast_mode = 0;
  397. // no longer supports corr-mode
  398. corr_mode = 0;
  399. corr_min = 5;
  400. corr_max = 10;
  401. corr_cov = 0.75;
  402. corr_bsize = 2048;
  403. corr_bstep = 2048 - 512;
  404. // -------
  405. max_bp = 0;
  406. max_idx_bp = 0LLU * 1000 * 1000 * 1000; // unlimited
  407. rdtag_filter[0] = NULL;
  408. rdtag_filter[1] = NULL;
  409. rdtaghash[0] = NULL;
  410. rdtaghash[1] = NULL;
  411. reglen = 1024;
  412. regovl = 256;
  413. node_drop = 0.25;
  414. node_mrg = 0.9;
  415. only_fix = 0;
  416. node_cov = 0; // will equal edge_cov, if no --node-cov
  417. max_node_cov = 200;
  418. exp_node_cov = 40;
  419. min_bins = 1;
  420. edge_cov = 0; // will be set to 3, if no genome_size available and no -e
  421. edge_span = 1024;
  422. rdclip = 1;
  423. chainning = 1;
  424. uniq_hit = 1;
  425. bestn = 500;
  426. ttr_n_cov = 0;
  427. ttr_e_cov = 0.5;
  428. dump_seqs = NULL;
  429. load_seqs = NULL;
  430. dump_kbm = NULL;
  431. load_kbm = NULL;
  432. load_clips = NULL;
  433. load_nodes = NULL;
  434. store_low_cov_edge = 1;
  435. cut_low_edges = 0.0;
  436. rescue_low_edges = 1;
  437. bub_step = 40;
  438. tip_step = 10;
  439. rep_step = 0;
  440. max_trace_end = 5;
  441. frgtip_len = 50000;
  442. prefix = NULL;
  443. overwrite = 0;
  444. less_out = 0;
  445. quiet = 0;
  446. rep_filter = 1;
  447. tip_like = 0;
  448. cut_tip = 1;
  449. cnn_filter = 1;
  450. log_rep = 1;
  451. rep_detach = 0;
  452. del_iso = 1;
  453. max_overhang = 256;
  454. min_ctg_len = 5000;
  455. min_ctg_nds = 3;
  456. node_order = 0;
  457. out_alns = 1;
  458. par = init_kbmpar();
  459. par->ksize = 0;
  460. par->psize = 21;
  461. par->kmer_mod = KBM_N_HASH * 4;
  462. par->kmin = 2;
  463. par->max_bgap = 4;
  464. par->max_bvar = 4;
  465. par->self_aln = 1; // won't perform B->A when existing A->B
  466. par->rd_len_order = 1;
  467. par->min_aln = 2048 / KBM_BIN_SIZE;
  468. par->min_mat = 200;
  469. par->min_sim = 0.05;
  470. par->aln_var = 0.25;
  471. realign = 0;
  472. rpar = init_kbmpar();
  473. rpar->ksize = 0;
  474. rpar->psize = 15;
  475. rpar->kmer_mod = KBM_N_HASH;
  476. rpar->kmin = 1;
  477. rpar->max_bgap = 4;
  478. rpar->max_bvar = 4;
  479. rpar->self_aln = 0; // won't perform B->A when existing A->B
  480. rpar->rd_len_order = 0;
  481. rpar->min_aln = 2048 / KBM_BIN_SIZE;
  482. rpar->min_mat = 200;
  483. rpar->min_sim = 0.1;
  484. rpar->aln_var = 0.25;
  485. opt_flags = 0;
  486. // 初始化mpi分布式通讯 ningwenmo@outlook.com
  487. MPI_Init(&argc, &argv);
  488. MPI_Comm_rank(MPI_COMM_WORLD, &g_mpi_comm_rank);
  489. MPI_Comm_size(MPI_COMM_WORLD, &g_mpi_comm_size);
  490. while((c = getopt_long(argc, argv, "ht:i:fo:x:E:k:p:K:S:l:m:s:RvqVe:L:Ag:X:", prog_opts, &opt_idx)) != -1){
  491. switch(c){
  492. case 't': ncpu = atoi(optarg); break;
  493. case 'i': push_cplist(pbs, optarg); break;
  494. //case 'I': push_cplist(ngs, optarg); par->rd_len_order = 0; break;
  495. case 'f': overwrite = 1; break;
  496. case 'o': prefix = optarg; break;
  497. case 'x':
  498. {
  499. char *ptr, *beg;
  500. beg = optarg;
  501. do {
  502. ptr = index(beg, ',');
  503. if(ptr) *ptr = 0;
  504. if(KBM_LOG){
  505. fprintf(KBM_LOGF, " -- Preset: '%s' --", beg); fflush(KBM_LOGF);
  506. }
  507. if(strcasecmp(beg, "preset1") == 0 || strcasecmp(beg, "rs") == 0 || strcasecmp(beg, "rsII") == 0){
  508. preset = 1;
  509. } else if(strcasecmp(beg, "preset2") == 0){
  510. preset = 2;
  511. } else if(strcasecmp(beg, "preset3") == 0){
  512. preset = 3;
  513. } else if(strcasecmp(beg, "sq") == 0 || strcasecmp(beg, "sequel") == 0){
  514. preset = -1;
  515. } else if(strcasecmp(beg, "ont") == 0 || strcasecmp(beg, "nanopore") == 0){
  516. preset = -1;
  517. } else if(strcasecmp(beg, "preset4") == 0 || strcasecmp(beg, "ccs") == 0 || strcasecmp(beg, "corrected") == 0){
  518. preset = 4;
  519. } else {
  520. fprintf(stderr, " ** ERROR: cannot recognize '%s' in '-x %s'\n", beg, optarg);
  521. exit(1);
  522. }
  523. if(KBM_LOG){
  524. fprintf(KBM_LOGF, "\n"); fflush(KBM_LOGF);
  525. }
  526. if(ptr){
  527. *ptr = ',';
  528. beg = ptr + 1;
  529. } else {
  530. break;
  531. }
  532. } while(1);
  533. }
  534. break;
  535. case 'k': par->ksize = atoi(optarg); opt_flags |= (1 << 1); break;
  536. case 'p': par->psize = atoi(optarg); opt_flags |= (1 << 0); break;
  537. case 'K': fval = atof(optarg); par->kmax = fval; par->ktop = fval - par->kmax; opt_flags |= (1 << 6); break;
  538. case 'E': par->kmin = atoi(optarg); break;
  539. case 'S': par->kmer_mod = UInt(atof(optarg) * KBM_N_HASH); opt_flags |= (1 << 2);break;
  540. case 'g': genome_size = mm_parse_num(optarg); break;
  541. case 'X': genome_depx = atof(optarg); break;
  542. case 3007: rdtag_filter[0] = optarg; break;
  543. case 3008: rdtag_filter[1] = optarg; break;
  544. case 2009: filter_rd_strategy = atoi(optarg); break;
  545. case 2005: par->max_bgap = atoi(optarg); break;
  546. case 2006: par->max_bvar = atoi(optarg); break;
  547. case 2007: par->pgap = atoi(optarg); break;
  548. case 2008: par->pvar = atoi(optarg); break;
  549. case 'l': par->min_aln = atoi(optarg) / KBM_BIN_SIZE; break;
  550. case 'm': par->min_mat = atoi(optarg); break;
  551. case 2004: par->aln_var = atof(optarg); break;
  552. case 's': par->min_sim = atof(optarg); opt_flags |= (1 << 3); break;
  553. //case 2010: corr_mode = atof(optarg); break;
  554. //case 2012: corr_min = atoi(optarg); break;
  555. //case 2013: corr_max = atoi(optarg); break;
  556. //case 2014: corr_cov = atof(optarg); break;
  557. //case 2015: corr_bsize = atoi(optarg); break;
  558. //case 2016: corr_bstep = atoi(optarg); break;
  559. case 2011: uniq_hit = 0; break;
  560. case 'v': KBM_LOG ++; break;
  561. case 'q': quiet = 1; break;
  562. case 'h': return usage(0);
  563. case 1000: return usage(1);
  564. case 'L': tidy_reads = atoi(optarg); opt_flags |= (1 << 4); break;
  565. case 1001: tidy_rdtag = 1; break;
  566. case 1002: only_fix = 1; break;
  567. case 1003: max_bp = atol(optarg); break;
  568. case 1035: num_index = atoi(optarg); break;
  569. case 1004: reglen = atoi(optarg); break;
  570. case 1005: regovl = atoi(optarg); break;
  571. case 1006: node_drop = atof(optarg); break;
  572. case 'e': edge_cov = atoi(optarg); break;
  573. case 3009: edge_span = atoi(optarg); break;
  574. case 1007: node_cov = atoi(optarg); break;
  575. case 1008: max_node_cov = atoi(optarg); break;
  576. case 1009: ttr_n_cov = atoi(optarg); break;
  577. case 1010: ttr_e_cov = atof(optarg); break;
  578. case 1036: dump_seqs = optarg; break;
  579. case 2002: load_seqs = optarg; break;
  580. case 1011: dump_kbm = optarg; break;
  581. case 1012: load_kbm = optarg; break;
  582. case 2000: load_nodes = optarg; break;
  583. case 2001: load_clips = optarg; break;
  584. case 1013: push_cplist(pws, optarg); break;
  585. case 1014: par->strand_mask = atoi(optarg); break;
  586. case 1015: bub_step = atoi(optarg); break;
  587. case 1016: tip_step = atoi(optarg); break;
  588. case 1017: min_ctg_len = atoi(optarg); break;
  589. case 1018: min_ctg_nds = atoi(optarg); break;
  590. case 1019: less_out = 1; break;
  591. case 1020: par->min_bin_degree = atoi(optarg); break;
  592. case 1021: max_overhang = atoi(optarg); break;
  593. case 1022: cnn_filter = 0; break;
  594. case 1023: par->rd_len_order = 0; break;
  595. case 1024: del_iso = 0; break;
  596. case 1025: rdclip = 0; break;
  597. case 1026: chainning = 0; break;
  598. case 1027: bestn = atoi(optarg); break;
  599. case 1028: par->max_hit = atoi(optarg); break;
  600. case 1029: par->ksampling = atoi(optarg); break;
  601. case 'R': realign = 1; break;
  602. case 3001: rpar->psize = atoi(optarg); break;
  603. case 3002: rpar->kmer_mod = UInt(atof(optarg) * KBM_N_HASH); break;
  604. case 3003: rpar->min_aln = atoi(optarg) / KBM_BIN_SIZE; break;
  605. case 3004: rpar->min_mat = atoi(optarg); break;
  606. case 3005: rpar->min_sim = atof(optarg); break;
  607. case 3006: rpar->aln_var = atof(optarg); break;
  608. case 'A': par->skip_contained = 0; opt_flags |= (1 << 5); break;
  609. case 1031: min_bins = atoi(optarg); break;
  610. case 1032: rescue_low_edges = 1; break;
  611. case 1033: rescue_low_edges = 0; break;
  612. case 'V': fprintf(stdout, "wtdbg2 %s\n", TOSTR(VERSION)); return 0;
  613. case 1034: mem_stingy = 1; break;
  614. default: return usage(-1);
  615. }
  616. }
  617. if(optind == 1) return usage(-1);
  618. if(optind < argc){
  619. fprintf(stderr, "WARNING: unused command-line arguments. For multiple input files, please apply multiple -i.\n");
  620. fprintf(stderr, "WARNING: try to recognize and add to input files list\n");
  621. for(c=optind;c<argc;c++){
  622. if(file_exists(argv[c])){
  623. fprintf(stderr, " * \"%s\" exists, added.\n", argv[c]);
  624. push_cplist(pbs, argv[c]);
  625. }
  626. }
  627. }
  628. if(prefix == NULL) {
  629. fprintf(stderr, "ERROR: please specify the output prefix with -o\n");
  630. return 1;
  631. }
  632. if(load_seqs == NULL && load_kbm == NULL && pbs->size + ngs->size == 0) {
  633. fprintf(stderr, "ERROR: please specify the input with -i/--load-seqs/--load-kbm\n");
  634. return 1;
  635. }
  636. if((reglen % KBM_BIN_SIZE)){
  637. reglen = ((reglen + KBM_BIN_SIZE - 1) / KBM_BIN_SIZE) * KBM_BIN_SIZE;
  638. fprintf(stderr, " ** Adjust -j to %d\n", reglen);
  639. }
  640. if(!overwrite && file_exists(prefix)){
  641. fprintf(stderr, "File exists! '%s'\n\n", prefix);
  642. return usage(-1);
  643. }
  644. if(max_idx_bp == 0) max_idx_bp = 0xFFFFFFFFFFFFFFFFLLU;
  645. if(preset == -1){
  646. if(genome_size && genome_size < 1000000000LLU){
  647. preset = 2;
  648. } else {
  649. preset = 3;
  650. }
  651. }
  652. switch(preset){
  653. case 1:
  654. if(!(opt_flags & (1 << 1))) par->ksize = 0;
  655. if(!(opt_flags & (1 << 0))) par->psize = 21;
  656. if(!(opt_flags & (1 << 2))) par->kmer_mod = 4 * KBM_N_HASH;
  657. if(!(opt_flags & (1 << 3))) par->min_sim = 0.05;
  658. if(!(opt_flags & (1 << 5))) par->skip_contained = 1;
  659. if(!(opt_flags & (1 << 4))) tidy_reads = 5000;
  660. break;
  661. case 2:
  662. if(!(opt_flags & (1 << 1))) par->ksize = 15;
  663. if(!(opt_flags & (1 << 0))) par->psize = 0;
  664. if(!(opt_flags & (1 << 2))) par->kmer_mod = 2 * KBM_N_HASH;
  665. if(!(opt_flags & (1 << 3))) par->min_sim = 0.05;
  666. if(!(opt_flags & (1 << 5))) par->skip_contained = 0;
  667. if(!(opt_flags & (1 << 4))) tidy_reads = 5000;
  668. break;
  669. case 3:
  670. if(!(opt_flags & (1 << 1))) par->ksize = 0;
  671. if(!(opt_flags & (1 << 0))) par->psize = 19;
  672. if(!(opt_flags & (1 << 2))) par->kmer_mod = 2 * KBM_N_HASH;
  673. if(!(opt_flags & (1 << 3))) par->min_sim = 0.05;
  674. if(!(opt_flags & (1 << 5))) par->skip_contained = 0;
  675. if(!(opt_flags & (1 << 4))) tidy_reads = 5000;
  676. break;
  677. case 4:
  678. if(!(opt_flags & (1 << 1))) par->ksize = 0;
  679. if(!(opt_flags & (1 << 0))) par->psize = 21;
  680. if(!(opt_flags & (1 << 2))) par->kmer_mod = 4 * KBM_N_HASH;
  681. if(!(opt_flags & (1 << 3))) par->min_sim = 0.5;
  682. if(!(opt_flags & (1 << 5))) par->skip_contained = 0;
  683. if(!(opt_flags & (1 << 6))){ par->kmax = 0; par->ktop = 0.05; }
  684. //if(!(opt_flags & (1 << 4))) tidy_reads = 5000;
  685. break;
  686. }
  687. if(par->ksize + par->psize > KBM_MAX_KSIZE){
  688. fprintf(stderr, " -- Invalid kmer size %d+%d=%d > %d in %s -- %s:%d --\n", par->ksize, par->psize, par->ksize + par->psize, KBM_MAX_KSIZE, __FUNCTION__, __FILE__, __LINE__); fflush(stderr);
  689. return 1;
  690. }
  691. if(quiet){
  692. int devnull;
  693. devnull = open("/dev/null", O_WRONLY);
  694. dup2(devnull, STDERR_FILENO);
  695. }
  696. if(tidy_rdtag == -1){
  697. if(tidy_reads >= 0){
  698. tidy_rdtag = 0;
  699. } else {
  700. tidy_rdtag = 1;
  701. }
  702. }
  703. if(tidy_reads < 0) tidy_reads = - tidy_reads;
  704. max_bp *= 1000000;
  705. BEG_STAT_PROC_INFO(stderr, argc, argv);
  706. if(ncpu <= 0 && _sig_proc_deamon) ncpu = _sig_proc_deamon->ncpu;
  707. if(ncpu <= 0){
  708. fprintf(stderr, " -- Invalid cpu number '%d' in %s -- %s:%d --\n", ncpu, __FUNCTION__, __FILE__, __LINE__); fflush(stderr);
  709. return 1;
  710. }
  711. if(load_kbm){
  712. fprintf(KBM_LOGF, "[%s] loading kbm index from %s\n", date(), load_kbm);
  713. if((kbm = mem_find_obj_file(&kbm_obj_desc, load_kbm, NULL, NULL, NULL, NULL, 0)) == NULL){
  714. fprintf(KBM_LOGF, " -- cannot find mmap object %s --\n", load_kbm);
  715. fprintf(KBM_LOGF, " -- try read from file --\n");
  716. kbm = mem_read_obj_file(&kbm_obj_desc, load_kbm, NULL, NULL, NULL, NULL);
  717. }
  718. nfix = 0;
  719. tot_bp = 0;
  720. for(i=0;i<kbm->reads->size;i++) tot_bp += kbm->reads->buffer[i].bincnt * KBM_BIN_SIZE;
  721. fprintf(KBM_LOGF, "[%s] Done. %u sequences, %llu bp, parameter('-S %d')\n", date(), (u4i)kbm->reads->size, tot_bp, kbm->par->kmer_mod / KBM_N_HASH);
  722. {
  723. // check KBMPar
  724. if((opt_flags >> 0) & 0x01){
  725. if(kbm->par->psize != par->psize){
  726. fprintf(KBM_LOGF, " ** -p is different, %d != %d\n", kbm->par->psize, par->psize); exit(1);
  727. }
  728. } else {
  729. par->psize = kbm->par->psize;
  730. }
  731. if((opt_flags >> 1) & 0x01){
  732. if(kbm->par->ksize != par->ksize){
  733. fprintf(KBM_LOGF, " ** -k is different, %d != %d\n", kbm->par->ksize, par->ksize); exit(1);
  734. }
  735. } else {
  736. par->ksize = kbm->par->ksize;
  737. }
  738. if((opt_flags >> 2) & 0x01){
  739. if(kbm->par->kmer_mod != par->kmer_mod){
  740. fprintf(KBM_LOGF, " ** -S is different, %d != %d\n", kbm->par->kmer_mod / KBM_N_HASH, par->kmer_mod / KBM_N_HASH); exit(1);
  741. }
  742. } else {
  743. par->kmer_mod = kbm->par->kmer_mod;
  744. }
  745. if((opt_flags >> 3) & 0x01){
  746. if(kbm->par->rd_len_order != par->rd_len_order){
  747. fprintf(KBM_LOGF, " ** par->rd_len_order is different, %d != %d\n", kbm->par->rd_len_order, par->rd_len_order); exit(1);
  748. }
  749. } else {
  750. par->rd_len_order = kbm->par->rd_len_order;
  751. }
  752. }
  753. } else if(load_seqs){
  754. fprintf(KBM_LOGF, "[%s] loading kbm index from %s\n", date(), load_seqs);
  755. if((kbm = mem_find_obj_file(&kbm_obj_desc, load_seqs, NULL, NULL, NULL, NULL, 0)) == NULL){
  756. fprintf(KBM_LOGF, " -- cannot find mmap object %s --\n", load_seqs);
  757. fprintf(KBM_LOGF, " -- try read from file --\n");
  758. kbm = mem_read_obj_file(&kbm_obj_desc, load_seqs, NULL, NULL, NULL, NULL);
  759. }
  760. kbm = clone_seqs_kbm(kbm, par);
  761. nfix = 0;
  762. tot_bp = 0;
  763. for(i=0;i<kbm->reads->size;i++) tot_bp += kbm->reads->buffer[i].bincnt * KBM_BIN_SIZE;
  764. fprintf(KBM_LOGF, "[%s] Done. %u sequences, %llu bp\n", date(), (u4i)kbm->reads->size, tot_bp);
  765. } else {
  766. kbm = init_kbm(par);
  767. for(i=0;i<2;i++){
  768. if(rdtag_filter[i]){
  769. rdtaghash[i] = init_chash(1023);
  770. fr = open_filereader(rdtag_filter[i], 0);
  771. while(readline_filereader(fr)){
  772. char *str = strdup(fr->line->string);
  773. put_chash(rdtaghash[i], str);
  774. }
  775. close_filereader(fr);
  776. tidy_reads = 0;
  777. } else {
  778. rdtaghash[i] = NULL;
  779. }
  780. }
  781. fprintf(KBM_LOGF, "[%s] loading reads\n", date());
  782. tot_bp = 0;
  783. nfix = 0;
  784. seqs[0] = init_biosequence();
  785. seqs[1] = init_biosequence();
  786. regex_t reg;
  787. regmatch_t mats[3];
  788. int z;
  789. z = regcomp(&reg, "^(.+?)/[0-9]+_[0-9]+$", REG_EXTENDED);
  790. if(z){
  791. regerror(z, &reg, regtag, 13);
  792. fprintf(stderr, " -- REGCOMP: %s --\n", regtag); fflush(stderr);
  793. return 1;
  794. }
  795. for(j=0;j<2;j++){
  796. if(j == 0){
  797. if(ngs->size == 0){
  798. continue;
  799. } else {
  800. fr = open_all_filereader(ngs->size, ngs->buffer, asyn_read);
  801. }
  802. } else {
  803. if(pbs->size == 0){
  804. continue;
  805. } else {
  806. fr = open_all_filereader(pbs->size, pbs->buffer, asyn_read);
  807. }
  808. }
  809. k = 0;
  810. reset_biosequence(seqs[0]);
  811. reset_biosequence(seqs[1]);
  812. while(1){
  813. int has = readseq_filereader(fr, seqs[k]);
  814. if(tidy_reads){
  815. if(has){
  816. if((z = regexec(&reg, seqs[k]->tag->string, 3, mats, 0)) == 0){
  817. trunc_string(seqs[k]->tag, mats[1].rm_eo);
  818. } else if(z != REG_NOMATCH){
  819. regerror(z, &reg, regtag, 13);
  820. fprintf(stderr, " -- REGEXEC: %s --\n", regtag); fflush(stderr);
  821. }
  822. //fprintf(stderr, "1: %s len=%d\n", seqs[k]->tag->string, seqs[k]->seq->size); fflush(stderr);
  823. //fprintf(stderr, "2: %s len=%d\n", seqs[!k]->tag->string, seqs[!k]->seq->size); fflush(stderr);
  824. if(seqs[k]->tag->size == seqs[!k]->tag->size && strcmp(seqs[k]->tag->string, seqs[!k]->tag->string) == 0){
  825. if(seqs[k]->seq->size > seqs[!k]->seq->size){
  826. k = !k;
  827. }
  828. continue;
  829. } else {
  830. seq = seqs[!k];
  831. k = !k;
  832. }
  833. } else {
  834. seq = seqs[!k];
  835. }
  836. if(seq->seq->size < tidy_reads){
  837. if(has) continue;
  838. else break;
  839. }
  840. if(tidy_rdtag){
  841. sprintf(regtag, "S%010llu", (u8i)kbm->reads->size);
  842. clear_string(seq->tag);
  843. append_string(seq->tag, regtag, 11);
  844. }
  845. } else {
  846. if(has == 0) break;
  847. seq = seqs[k];
  848. if(rdtaghash[0]){
  849. if(exists_chash(rdtaghash[0], seq->tag->string)){
  850. continue;
  851. }
  852. }
  853. if(rdtaghash[1]){
  854. if(!exists_chash(rdtaghash[1], seq->tag->string)){
  855. continue;
  856. }
  857. }
  858. }
  859. tag_size = seq->tag->size;
  860. for(i=0;(int)i<seq->seq->size;i+=WT_MAX_RDLEN){
  861. len = num_min(seq->seq->size - i, WT_MAX_RDLEN);
  862. if(i){
  863. append_string(seq->tag, "_V", 2);
  864. add_int_string(seq->tag, i / WT_MAX_RDLEN);
  865. }
  866. if(!KBM_LOG && (kbm->reads->size % 10000) == 0){ fprintf(KBM_LOGF, "\r%u", (u4i)kbm->reads->size); fflush(KBM_LOGF); }
  867. //fprintf(stderr, " -- %s len=%d in %s -- %s:%d --\n", seq->tag->string, seq->seq->size, __FUNCTION__, __FILE__, __LINE__); fflush(stderr);
  868. if(kbm->reads->size >= WT_MAX_RD){
  869. fprintf(stderr, " -- Read Number Out of Range: %u --\n", (u4i)kbm->reads->size); fflush(stderr);
  870. break;
  871. }
  872. push_kbm(kbm, seq->tag->string, seq->tag->size, seq->seq->string + i, len);
  873. if(i){ seq->tag->size = tag_size; seq->tag->string[tag_size] = '\0'; }
  874. if(j == 0) nfix ++;
  875. }
  876. tot_bp += seq->seq->size;
  877. if(max_bp && tot_bp >= max_bp){ break; }
  878. if(has == 0) break;
  879. if(kbm->reads->size >= WT_MAX_RD){
  880. fprintf(stderr, " -- Read Number Out of Range: %u --\n", (u4i)kbm->reads->size); fflush(stderr);
  881. break;
  882. }
  883. }
  884. close_filereader(fr);
  885. for(i=0;i<2;i++){
  886. if(rdtaghash[i]){
  887. char **str;
  888. reset_iter_chash(rdtaghash[i]);
  889. while((str = ref_iter_chash(rdtaghash[i]))){
  890. free(*str);
  891. }
  892. free_chash(rdtaghash[i]);
  893. }
  894. }
  895. }
  896. regfree(&reg);
  897. free_biosequence(seqs[0]);
  898. free_biosequence(seqs[1]);
  899. if(!KBM_LOG){ fprintf(KBM_LOGF, "\r%u reads", (unsigned)kbm->reads->size); fflush(KBM_LOGF); }
  900. {
  901. if(par->rd_len_order && genome_size > 0 && genome_depx > 0){
  902. cnt = genome_size * genome_depx;
  903. if(cnt < tot_bp){
  904. fprintf(KBM_LOGF, "\n[%s] filtering from %u reads (>=%u bp), %llu bp. Try selecting %llu bp", date(), (unsigned)kbm->reads->size, tidy_reads, tot_bp, cnt); fflush(KBM_LOGF);
  905. tot_bp = filter_reads_kbm(kbm, cnt, filter_rd_strategy);
  906. }
  907. }
  908. ready_kbm(kbm);
  909. fprintf(KBM_LOGF, "\n[%s] Done, %u reads (>=%u bp), %llu bp, %u bins\n", date(), (unsigned)kbm->reads->size, tidy_reads, tot_bp, (u4i)kbm->bins->size); fflush(KBM_LOGF);
  910. if(dump_seqs){
  911. FILE *dump;
  912. fprintf(KBM_LOGF, "[%s] dump kbm-index (only seqs) to %s ...", date(), dump_seqs); fflush(KBM_LOGF);
  913. dump = open_file_for_write(dump_seqs, NULL, 1);
  914. mem_dump_obj_file(kbm, 1, &kbm_obj_desc, 1, 0, dump);
  915. fclose(dump);
  916. fprintf(KBM_LOGF, " Done\n"); fflush(KBM_LOGF);
  917. }
  918. }
  919. }
  920. print_proc_stat_info(g_mpi_comm_rank);
  921. if(edge_cov <= 0){
  922. if(genome_size > 0){
  923. float dep;
  924. dep = tot_bp / genome_size;
  925. if(dep <= 40){
  926. edge_cov = 2;
  927. } else if(dep >= 80){
  928. edge_cov = 4;
  929. } else {
  930. edge_cov = 3;
  931. }
  932. } else {
  933. edge_cov = 3;
  934. }
  935. fprintf(KBM_LOGF, "[%s] Set --edge-cov to %d\n", date(), edge_cov); fflush(KBM_LOGF);
  936. }
  937. //if(genome_size <= 0 && corr_mode > 0){
  938. //fprintf(KBM_LOGF, "[%s] MUST set -g <?> with --corr-mode %f\n", date(), corr_mode); fflush(KBM_LOGF);
  939. //return 1;
  940. //}
  941. if(node_cov == 0) node_cov = edge_cov;
  942. fprintf(KBM_LOGF, "KEY PARAMETERS: -k %d -p %d -K %f %s-S %f -s %f -g %llu -X %f -e %d -L %d\n",
  943. par->ksize, par->psize, par->kmax + par->ktop, par->skip_contained? "" : "-A ", ((double)par->kmer_mod) / KBM_N_HASH, par->min_sim, (u8i)genome_size, genome_depx, edge_cov, tidy_reads);
  944. g = init_graph(kbm);
  945. {
  946. g->rpar = realign? rpar : NULL;
  947. g->genome_size = genome_size;
  948. g->num_index = (g_mpi_comm_size >= 2) ? (g_mpi_comm_size - 1) : num_index; // 除第一个mpi进程外,其他进程将参与分布计算 ningwenmo@outlook.com
  949. //g->corr_mode = (corr_mode > 0 && genome_size > 0)? 1 : 0;
  950. //g->corr_gcov = corr_mode;
  951. //g->corr_min = corr_min;
  952. //g->corr_max = corr_max;
  953. //g->corr_cov = corr_cov;
  954. //g->corr_bsize = corr_bsize;
  955. //g->corr_bstep = corr_bstep;
  956. g->node_order = node_order;
  957. g->mem_stingy = mem_stingy;
  958. g->reglen = reglen / KBM_BIN_SIZE;
  959. g->regovl = regovl / KBM_BIN_SIZE;
  960. g->max_overhang = max_overhang / KBM_BIN_SIZE;
  961. g->node_max_conflict = node_drop;
  962. g->node_merge_cutoff = node_mrg;
  963. g->min_node_cov = node_cov;
  964. g->max_node_cov_sg = node_cov;
  965. g->max_node_cov = max_node_cov;
  966. g->exp_node_cov = exp_node_cov;
  967. g->min_node_mats = min_bins;
  968. g->min_edge_cov = edge_cov;
  969. g->max_edge_span = edge_span;
  970. g->max_sg_end = max_trace_end;
  971. g->store_low_cov_edge = store_low_cov_edge;
  972. g->bub_step = bub_step;
  973. g->tip_step = tip_step;
  974. g->rep_step = rep_step;
  975. g->min_ctg_len = min_ctg_len;
  976. g->min_ctg_nds = min_ctg_nds;
  977. g->n_fix = nfix;
  978. g->only_fix = only_fix;
  979. g->rep_filter = rep_filter;
  980. g->rep_detach = rep_detach;
  981. g->cut_tip = cut_tip;
  982. g->chainning_hits = chainning;
  983. g->uniq_hit = uniq_hit;
  984. g->bestn = bestn;
  985. g->minimal_output = less_out;
  986. }
  987. g->par = par;
  988. // master节点将等待每个分布计算节点完成,并同步加载各节点alignments ningwenmo@outlook.com
  989. if (g_mpi_comm_size >= 2 && g_mpi_comm_rank == 0){
  990. int i ;
  991. for (i= 1; i < g_mpi_comm_size; i++){
  992. char *alignments_file_name = malloc(strlen(prefix) + 24);
  993. sprintf(alignments_file_name, "%s.%u_%u.alignments", prefix, i, g_mpi_comm_size);
  994. push_cplist(pws, alignments_file_name);
  995. }
  996. MPI_Status status;
  997. int message;
  998. for (i = 1; i < g_mpi_comm_size; i++)
  999. {
  1000. MPI_Recv(&message, 1, MPI_INT, i, 1, MPI_COMM_WORLD, &status);
  1001. fprintf(KBM_LOGF, "[%s] recv %u/%u\n", date(), i, g_mpi_comm_size);
  1002. fflush(KBM_LOGF);
  1003. }
  1004. }
  1005. if(log_rep && !less_out){
  1006. evtlog = open_file_for_write(prefix, ".events", 1);
  1007. } else evtlog = NULL;
  1008. if(load_nodes && load_clips){
  1009. fprintf(KBM_LOGF, "[%s] loading nodes from %s ... ", date(), load_nodes); fflush(KBM_LOGF);
  1010. FileReader *clp = open_filereader(load_clips, asyn_read);
  1011. FileReader *nds = open_filereader(load_nodes, asyn_read);
  1012. load_nodes_graph(g, clp, nds);
  1013. close_filereader(clp);
  1014. close_filereader(nds);
  1015. fprintf(KBM_LOGF, " %llu nodes\n", (u8i)g->nodes->size);
  1016. print_proc_stat_info(g_mpi_comm_rank);
  1017. } else if(pws->size){
  1018. fprintf(KBM_LOGF, "[%s] loading alignments from ", date());
  1019. for(i=0;i<pws->size;i++){
  1020. if(i){
  1021. fprintf(KBM_LOGF, ",\"%s\"", pws->buffer[i]);
  1022. } else {
  1023. fprintf(KBM_LOGF, "\"%s\"", pws->buffer[i]);
  1024. }
  1025. }
  1026. fprintf(KBM_LOGF, "\n");
  1027. fr = open_all_filereader(pws->size, pws->buffer, asyn_read);
  1028. build_nodes_graph(g, max_idx_bp, ncpu, fr, rdclip, prefix, NULL);
  1029. close_filereader(fr);
  1030. fprintf(KBM_LOGF, "[%s] Done, %llu nodes\n", date(), (unsigned long long)g->nodes->size);
  1031. } else {
  1032. fprintf(KBM_LOGF, "[%s] generating nodes, %d threads\n", date(), ncpu);
  1033. build_nodes_graph(g, max_idx_bp, ncpu, NULL, rdclip, prefix, dump_kbm);
  1034. fprintf(KBM_LOGF, "[%s] Done, %llu nodes\n", date(), (unsigned long long)g->nodes->size);
  1035. }
  1036. // 各计算节点在分布计算完成后,通知master节点并立刻退出 ningwenmo@outlook.com
  1037. if (g_mpi_comm_size >= 2 && g_mpi_comm_rank != 0){
  1038. int message = 0;
  1039. MPI_Send(&message, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
  1040. fprintf(KBM_LOGF, "[%s] send %u/%u\n", date(), g_mpi_comm_rank, g_mpi_comm_size);
  1041. fflush(KBM_LOGF);
  1042. goto MPI_END;
  1043. }
  1044. if(load_nodes == NULL || strlen(load_nodes) != strlen(prefix) + strlen(".1.nodes") || strncmp(load_nodes, prefix, strlen(prefix)) || strcmp(load_nodes + strlen(prefix), ".1.nodes")){
  1045. generic_print_graph(g, print_nodes_graph, prefix, ".1.nodes");
  1046. }
  1047. if(1){
  1048. estimate_genome_size(g, tot_bp, KBM_LOGF);
  1049. cnt = mask_nodes_by_cov_graph(g, evtlog);
  1050. fprintf(KBM_LOGF, "[%s] masked %llu high coverage nodes (>%d or <%d)\n", date(), (unsigned long long)cnt, max_node_cov, node_cov);
  1051. }
  1052. if(cnn_filter){
  1053. cnt = mask_nodes_by_connectivity_graph(g, ncpu, evtlog);
  1054. fprintf(KBM_LOGF, "[%s] masked %llu repeat-like nodes by local subgraph analysis\n", date(), (unsigned long long)cnt);
  1055. }
  1056. if(tip_like){
  1057. cnt = mask_possible_tip_nodes_graph(g);
  1058. fprintf(KBM_LOGF, "[%s] masked %llu tip-like nodes\n", date(), (unsigned long long)cnt);
  1059. }
  1060. fprintf(KBM_LOGF, "[%s] generating edges\n", date());
  1061. build_edges_graph(g, ncpu, evtlog);
  1062. fprintf(KBM_LOGF, "[%s] Done, %llu edges\n", date(), (unsigned long long)g->edges->size);
  1063. if(ttr_n_cov){
  1064. //print_node_edges_cov_graph(g, evtlog);
  1065. cnt = mask_nodes_by_edge_cov_graph(g, ttr_n_cov, ttr_e_cov, evtlog);
  1066. fprintf(KBM_LOGF, "[%s] deleted %llu nodes, might be tandom repeats\n", date(), (unsigned long long)cnt);
  1067. }
  1068. if(!less_out) generic_print_graph(g, print_reads_graph, prefix, ".1.reads");
  1069. if(!less_out) generic_print_graph(g, print_dot_full_graph, prefix, ".1.dot.gz");
  1070. fprintf(KBM_LOGF, "[%s] graph clean\n", date()); fflush(KBM_LOGF);
  1071. if(0){
  1072. cnt = mask_read_weak_regs_graph(g, ncpu);
  1073. fprintf(KBM_LOGF, "[%s] masked %llu regions(%d bp) as unreliable, total regs %llu\n", date(), (unsigned long long)cnt, reglen, (u8i)g->regs->size);
  1074. }
  1075. if(cut_low_edges){
  1076. cnt = cut_relative_low_cov_edges_graph(g, cut_low_edges);
  1077. fprintf(KBM_LOGF, "[%s] cut %llu low cov edges\n", date(), (unsigned long long)cnt);
  1078. }
  1079. if(rescue_low_edges){
  1080. //cnt = rescue_low_cov_tip_edges_graph(g);
  1081. //cnt = rescue_low_cov_edges_graph(g);
  1082. cnt = rescue_mercy_edges_graph(g);
  1083. fprintf(KBM_LOGF, "[%s] rescued %llu low cov edges\n", date(), (unsigned long long)cnt);
  1084. }
  1085. cnt = cut_binary_edges_graph(g);
  1086. fprintf(KBM_LOGF, "[%s] deleted %llu binary edges\n", date(), (unsigned long long)cnt);
  1087. if(!g->rep_detach && del_iso){
  1088. cnt = del_isolated_nodes_graph(g, evtlog);
  1089. fprintf(KBM_LOGF, "[%s] deleted %llu isolated nodes\n", date(), (unsigned long long)cnt);
  1090. }
  1091. //cnt = reduce_transitive_edges_graph(g);
  1092. cnt = myers_transitive_reduction_graph(g, 1.2f);
  1093. set_init_ends_graph(g);
  1094. fprintf(KBM_LOGF, "[%s] cut %llu transitive edges\n", date(), (unsigned long long)cnt);
  1095. if(del_iso){
  1096. cnt = del_isolated_nodes_graph(g, evtlog);
  1097. if(cnt){
  1098. fprintf(KBM_LOGF, "[%s] deleted %llu isolated nodes\n", date(), (unsigned long long)cnt);
  1099. }
  1100. }
  1101. if(!less_out) generic_print_graph(g, print_dot_graph, prefix, ".2.dot.gz");
  1102. {
  1103. bub = tip = rep = yarn = 0;
  1104. u8i high = 0;
  1105. int safe = 1;
  1106. do {
  1107. c = 0;
  1108. do {
  1109. cnt = trim_tips_graph(g, tip_step, bub > 0);
  1110. tip += cnt;
  1111. if(cnt) c = 1;
  1112. } while(cnt);
  1113. do {
  1114. cnt = pop_bubbles_graph(g, bub_step, safe);
  1115. bub += cnt;
  1116. if(cnt) c = 1;
  1117. } while(cnt);
  1118. do {
  1119. cnt = trim_blunt_tips_graph(g);
  1120. tip += cnt;
  1121. if(cnt) c = 1;
  1122. } while(cnt);
  1123. do {
  1124. cnt = pop_bubbles_graph(g, bub_step, safe);
  1125. bub += cnt;
  1126. if(cnt) c = 1;
  1127. } while(cnt);
  1128. if(c) continue;
  1129. if(safe == 1){
  1130. safe = 0;
  1131. c = 1;
  1132. continue;
  1133. }
  1134. do {
  1135. cnt = resolve_yarns_graph(g, bub_step * 5);
  1136. yarn += cnt;
  1137. if(cnt) c = 1;
  1138. } while(cnt);
  1139. } while(c);
  1140. do {
  1141. c = 0;
  1142. cnt = rescue_high_cov_edges_graph(g, 2, 20);
  1143. if(cnt){
  1144. high += cnt;
  1145. c = 1;
  1146. }
  1147. } while(c);
  1148. if(bub + tip + high){ fprintf(KBM_LOGF, "[%s] %llu bubbles; %llu tips; %llu yarns; rescued %llu high edges\n", date(), bub, tip, yarn, high); fflush(KBM_LOGF); }
  1149. //if(bub + tip + yarn){ fprintf(KBM_LOGF, "[%s] %llu bubbles; %llu tips; %llu yarns\n", date(), bub, tip, yarn); fflush(KBM_LOGF); }
  1150. }
  1151. if(del_iso){
  1152. cnt = del_isolated_nodes_graph(g, evtlog);
  1153. fprintf(KBM_LOGF, "[%s] deleted %llu isolated nodes\n", date(), (unsigned long long)cnt);
  1154. }
  1155. if(!less_out) generic_print_graph(g, print_dot_graph, prefix, ".3.dot.gz");
  1156. rep = mask_all_branching_nodes_graph(g);
  1157. fprintf(KBM_LOGF, "[%s] cut %llu branching nodes\n", date(), rep);
  1158. if(del_iso){
  1159. cnt = del_isolated_nodes_graph(g, evtlog);
  1160. fprintf(KBM_LOGF, "[%s] deleted %llu isolated nodes\n", date(), (unsigned long long)cnt);
  1161. }
  1162. fprintf(KBM_LOGF, "[%s] building unitigs\n", date());
  1163. gen_unitigs_graph(g);
  1164. //fprintf(KBM_LOGF, "[%s] trimming and extending unitigs by local assembly, %d threads\n", date(), ncpu);
  1165. unitigs2frgs_graph(g, ncpu);
  1166. if(!less_out) generic_print_graph(g, print_frgs_nodes_graph, prefix, ".frg.nodes");
  1167. fprintf(KBM_LOGF, "[%s] generating links\n", date());
  1168. cnt = gen_lnks_graph(g, ncpu, evtlog);
  1169. fprintf(KBM_LOGF, "[%s] generated %llu links\n", date(), cnt);
  1170. if(!less_out) generic_print_graph(g, print_frgs_dot_graph, prefix, ".frg.dot.gz");
  1171. if(1){
  1172. cnt = rescue_weak_tip_lnks_graph(g);
  1173. fprintf(KBM_LOGF, "[%s] rescue %llu weak links\n", date(), (unsigned long long)cnt);
  1174. }
  1175. cnt = cut_binary_lnks_graph(g, evtlog);
  1176. fprintf(KBM_LOGF, "[%s] deleted %llu binary links\n", date(), (unsigned long long)cnt);
  1177. //cnt = reduce_transitive_lnks_graph(g);
  1178. cnt = myers_transitive_reduction_frg_graph(g, 10000.1f / KBM_BIN_SIZE);
  1179. fprintf(KBM_LOGF, "[%s] cut %llu transitive links\n", date(), (unsigned long long)cnt);
  1180. cnt = remove_boomerangs_frg_graph(g, 30 * 1000 / KBM_BIN_SIZE);
  1181. fprintf(KBM_LOGF, "[%s] remove %llu boomerangs\n", date(), (unsigned long long)cnt);
  1182. cnt = cut_weak_branches_frg_graph(g);
  1183. fprintf(KBM_LOGF, "[%s] remove %llu weak branches\n", date(), (unsigned long long)cnt);
  1184. //cnt = cut_low_cov_lnks_graph(g, 1);
  1185. //fprintf(KBM_LOGF, "[%s] deleted %llu low cov links\n", date(), (unsigned long long)cnt);
  1186. //if(!less_out) generic_print_graph(g, print_frgs_dot_graph, prefix, ".frg.2.dot");
  1187. cnt = trim_frgtips_graph(g, frgtip_len);
  1188. fprintf(KBM_LOGF, "[%s] cut %llu tips\n", date(), (unsigned long long)cnt);
  1189. //if(!less_out) generic_print_graph(g, print_frgs_dot_graph, prefix, ".frg.3.dot");
  1190. bub = 0;
  1191. do {
  1192. cnt = pop_frg_bubbles_graph(g, bub_step);
  1193. bub += cnt;
  1194. } while(cnt);
  1195. fprintf(KBM_LOGF, "[%s] pop %llu bubbles\n", date(), bub);
  1196. {
  1197. cnt = 0;
  1198. while(1){
  1199. u8i c;
  1200. if((c = detach_repetitive_frg_graph(g, 100 * 1000 / KBM_BIN_SIZE)) == 0){
  1201. break;
  1202. }
  1203. cnt += c;
  1204. }
  1205. fprintf(KBM_LOGF, "[%s] detached %llu repeat-associated paths\n", date(), (unsigned long long)cnt);
  1206. }
  1207. cnt = trim_frgtips_graph(g, frgtip_len);
  1208. fprintf(KBM_LOGF, "[%s] cut %llu tips\n", date(), (unsigned long long)cnt);
  1209. if(!less_out) generic_print_graph(g, print_frgs_dot_graph, prefix, ".ctg.dot.gz");
  1210. fprintf(KBM_LOGF, "[%s] building contigs\n", date());
  1211. cnt = gen_contigs_graph(g, evtlog);
  1212. fprintf(KBM_LOGF, "[%s] searched %llu contigs\n", date(), (unsigned long long)cnt);
  1213. if(0){
  1214. cnt = gen_complex_contigs_graph(g);
  1215. u8i sum;
  1216. seqletv *qs;
  1217. sum = 0;
  1218. for(i=g->major_nctg;i<g->ctgs->size;i++){
  1219. qs = (seqletv*)get_vplist(g->ctgs, i);
  1220. sum += qs->buffer[qs->size - 1].off + qs->buffer[qs->size - 1].len;
  1221. }
  1222. fprintf(KBM_LOGF, "[%s] added %llu unsolved repetitive contigs, %llu bp\n", date(), (unsigned long long)cnt, sum);
  1223. }
  1224. n50_stat_contigs_graph(g);
  1225. //cnt = generic_print_graph(g, print_isolated_nodes_dot_graph, prefix, ".4.dot");
  1226. //fprintf(KBM_LOGF, "[%s] %llu nodes not in contigs\n", date(), (unsigned long long)cnt);
  1227. //cnt = count_isolated_reads_graph(g);
  1228. //fprintf(KBM_LOGF, "[%s] %llu reads not in contigs\n", date(), (unsigned long long)cnt);
  1229. cnt = print_ctgs_graph(g, 0, 0, g->major_nctg, prefix, ".ctg.lay.gz", ncpu, evtlog);
  1230. if(0){
  1231. fprintf(KBM_LOGF, "[%s] outputing reptigs\n", date());
  1232. cnt = print_ctgs_graph(g, cnt, g->major_nctg, g->ctgs->size, prefix, ".rtg.lay", ncpu, evtlog);
  1233. }
  1234. MPI_END:
  1235. if(evtlog) fclose(evtlog);
  1236. free_cplist(pbs);
  1237. free_cplist(ngs);
  1238. free_cplist(pws);
  1239. if(load_kbm == NULL) free_kbm(kbm);
  1240. free_kbmpar(par);
  1241. free_kbmpar(rpar);
  1242. free_graph(g);
  1243. fprintf(KBM_LOGF, "[%s] Program Done\n", date());
  1244. END_STAT_PROC_INFO(stderr);
  1245. /* All done */
  1246. MPI_Finalize();
  1247. return 0;
  1248. }