<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article
  PUBLIC "-//NLM//DTD Journal Publishing DTD v3.0 20080202//EN" "http://dtd.nlm.nih.gov/publishing/3.0/journalpublishing3.dtd">
<article xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" article-type="research-article" dtd-version="3.0" xml:lang="EN">
  <front>
    <journal-meta><journal-id journal-id-type="nlm-ta">PLoS ONE</journal-id><journal-id journal-id-type="publisher-id">plos</journal-id><journal-id journal-id-type="pmc">plosone</journal-id><!--===== Grouping journal title elements =====--><journal-title-group><journal-title>PLoS ONE</journal-title></journal-title-group><issn pub-type="epub">1932-6203</issn><publisher>
        <publisher-name>Public Library of Science</publisher-name>
        <publisher-loc>San Francisco, USA</publisher-loc>
      </publisher></journal-meta>
    <article-meta><article-id pub-id-type="publisher-id">PONE-D-12-05176</article-id><article-id pub-id-type="doi">10.1371/journal.pone.0039232</article-id><article-categories>
        <subj-group subj-group-type="heading">
          <subject>Research Article</subject>
        </subj-group>
        <subj-group subj-group-type="Discipline-v2">
          <subject>Biology</subject>
          <subj-group>
            <subject>Computational biology</subject>
            <subj-group>
              <subject>Genomics</subject>
              <subj-group>
                <subject>Genome analysis tools</subject>
                <subj-group>
                  <subject>Sequence assembly tools</subject>
                </subj-group>
              </subj-group>
              <subj-group>
                <subject>Genome sequencing</subject>
              </subj-group>
            </subj-group>
            <subj-group>
              <subject>Sequence analysis</subject>
            </subj-group>
          </subj-group>
          <subj-group>
            <subject>Genomics</subject>
            <subj-group>
              <subject>Genome analysis tools</subject>
              <subj-group>
                <subject>Sequence assembly tools</subject>
              </subj-group>
            </subj-group>
          </subj-group>
        </subj-group>
        <subj-group subj-group-type="Discipline-v2">
          <subject>Computer science</subject>
          <subj-group>
            <subject>Computer architecture</subject>
            <subj-group>
              <subject>Computer hardware</subject>
            </subj-group>
          </subj-group>
          <subj-group>
            <subject>Computing methods</subject>
          </subj-group>
          <subj-group>
            <subject>Computing systems</subject>
            <subj-group>
              <subject>Digital computing</subject>
            </subj-group>
          </subj-group>
        </subj-group>
        <subj-group subj-group-type="Discipline">
          <subject>Genetics and Genomics</subject>
          <subject>Computational Biology</subject>
          <subject>Computer Science</subject>
        </subj-group>
      </article-categories><title-group><article-title>ccTSA: A Coverage-Centric Threaded Sequence Assembler</article-title><alt-title alt-title-type="running-head">A Coverage-Centric Threaded Sequence Assembler</alt-title></title-group><contrib-group>
        <contrib contrib-type="author" xlink:type="simple">
          <name name-style="western">
            <surname>Ahn</surname>
            <given-names>Jung Ho</given-names>
          </name>
          <xref ref-type="aff" rid="aff1"/>
          <xref ref-type="corresp" rid="cor1">
            <sup>*</sup>
          </xref>
        </contrib>
      </contrib-group><aff id="aff1">          <addr-line>Department of Intelligent Convergence Systems, Seoul National University, Seoul, Republic of Korea</addr-line>       </aff><contrib-group>
        <contrib contrib-type="editor" xlink:type="simple">
          <name name-style="western">
            <surname>Kingsford</surname>
            <given-names>Carl</given-names>
          </name>
          <role>Editor</role>
          <xref ref-type="aff" rid="edit1"/>
        </contrib>
      </contrib-group><aff id="edit1">University of Maryland, United States of America</aff><author-notes>
        <corresp id="cor1">* E-mail: <email xlink:type="simple">gajh@snu.ac.kr</email></corresp>
        <fn fn-type="con">
          <p>Conceived and designed the experiments: JA. Performed the experiments: JA. Analyzed the data: JA. Contributed reagents/materials/analysis tools: JA. Wrote the paper: JA.</p>
        </fn>
      <fn fn-type="conflict">
        <p>The authors have declared that no competing interests exist.</p>
      </fn></author-notes><pub-date pub-type="collection">
        <year>2012</year>
      </pub-date><pub-date pub-type="epub">
        <day>19</day>
        <month>6</month>
        <year>2012</year>
      </pub-date><volume>7</volume><issue>6</issue><elocation-id>e39232</elocation-id><history>
        <date date-type="received">
          <day>21</day>
          <month>2</month>
          <year>2012</year>
        </date>
        <date date-type="accepted">
          <day>21</day>
          <month>5</month>
          <year>2012</year>
        </date>
      </history><!--===== Grouping copyright info into permissions =====--><permissions><copyright-year>2012</copyright-year><copyright-holder>Jung Ho Ahn</copyright-holder><license><license-p>This is an open-access article distributed under the terms of the Creative Commons Attribution License, which permits unrestricted use, distribution, and reproduction in any medium, provided the original author and source are credited.</license-p></license></permissions><abstract>
        <p>De novo sequencing, a process to find the whole genome or the regions of a species without references, requires much higher computational power compared to mapped sequencing with references. The advent and continuous evolution of next-generation sequencing technologies further stress the demands of high-throughput processing of myriads of short DNA fragments. Recently announced sequence assemblers, such as Velvet, SOAPdenovo, and ABySS, all exploit parallelism to meet these computational demands since contemporary computer systems primarily rely on scaling the number of computing cores to improve performance. However, most of them are not tailored to exploit the full potential of these systems, leading to suboptimal performance. In this paper, we present ccTSA, a parallel sequence assembler that utilizes coverage to prune k-mers, find preferred edges, and resolve conflicts in preferred edges between k-mers. We minimize computation dependencies between threads to effectively parallelize k-mer processing. We also judiciously allocate and reuse memory space in order to lower memory usage and further improve sequencing speed. The results of ccTSA are compelling such that it runs several times faster than other assemblers while providing comparable quality values such as N50.</p>
      </abstract><funding-group><funding-statement>This work was supported by the Seoul National University Brain Fusion Program Research Grant. The funders had no role in study design, data collection and analysis, decision to publish, or preparation of the manuscript.</funding-statement></funding-group><counts>
        <page-count count="13"/>
      </counts></article-meta>
  </front>
  <body>
    <sec id="s1">
      <title>Introduction</title>
      <p>Sequence assembly is a process of aligning and merging the fragments of a DNA sequence to reconstruct the original one, which is an important part of bioinformatics <xref ref-type="bibr" rid="pone.0039232-Miller1">[1]</xref>. It can be categorized into two types, mapped and de-novo assembly. The mapped assembly has a reference sequence for the fragments to be assembled, while the de-novo assembly does not. A de-novo assembler is used to find the complete DNA sequence of an organism without a reference genome and to assemble some parts of the sequence that are largely different from the reference. The lack of a reference sequence makes a de-novo assembler demand much higher computational power than a mapped assembler to assemble the same amount of fragments <xref ref-type="bibr" rid="pone.0039232-Miller1">[1]</xref>, <xref ref-type="bibr" rid="pone.0039232-Butler1">[2]</xref>.</p>
      <p>The advent and continuous evolution of next-generation sequencing (NGS) machines enable the high-throughput sequencing of short DNA fragments called reads <xref ref-type="bibr" rid="pone.0039232-Elaine1">[3]</xref>, <xref ref-type="bibr" rid="pone.0039232-Salzberg1">[4]</xref>, whose length is typically in the range of dozens to low hundreds of base pairs. Traditional assembly methods, such as Smith-Waterman algorithm <xref ref-type="bibr" rid="pone.0039232-Smith1">[5]</xref>, are not suitable to process these massive data effectively. Instead, recently announced sequence assemblers such as Velvet <xref ref-type="bibr" rid="pone.0039232-Daniel1">[6]</xref>, ABySS <xref ref-type="bibr" rid="pone.0039232-Simpson1">[7]</xref>, and SOAPdenovo <xref ref-type="bibr" rid="pone.0039232-Li1">[8]</xref> extract fixed length k-mers from the reads and build de Bruijn graphs using the k-mers. These assemblers <xref ref-type="bibr" rid="pone.0039232-Daniel1">[6]</xref>–<xref ref-type="bibr" rid="pone.0039232-Wenyu1">[10]</xref> are all parallelized in order to meet the computational demands of de-novo assembly. It is because contemporary computer systems primarily rely on scaling the number of computing cores to improve performance <xref ref-type="bibr" rid="pone.0039232-Hennessy1">[11]</xref>. A system with dozens of cores and terabytes of shared memory was available only as a supercomputer and excessively expensive before, but now it is even cheaper than a sequencing machine.</p>
      <p>Even though the parallel versions of these assemblers provide a noticeable improvement in assembly speed, those are not tailored to exploit the full potential of modern computer systems. They either statically divide workload to computing cores or assume message passing between cores. Even if the reads are evenly distributed across the cores, the time taken to build and access a data structure that is storing k-mers heavily depends on the distribution of the k-mer values extracted from the reads as well as the memory system architecture of the computer systems. This can lead to a huge load imbalance problem across the cores <xref ref-type="bibr" rid="pone.0039232-Culler1">[12]</xref>. Message passing has been a technique primarily for programs on a cluster of computers connected over a network, where the access latency and communication throughput over the network are an order of magnitude worse than those over shared memory on multithreaded programs <xref ref-type="bibr" rid="pone.0039232-Culler1">[12]</xref>. Because a de-novo assembler is a memory intensive application, an application designed for a message passing system typically does not perform effectively on a shared-memory system. These all lead to suboptimal performance.</p>
      <p>In this paper, we introduce ccTSA, a coverage-centric threaded sequence assembler, which is written in C++. It utilizes k-mer coverage, the number of k-mer instances in the DNA fragments, in building a k-mer coverage table, pruning k-mers from the table, finding preferred edges in the de Bruijn graph <xref ref-type="bibr" rid="pone.0039232-Pevzner1">[13]</xref> made of k-mer nodes, and resolving conflicts between the preferred edges. It exploits the high-throughput and low-latency memory access characteristics of modern shared-memory systems by spawning multiple worker threads and making them access data structures concurrently in the shared memory. In order to reduce memory usage, ccTSA extensively utilizes bit fields, implements a custom memory allocator <xref ref-type="bibr" rid="pone.0039232-Berger1">[14]</xref>, and has an option to prune low coverage k-mers in the middle of building the k-mer coverage table, which provides a tradeoff between the memory footprint and assembly quality. The modular structure and careful design make ccTSA run faster and have better scalability in sequencing speed than other sequence assemblers, while providing comparable memory usage and quality values such as N50.</p>
    </sec>
    <sec id="s2">
      <title>Results and Discussion</title>
      <p>We compared the performance (sequencing speed and memory usage) and quality (such as N50 and NG50) of ccTSA with other sequence assemblers using synthetic reads from 4 organisms and real paired-end reads from 2 organisms. First, synthetic reads were used for comparison, which enabled the results of the assemblers to be compared to the original sequence. The scalability of sequencing speed on ccTSA and other assemblers were evaluated. We utilized the evaluation framework of GAGE <xref ref-type="bibr" rid="pone.0039232-Salzberg1">[4]</xref> to compare the quality of the assemblers using 2 whole-genome shotgun paired-end data. We also explored one of the ccTSA’s interesting features that provides the tradeoff between memory usage and assembly quality by pruning low coverage k-mers in the middle, not at the end, of building a k-mer coverage table.</p>
      <sec id="s2a">
        <title>Experimental Setup</title>
        <p>As for the synthetic reads, we used the datasets of 4 organisms: C.elegans (Caenorhabditis elegans), E.coli (Escherichia coli strain K-12), L.major (Leishmania major strain Friedlin), and S.cerevisiae (Saccharomyces cerevisiae S288c). The reference genome of each organism was downloaded from NCBI Genome Sequence (<xref ref-type="table" rid="pone-0039232-t001">Table 1</xref>, <xref ref-type="supplementary-material" rid="pone.0039232.s002">1</xref>, and <xref ref-type="supplementary-material" rid="pone.0039232.s003">S2</xref>). MetaSim <xref ref-type="bibr" rid="pone.0039232-Richter1">[15]</xref> was used to generate synthetic reads for each reference genome. MetaSim provides options to choose a read length, an average sequence coverage value, and an empirical error model. The sequence coverage stands for how many times a nucleotide in the original sequence (the genome of an organism in our study) appears at the reads. We set the read length to either 36 or 75 base pairs (bps), the sequence coverage to 10, 20, 40, 80, or 160, and the empirical error model to either error free (Exact) or an error model for the short reads of the Illumina technology (Illumina). We used the error model included in MetaSim for the error probabilities of 36 bp reads and the one from Plantagora <xref ref-type="bibr" rid="pone.0039232-Plantagora1">[16]</xref> for the probabilities of 75 bp reads. For example, a dataset ‘E.coli-Illumina-<bold>75</bold> bp-80x’ consists of a sequence of reads from the E.coli reference genome with the sequence coverage of 80, each of which has 75 base pairs, and following the Illumina error probability model. All simulation parameters of MetaSim are listed in <xref ref-type="supplementary-material" rid="pone.0039232.s004">Table S3</xref>. ccTSA relies on separate scaffolding tools to orient and align the contigs into super-contigs or scaffolds. In order to fairly compare the performance and quality of the assemblers, we configured each assembler to treat the synthetic sequences as single-end reads, and excluded scaffolding and gap closure parts from comparison even though MetaSim generated paired-end data.</p>
        <table-wrap id="pone-0039232-t001" position="float"><object-id pub-id-type="doi">10.1371/journal.pone.0039232.t001</object-id><label>Table 1</label><caption>
            <title>Reference genome datasets downloaded from NCBI Genome Sequence.</title>
          </caption><!--===== Grouping alternate versions of objects =====--><alternatives><graphic id="pone-0039232-t001-1" mimetype="image" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.t001" xlink:type="simple"/><table>
            <colgroup span="1">
              <col align="left" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
            </colgroup>
            <thead>
              <tr>
                <td align="left" colspan="1" rowspan="1">TaxonomyID</td>
                <td align="left" colspan="1" rowspan="1">Name</td>
                <td align="left" colspan="1" rowspan="1">Genomes</td>
                <td align="left" colspan="1" rowspan="1">Size</td>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left" colspan="1" rowspan="1">6239</td>
                <td align="left" colspan="1" rowspan="1">Caenorhabditis Elegans</td>
                <td align="left" colspan="1" rowspan="1">6 (Linear)</td>
                <td align="left" colspan="1" rowspan="1">100,267,633</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">31685</td>
                <td align="left" colspan="1" rowspan="1">Escherichia Coli str. K-12 Substr.DH10B</td>
                <td align="left" colspan="1" rowspan="1">1 (Circular)</td>
                <td align="left" colspan="1" rowspan="1">4,686,137</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">347515</td>
                <td align="left" colspan="1" rowspan="1">Leishmania Major Strain Friedlin</td>
                <td align="left" colspan="1" rowspan="1">36 (Linear)</td>
                <td align="left" colspan="1" rowspan="1">32,816,778</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">559292</td>
                <td align="left" colspan="1" rowspan="1">Saccharmoyces Cerevisiae S288c</td>
                <td align="left" colspan="1" rowspan="1">16 (Linear)</td>
                <td align="left" colspan="1" rowspan="1">12,071,326</td>
              </tr>
            </tbody>
          </table></alternatives><table-wrap-foot>
            <fn id="nt101">
              <label/>
              <p>The details of the NGS data we got and used for the experiments are listed in <xref ref-type="supplementary-material" rid="pone.0039232.s002">Table S1</xref> and <xref ref-type="supplementary-material" rid="pone.0039232.s003">S2</xref>.</p>
            </fn>
          </table-wrap-foot></table-wrap>
        <p>We used the paired-end whole-genome shotgun data of the following organisms: S.aureus (Staphylococcus aureus) and R.sphaeroides (Rhodobacter sphaeroides). We downloaded the data sets from the GAGE <xref ref-type="bibr" rid="pone.0039232-Salzberg1">[4]</xref> web site at <ext-link ext-link-type="uri" xlink:href="http://gage.cbcb.umd.edu" xlink:type="simple">http://gage.cbcb.umd.edu</ext-link>, which originated from NCBI Genome Sequence, and then were preprocessed using the Quake <xref ref-type="bibr" rid="pone.0039232-Kelley1">[17]</xref> and ALLPATHS-LG <xref ref-type="bibr" rid="pone.0039232-Gnerre1">[18]</xref> error correctors. As for the real reads, we set all the assemblers to perform scaffolding and gap closure parts to compare the quality values of the assembly results. Because ccTSA did not exploit paired-end reads, we used SSPACE <xref ref-type="bibr" rid="pone.0039232-Marteb1">[19]</xref> to scaffold contigs. We ran ccTSA and SSPACE using both datasets of preprocessed reads and reported the better assembly results. For the other assemblers compared in this paper, we used their own internal scaffolding features. We reported the NG50 values, the numbers, and the error-corrected sizes of contigs and scaffolds using the analysis tools available from the GAGE web site.</p>
        <fig id="pone-0039232-g001" position="float">
          <object-id pub-id-type="doi">10.1371/journal.pone.0039232.g001</object-id>
          <label>Figure 1</label>
          <caption>
            <title>The NG50 of ccTSA on datasets from 4 organisms with different sequence coverage and k-mer values.</title>
            <p>(A) E.coli, Exact error model (Exact), and 36 bp reads (36 bp), (B) E.coli, Illumina error model (Illumina), and 36 bp, (C) E.coli, Exact, and 75 bp reads (75 bp), (D) E.coli Illumina, and 75 bp, (E) S.cerevisiae, Illumina, and 75 bp, (F) L.major, Illumina, and 75 bp, and (G) C.elegans, Illumina, and 75 bp. The k-mer values were varied from 19 to 35 on 36 bp data and from 37 to 73 on 76 bp data. In most datasets, NG50 values increased then decreased as we increased the k-mer values. The NG50 values were mostly saturated on the sequence coverage of 80x. The longer the genome size of an organism, the lower its NG50 values were.</p>
          </caption>
          <graphic mimetype="image" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.g001" xlink:type="simple"/>
        </fig>
        <p>The parallel versions of Velvet 1.2.01 <xref ref-type="bibr" rid="pone.0039232-Daniel1">[6]</xref>, SOAPdenovo 1.05 <xref ref-type="bibr" rid="pone.0039232-Li1">[8]</xref>, and ABySS 1.2.7 <xref ref-type="bibr" rid="pone.0039232-Simpson1">[7]</xref> were used for assembly. We compared the generated contigs (contiguous DNA sequences reconstructed from the assemblers) with the reference genomes using megablast <xref ref-type="bibr" rid="pone.0039232-Zhang1">[20]</xref> in NCBI BLAST+2.2.25 <xref ref-type="bibr" rid="pone.0039232-Stephen1">[21]</xref>. The parameters and configuration files used for BLAST+, Velvet, ABySS, SOAPdenovo, and ccTSA are listed in <xref ref-type="supplementary-material" rid="pone.0039232.s005">Table S4</xref>. We measured the assembler performance on a system with 4 octo-core Intel Xeon 4820 processors (total 32 computing cores) and 512GB of main memory that ran RHEL 6, gcc 4.4.4, and Open MPI 1.4.3. We used 16 hardware threads for executing the assemblers by default, and scaled the assemblers to utilize up to 32 cores. Unless mentioned otherwise, ccTSA pruned the k-mers with coverage value 1 from the k-mer coverage table before building a de Bruijn graph. We used SSPACE 1.1 <xref ref-type="bibr" rid="pone.0039232-Marteb1">[19]</xref> for scaffolding contigs generated from ccTSA.</p>
        <fig id="pone-0039232-g002" position="float">
          <object-id pub-id-type="doi">10.1371/journal.pone.0039232.g002</object-id>
          <label>Figure 2</label>
          <caption>
            <title>The NG50 of 4 assemblers on datasets from E.coli with different sequence coverage and k-mer values.</title>
            <p>(A) 20x, (B) 40x, (C) 80x, and (D) 160x. Illumina error model and 75 bp reads were used. Note that (C) and <xref ref-type="fig" rid="pone-0039232-g003">Figure 3(B)</xref> are the same. The NG50 values are mostly saturated on the sequence coverage of 80x for all the assemblers.</p>
          </caption>
          <graphic mimetype="image" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.g002" xlink:type="simple"/>
        </fig>
        <fig id="pone-0039232-g003" position="float">
          <object-id pub-id-type="doi">10.1371/journal.pone.0039232.g003</object-id>
          <label>Figure 3</label>
          <caption>
            <title>The NG50 of 4 assemblers on E.coli and L.major 80x with various k-mer values.</title>
            <p>(A) E.coli, Exact, and 36 bp, (B) E.coli, Illumina, and 75 bp, and (C) L.major, Illumina, and 75 bp. All the assemblers show similar trends on the NG50 values over various k-mer values. No single assembler produced the highest NG50 values on the entire range of k-mer values, but the NG50 values of Velvet and ccTSA were higher than others on many points.</p>
          </caption>
          <graphic mimetype="image" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.g003" xlink:type="simple"/>
        </fig>
      </sec>
      <sec id="s2b">
        <title>Evaluation</title>
        <p>We compared the execution time, the maximum memory usage, and the quality of the generated contigs of ccTSA with other assemblers. For the experiments using the synthetic reads, we used the following quality metrics: the largest contig length (Max), N20, N50, NG50, N80, and the fraction of the genome covered by the assembled contigs, called covered genome ratio (CGR). The assembled contigs were aligned to the reference genome with NCBI BLAST+2.2.25 using megablast algorithm. Among the generated contigs, we discarded the sequences that were either lower than 98% identical to the reference or too short (shorter than 100 bases for 36 bp reads and 200 bases for 75 bp reads). We counted the bases in the genome that were mapped to the remaining contigs to compute the covered genome ratio. The NG50 value is the length of a contig when the aggregate size of the contigs that are not smaller than the contig reaches half of the reference genome length.</p>
        <fig id="pone-0039232-g004" position="float">
          <object-id pub-id-type="doi">10.1371/journal.pone.0039232.g004</object-id>
          <label>Figure 4</label>
          <caption>
            <title>The quality values of ccTSA on 75 bp, Illumina, 80x datasets from 4 organisms with various k-mer values.</title>
            <p>(A) E.coli, (B) S.cerevisiae, (C) L.major, and (D) C.elegans. The k-mer values were varied from 19 to 35 on 36 bp data and from 37 to 73 on 76 bp data. Max stands for the largest contig length. Other quality values, such N20, N50, N80, and the largest contig length, have the trends similar to NG50.</p>
          </caption>
          <graphic mimetype="image" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.g004" xlink:type="simple"/>
        </fig>
        <p><xref ref-type="fig" rid="pone-0039232-g001">Figure 1</xref> shows the NG50 values ccTSA produced for datasets from 4 organisms when we varied the read length, the error model, and the sequence coverage of the synthetic reads. <xref ref-type="fig" rid="pone-0039232-g001">Figure 1A</xref> shows the NG50 of E.coli 36 bp synthetic reads without base-call errors (E.coli-Exact-36 bp) on various k-mer lengths. At a given sequence coverage, the NG50 values first increased then decreased as the k-mer length increased. As the sequence coverage increased, the NG50 values increased but were saturated starting from 80x. Also, the k-mer length giving the best NG50 value increases as the sequence coverage increases. When we introduced errors to the reads using the Illumina error model, the trends of the NG50 over the k-mer length and the sequence coverage were similar, but the NG50 values were smaller than the ones without errors (<xref ref-type="fig" rid="pone-0039232-g001">Figure 1B</xref>). When we increased the read length from 36 bp to 75 bp, the trends were unchanged, but the NG50 increased as fewer regions of a genome were aliased such that a read was mapped to multiple regions (<xref ref-type="fig" rid="pone-0039232-g001">Figure 1C and 1D</xref>). On other organisms, the trends of the NG50 were unchanged. However, the NG50 at a given sequence coverage decreased as the length of a genome increased (<xref ref-type="fig" rid="pone-0039232-g001">Figure 1E, 1F, and 1G</xref>).</p>
        <fig id="pone-0039232-g005" position="float">
          <object-id pub-id-type="doi">10.1371/journal.pone.0039232.g005</object-id>
          <label>Figure 5</label>
          <caption>
            <title>The execution time of 4 assemblers on E.coli and L.major 80x with thread numbers varied.</title>
            <p>(A) E.coli, Exact, and 36 bp, (B) E.coli, Illumina, and 75 bp, and (C) L.major, Illumina, and 75 bp. The k-mer value that produced the highest NG50 value was chosen for each assembler. As the dataset size increases, the scalability of the execution time improves. ccTSA ran faster and had better scalability in speed than the other assemblers.</p>
          </caption>
          <graphic mimetype="image" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.g005" xlink:type="simple"/>
        </fig>
        <table-wrap id="pone-0039232-t002" position="float"><object-id pub-id-type="doi">10.1371/journal.pone.0039232.t002</object-id><label>Table 2</label><caption>
            <title>The contig lengths, quality, sequencing speed, and memory usage of the sequence assemblers.</title>
          </caption><!--===== Grouping alternate versions of objects =====--><alternatives><graphic id="pone-0039232-t002-2" mimetype="image" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.t002" xlink:type="simple"/><table>
            <colgroup span="1">
              <col align="left" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
            </colgroup>
            <thead>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">Read</td>
                <td align="left" colspan="1" rowspan="1">Error</td>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">Time</td>
                <td align="left" colspan="1" rowspan="1">Memory</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">Organism</td>
                <td align="left" colspan="1" rowspan="1">length</td>
                <td align="left" colspan="1" rowspan="1">Model</td>
                <td align="left" colspan="1" rowspan="1">Assembler</td>
                <td align="left" colspan="1" rowspan="1">k-mer</td>
                <td align="left" colspan="1" rowspan="1">N20</td>
                <td align="left" colspan="1" rowspan="1">N50</td>
                <td align="left" colspan="1" rowspan="1">N80</td>
                <td align="left" colspan="1" rowspan="1">Max</td>
                <td align="left" colspan="1" rowspan="1">NG50</td>
                <td align="left" colspan="1" rowspan="1">CGR</td>
                <td align="left" colspan="1" rowspan="1">(s)</td>
                <td align="left" colspan="1" rowspan="1">(GB)</td>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left" colspan="1" rowspan="1">E.coli</td>
                <td align="left" colspan="1" rowspan="1">36x</td>
                <td align="left" colspan="1" rowspan="1">Exact</td>
                <td align="left" colspan="1" rowspan="1">Velvet</td>
                <td align="left" colspan="1" rowspan="1">29</td>
                <td align="left" colspan="1" rowspan="1">43126</td>
                <td align="left" colspan="1" rowspan="1">23964</td>
                <td align="left" colspan="1" rowspan="1">9880</td>
                <td align="left" colspan="1" rowspan="1">138180</td>
                <td align="left" colspan="1" rowspan="1">21593</td>
                <td align="left" colspan="1" rowspan="1">0.990</td>
                <td align="left" colspan="1" rowspan="1">164.1</td>
                <td align="left" colspan="1" rowspan="1">1.15</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">SOAP</td>
                <td align="left" colspan="1" rowspan="1">29</td>
                <td align="left" colspan="1" rowspan="1">41945</td>
                <td align="left" colspan="1" rowspan="1">20161</td>
                <td align="left" colspan="1" rowspan="1">9218</td>
                <td align="left" colspan="1" rowspan="1">127974</td>
                <td align="left" colspan="1" rowspan="1">18951</td>
                <td align="left" colspan="1" rowspan="1">0.988</td>
                <td align="left" colspan="1" rowspan="1">46.0</td>
                <td align="left" colspan="1" rowspan="1">0.20</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ABySS</td>
                <td align="left" colspan="1" rowspan="1">31</td>
                <td align="left" colspan="1" rowspan="1">41813</td>
                <td align="left" colspan="1" rowspan="1">20762</td>
                <td align="left" colspan="1" rowspan="1">9047</td>
                <td align="left" colspan="1" rowspan="1">127976</td>
                <td align="left" colspan="1" rowspan="1">18720</td>
                <td align="left" colspan="1" rowspan="1">0.988</td>
                <td align="left" colspan="1" rowspan="1">109.9</td>
                <td align="left" colspan="1" rowspan="1">0.50</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ccTSA</td>
                <td align="left" colspan="1" rowspan="1">29</td>
                <td align="left" colspan="1" rowspan="1">41950</td>
                <td align="left" colspan="1" rowspan="1">23404</td>
                <td align="left" colspan="1" rowspan="1">9865</td>
                <td align="left" colspan="1" rowspan="1">129729</td>
                <td align="left" colspan="1" rowspan="1">22251</td>
                <td align="left" colspan="1" rowspan="1">0.982</td>
                <td align="left" colspan="1" rowspan="1">8.3</td>
                <td align="left" colspan="1" rowspan="1">0.71</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">Illumina</td>
                <td align="left" colspan="1" rowspan="1">Velvet</td>
                <td align="left" colspan="1" rowspan="1">27</td>
                <td align="left" colspan="1" rowspan="1">42081</td>
                <td align="left" colspan="1" rowspan="1">20559</td>
                <td align="left" colspan="1" rowspan="1">9650</td>
                <td align="left" colspan="1" rowspan="1">120911</td>
                <td align="left" colspan="1" rowspan="1">19112</td>
                <td align="left" colspan="1" rowspan="1">0.989</td>
                <td align="left" colspan="1" rowspan="1">148.4</td>
                <td align="left" colspan="1" rowspan="1">1.06</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">SOAP</td>
                <td align="left" colspan="1" rowspan="1">27</td>
                <td align="left" colspan="1" rowspan="1">32335</td>
                <td align="left" colspan="1" rowspan="1">15785</td>
                <td align="left" colspan="1" rowspan="1">7658</td>
                <td align="left" colspan="1" rowspan="1">120913</td>
                <td align="left" colspan="1" rowspan="1">15339</td>
                <td align="left" colspan="1" rowspan="1">0.986</td>
                <td align="left" colspan="1" rowspan="1">60.6</td>
                <td align="left" colspan="1" rowspan="1">1.15</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ABySS</td>
                <td align="left" colspan="1" rowspan="1">29</td>
                <td align="left" colspan="1" rowspan="1">35359</td>
                <td align="left" colspan="1" rowspan="1">17045</td>
                <td align="left" colspan="1" rowspan="1">8015</td>
                <td align="left" colspan="1" rowspan="1">74618</td>
                <td align="left" colspan="1" rowspan="1">16305</td>
                <td align="left" colspan="1" rowspan="1">0.985</td>
                <td align="left" colspan="1" rowspan="1">144.0</td>
                <td align="left" colspan="1" rowspan="1">1.91</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ccTSA</td>
                <td align="left" colspan="1" rowspan="1">27</td>
                <td align="left" colspan="1" rowspan="1">35538</td>
                <td align="left" colspan="1" rowspan="1">17765</td>
                <td align="left" colspan="1" rowspan="1">9474</td>
                <td align="left" colspan="1" rowspan="1">120914</td>
                <td align="left" colspan="1" rowspan="1">16566</td>
                <td align="left" colspan="1" rowspan="1">0.982</td>
                <td align="left" colspan="1" rowspan="1">14.6</td>
                <td align="left" colspan="1" rowspan="1">2.13</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">75x</td>
                <td align="left" colspan="1" rowspan="1">Exact</td>
                <td align="left" colspan="1" rowspan="1">Velvet</td>
                <td align="left" colspan="1" rowspan="1">63</td>
                <td align="left" colspan="1" rowspan="1">140955</td>
                <td align="left" colspan="1" rowspan="1">67344</td>
                <td align="left" colspan="1" rowspan="1">30857</td>
                <td align="left" colspan="1" rowspan="1">326386</td>
                <td align="left" colspan="1" rowspan="1">63602</td>
                <td align="left" colspan="1" rowspan="1">0.996</td>
                <td align="left" colspan="1" rowspan="1">127.5</td>
                <td align="left" colspan="1" rowspan="1">0.74</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">SOAP</td>
                <td align="left" colspan="1" rowspan="1">59</td>
                <td align="left" colspan="1" rowspan="1">131882</td>
                <td align="left" colspan="1" rowspan="1">60346</td>
                <td align="left" colspan="1" rowspan="1">30851</td>
                <td align="left" colspan="1" rowspan="1">326380</td>
                <td align="left" colspan="1" rowspan="1">59806</td>
                <td align="left" colspan="1" rowspan="1">0.995</td>
                <td align="left" colspan="1" rowspan="1">39.0</td>
                <td align="left" colspan="1" rowspan="1">2.61</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ABySS</td>
                <td align="left" colspan="1" rowspan="1">63</td>
                <td align="left" colspan="1" rowspan="1">131888</td>
                <td align="left" colspan="1" rowspan="1">60352</td>
                <td align="left" colspan="1" rowspan="1">31019</td>
                <td align="left" colspan="1" rowspan="1">326386</td>
                <td align="left" colspan="1" rowspan="1">59812</td>
                <td align="left" colspan="1" rowspan="1">0.996</td>
                <td align="left" colspan="1" rowspan="1">140.1</td>
                <td align="left" colspan="1" rowspan="1">1.32</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ccTSA</td>
                <td align="left" colspan="1" rowspan="1">59</td>
                <td align="left" colspan="1" rowspan="1">134957</td>
                <td align="left" colspan="1" rowspan="1">73692</td>
                <td align="left" colspan="1" rowspan="1">34655</td>
                <td align="left" colspan="1" rowspan="1">326382</td>
                <td align="left" colspan="1" rowspan="1">72272</td>
                <td align="left" colspan="1" rowspan="1">0.993</td>
                <td align="left" colspan="1" rowspan="1">8.6</td>
                <td align="left" colspan="1" rowspan="1">0.75</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">Illumina</td>
                <td align="left" colspan="1" rowspan="1">Velvet</td>
                <td align="left" colspan="1" rowspan="1">53</td>
                <td align="left" colspan="1" rowspan="1">140928</td>
                <td align="left" colspan="1" rowspan="1">67324</td>
                <td align="left" colspan="1" rowspan="1">31713</td>
                <td align="left" colspan="1" rowspan="1">269798</td>
                <td align="left" colspan="1" rowspan="1">60146</td>
                <td align="left" colspan="1" rowspan="1">0.996</td>
                <td align="left" colspan="1" rowspan="1">120.1</td>
                <td align="left" colspan="1" rowspan="1">2.75</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">SOAP</td>
                <td align="left" colspan="1" rowspan="1">53</td>
                <td align="left" colspan="1" rowspan="1">123955</td>
                <td align="left" colspan="1" rowspan="1">59642</td>
                <td align="left" colspan="1" rowspan="1">27864</td>
                <td align="left" colspan="1" rowspan="1">180837</td>
                <td align="left" colspan="1" rowspan="1">58773</td>
                <td align="left" colspan="1" rowspan="1">0.994</td>
                <td align="left" colspan="1" rowspan="1">58.1</td>
                <td align="left" colspan="1" rowspan="1">4.45</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ABySS</td>
                <td align="left" colspan="1" rowspan="1">55</td>
                <td align="left" colspan="1" rowspan="1">123957</td>
                <td align="left" colspan="1" rowspan="1">59644</td>
                <td align="left" colspan="1" rowspan="1">29823</td>
                <td align="left" colspan="1" rowspan="1">269799</td>
                <td align="left" colspan="1" rowspan="1">57834</td>
                <td align="left" colspan="1" rowspan="1">0.994</td>
                <td align="left" colspan="1" rowspan="1">209.5</td>
                <td align="left" colspan="1" rowspan="1">3.23</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ccTSA</td>
                <td align="left" colspan="1" rowspan="1">53</td>
                <td align="left" colspan="1" rowspan="1">123953</td>
                <td align="left" colspan="1" rowspan="1">60418</td>
                <td align="left" colspan="1" rowspan="1">32481</td>
                <td align="left" colspan="1" rowspan="1">269712</td>
                <td align="left" colspan="1" rowspan="1">60146</td>
                <td align="left" colspan="1" rowspan="1">0.998</td>
                <td align="left" colspan="1" rowspan="1">14.5</td>
                <td align="left" colspan="1" rowspan="1">2.74</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">S.cerevisiae</td>
                <td align="left" colspan="1" rowspan="1">75x</td>
                <td align="left" colspan="1" rowspan="1">Illumina</td>
                <td align="left" colspan="1" rowspan="1">Velvet</td>
                <td align="left" colspan="1" rowspan="1">55</td>
                <td align="left" colspan="1" rowspan="1">73808</td>
                <td align="left" colspan="1" rowspan="1">42367</td>
                <td align="left" colspan="1" rowspan="1">19557</td>
                <td align="left" colspan="1" rowspan="1">151220</td>
                <td align="left" colspan="1" rowspan="1">39645</td>
                <td align="left" colspan="1" rowspan="1">0.974</td>
                <td align="left" colspan="1" rowspan="1">245.0</td>
                <td align="left" colspan="1" rowspan="1">6.62</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">SOAP</td>
                <td align="left" colspan="1" rowspan="1">51</td>
                <td align="left" colspan="1" rowspan="1">69026</td>
                <td align="left" colspan="1" rowspan="1">37752</td>
                <td align="left" colspan="1" rowspan="1">17390</td>
                <td align="left" colspan="1" rowspan="1">140363</td>
                <td align="left" colspan="1" rowspan="1">35826</td>
                <td align="left" colspan="1" rowspan="1">0.962</td>
                <td align="left" colspan="1" rowspan="1">169.1</td>
                <td align="left" colspan="1" rowspan="1">9.76</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ABySS</td>
                <td align="left" colspan="1" rowspan="1">55</td>
                <td align="left" colspan="1" rowspan="1">69403</td>
                <td align="left" colspan="1" rowspan="1">38353</td>
                <td align="left" colspan="1" rowspan="1">17645</td>
                <td align="left" colspan="1" rowspan="1">140369</td>
                <td align="left" colspan="1" rowspan="1">36100</td>
                <td align="left" colspan="1" rowspan="1">0.963</td>
                <td align="left" colspan="1" rowspan="1">552.0</td>
                <td align="left" colspan="1" rowspan="1">5.59</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ccTSA</td>
                <td align="left" colspan="1" rowspan="1">55</td>
                <td align="left" colspan="1" rowspan="1">82638</td>
                <td align="left" colspan="1" rowspan="1">42169</td>
                <td align="left" colspan="1" rowspan="1">18698</td>
                <td align="left" colspan="1" rowspan="1">150817</td>
                <td align="left" colspan="1" rowspan="1">39763</td>
                <td align="left" colspan="1" rowspan="1">0.982</td>
                <td align="left" colspan="1" rowspan="1">32.2</td>
                <td align="left" colspan="1" rowspan="1">6.48</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">L.major</td>
                <td align="left" colspan="1" rowspan="1">75x</td>
                <td align="left" colspan="1" rowspan="1">Illumina</td>
                <td align="left" colspan="1" rowspan="1">Velvet</td>
                <td align="left" colspan="1" rowspan="1">63</td>
                <td align="left" colspan="1" rowspan="1">52565</td>
                <td align="left" colspan="1" rowspan="1">25446</td>
                <td align="left" colspan="1" rowspan="1">10053</td>
                <td align="left" colspan="1" rowspan="1">205626</td>
                <td align="left" colspan="1" rowspan="1">22857</td>
                <td align="left" colspan="1" rowspan="1">0.976</td>
                <td align="left" colspan="1" rowspan="1">1242.6</td>
                <td align="left" colspan="1" rowspan="1">27.02</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">SOAP</td>
                <td align="left" colspan="1" rowspan="1">61</td>
                <td align="left" colspan="1" rowspan="1">49947</td>
                <td align="left" colspan="1" rowspan="1">24148</td>
                <td align="left" colspan="1" rowspan="1">9542</td>
                <td align="left" colspan="1" rowspan="1">160354</td>
                <td align="left" colspan="1" rowspan="1">22121</td>
                <td align="left" colspan="1" rowspan="1">0.973</td>
                <td align="left" colspan="1" rowspan="1">680.0</td>
                <td align="left" colspan="1" rowspan="1">30.11</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ABySS</td>
                <td align="left" colspan="1" rowspan="1">65</td>
                <td align="left" colspan="1" rowspan="1">51281</td>
                <td align="left" colspan="1" rowspan="1">24348</td>
                <td align="left" colspan="1" rowspan="1">9710</td>
                <td align="left" colspan="1" rowspan="1">205630</td>
                <td align="left" colspan="1" rowspan="1">22226</td>
                <td align="left" colspan="1" rowspan="1">0.971</td>
                <td align="left" colspan="1" rowspan="1">2135.3</td>
                <td align="left" colspan="1" rowspan="1">13.72</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ccTSA</td>
                <td align="left" colspan="1" rowspan="1">63</td>
                <td align="left" colspan="1" rowspan="1">55290</td>
                <td align="left" colspan="1" rowspan="1">28582</td>
                <td align="left" colspan="1" rowspan="1">11915</td>
                <td align="left" colspan="1" rowspan="1">228670</td>
                <td align="left" colspan="1" rowspan="1">26404</td>
                <td align="left" colspan="1" rowspan="1">0.988</td>
                <td align="left" colspan="1" rowspan="1">128.6</td>
                <td align="left" colspan="1" rowspan="1">23.56</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">C.elegans</td>
                <td align="left" colspan="1" rowspan="1">75x</td>
                <td align="left" colspan="1" rowspan="1">Illumina</td>
                <td align="left" colspan="1" rowspan="1">Velvet</td>
                <td align="left" colspan="1" rowspan="1">55</td>
                <td align="left" colspan="1" rowspan="1">39346</td>
                <td align="left" colspan="1" rowspan="1">15891</td>
                <td align="left" colspan="1" rowspan="1">4729</td>
                <td align="left" colspan="1" rowspan="1">130754</td>
                <td align="left" colspan="1" rowspan="1">14450</td>
                <td align="left" colspan="1" rowspan="1">0.953</td>
                <td align="left" colspan="1" rowspan="1">2395.0</td>
                <td align="left" colspan="1" rowspan="1">53.49</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">SOAP</td>
                <td align="left" colspan="1" rowspan="1">53</td>
                <td align="left" colspan="1" rowspan="1">32571</td>
                <td align="left" colspan="1" rowspan="1">12928</td>
                <td align="left" colspan="1" rowspan="1">3646</td>
                <td align="left" colspan="1" rowspan="1">130752</td>
                <td align="left" colspan="1" rowspan="1">11595</td>
                <td align="left" colspan="1" rowspan="1">0.946</td>
                <td align="left" colspan="1" rowspan="1">1391.0</td>
                <td align="left" colspan="1" rowspan="1">58.40</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ABySS</td>
                <td align="left" colspan="1" rowspan="1">57</td>
                <td align="left" colspan="1" rowspan="1">34652</td>
                <td align="left" colspan="1" rowspan="1">13753</td>
                <td align="left" colspan="1" rowspan="1">3944</td>
                <td align="left" colspan="1" rowspan="1">130760</td>
                <td align="left" colspan="1" rowspan="1">12532</td>
                <td align="left" colspan="1" rowspan="1">0.949</td>
                <td align="left" colspan="1" rowspan="1">4643.0</td>
                <td align="left" colspan="1" rowspan="1">34.63</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">ccTSA</td>
                <td align="left" colspan="1" rowspan="1">55</td>
                <td align="left" colspan="1" rowspan="1">33498</td>
                <td align="left" colspan="1" rowspan="1">13902</td>
                <td align="left" colspan="1" rowspan="1">4252</td>
                <td align="left" colspan="1" rowspan="1">125563</td>
                <td align="left" colspan="1" rowspan="1">12817</td>
                <td align="left" colspan="1" rowspan="1">0.962</td>
                <td align="left" colspan="1" rowspan="1">383.1</td>
                <td align="left" colspan="1" rowspan="1">53.97</td>
              </tr>
            </tbody>
          </table></alternatives><table-wrap-foot>
            <fn id="nt102">
              <label/>
              <p>Max stands for the largest contig length. While ccTSA produced comparable sequencing quality and superior sequencing speed, its memory usage was not much better than the other assemblers, especially compared to ABySS on large datasets.</p>
            </fn>
          </table-wrap-foot></table-wrap>
        <p><xref ref-type="fig" rid="pone-0039232-g002">Figure 2</xref> shows the NG50 values from ccTSA and the other assemblers on E.coli 75 bp reads using the Illumina error model. Other assemblers showed similar trends in NG50 when the k-mer lengths and sequence coverage values were varied. The NG50 values of Velvet were higher than those of other assemblers on small sequence coverage values, but became similar when the coverage value exceeded 40x. The NG50 values on other organisms showed similar trends and were not included in this paper. Because the improvement on NG50 was marginal after the sequence coverage of 80, we used 80x reads hereafter.</p>
        <fig id="pone-0039232-g006" position="float">
          <object-id pub-id-type="doi">10.1371/journal.pone.0039232.g006</object-id>
          <label>Figure 6</label>
          <caption>
            <title>The relationship between the NG50, execution time, and memory usage of ccTSA.</title>
            <p>We used the C.elegans, Illumina, and 75 bp reads, chose the pruning interval as 10 M reads, and increased it by 10 M for subsequent configurations. Note that the dataset had about 105 M reads. As the pruning interval increases, the execution time increases slowly, the NG value improves slightly, but the memory usage grows rapidly.</p>
          </caption>
          <graphic mimetype="image" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.g006" xlink:type="simple"/>
        </fig>
        <p>We compared the NG50 values of the four assemblers on the E.coli datasets in <xref ref-type="fig" rid="pone-0039232-g003">Figure 3A and 3B</xref>. All the assemblers generated similar NG50 values on a given k-mer length. No single assembler produced the highest NG50 values on the entire range of k-mer values, but the NG50 values of Velvet and ccTSA were higher than others on many points. For the 75 bp reads with the Illumina error model, the k-mer values that provided the highest NG50 were similar: 53 for Velvet, SOAPdenovo, and ccTSA, and 55 for ABySS. The results on other organisms showed the same trends. Among them, we presented the NG50 values on L.major 80x reads with the Illumina error model in <xref ref-type="fig" rid="pone-0039232-g003">Figure 3C</xref>.</p>
        <table-wrap id="pone-0039232-t003" position="float"><object-id pub-id-type="doi">10.1371/journal.pone.0039232.t003</object-id><label>Table 3</label><caption>
            <title>The quality values of the sequence assemblers on paired-end data sets.</title>
          </caption><!--===== Grouping alternate versions of objects =====--><alternatives><graphic id="pone-0039232-t003-3" mimetype="image" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.t003" xlink:type="simple"/><table>
            <colgroup span="1">
              <col align="left" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
              <col align="center" span="1"/>
            </colgroup>
            <thead>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="4" rowspan="1">Contigs</td>
                <td align="left" colspan="4" rowspan="1">Scaffolds</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1"/>
                <td align="left" colspan="1" rowspan="1">Num</td>
                <td align="left" colspan="1" rowspan="1">NG50 (kb)</td>
                <td align="left" colspan="1" rowspan="1">Errors</td>
                <td align="left" colspan="1" rowspan="1">NG50 corr (kb)</td>
                <td align="left" colspan="1" rowspan="1">Num</td>
                <td align="left" colspan="1" rowspan="1">NG50 (kb)</td>
                <td align="left" colspan="1" rowspan="1">Errors</td>
                <td align="left" colspan="1" rowspan="1">NG50 corr (kb)</td>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left" colspan="9" rowspan="1">S.aureus</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">ABySS</td>
                <td align="left" colspan="1" rowspan="1">302</td>
                <td align="left" colspan="1" rowspan="1">29.2</td>
                <td align="left" colspan="1" rowspan="1">14</td>
                <td align="left" colspan="1" rowspan="1">24.8</td>
                <td align="left" colspan="1" rowspan="1">246</td>
                <td align="left" colspan="1" rowspan="1">34</td>
                <td align="left" colspan="1" rowspan="1">1</td>
                <td align="left" colspan="1" rowspan="1">28</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">SOAPdenovo</td>
                <td align="left" colspan="1" rowspan="1">107</td>
                <td align="left" colspan="1" rowspan="1">288.2</td>
                <td align="left" colspan="1" rowspan="1">48</td>
                <td align="left" colspan="1" rowspan="1">62.7</td>
                <td align="left" colspan="1" rowspan="1">99</td>
                <td align="left" colspan="1" rowspan="1">332</td>
                <td align="left" colspan="1" rowspan="1">8</td>
                <td align="left" colspan="1" rowspan="1">284</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">Velvet</td>
                <td align="left" colspan="1" rowspan="1">162</td>
                <td align="left" colspan="1" rowspan="1">48.4</td>
                <td align="left" colspan="1" rowspan="1">28</td>
                <td align="left" colspan="1" rowspan="1">41.5</td>
                <td align="left" colspan="1" rowspan="1">45</td>
                <td align="left" colspan="1" rowspan="1">762</td>
                <td align="left" colspan="1" rowspan="1">17</td>
                <td align="left" colspan="1" rowspan="1">126</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">ccTSA (k-mer = 31)</td>
                <td align="left" colspan="1" rowspan="1">167</td>
                <td align="left" colspan="1" rowspan="1">70.2</td>
                <td align="left" colspan="1" rowspan="1">74</td>
                <td align="left" colspan="1" rowspan="1">35.0</td>
                <td align="left" colspan="1" rowspan="1">95</td>
                <td align="left" colspan="1" rowspan="1">248.2</td>
                <td align="left" colspan="1" rowspan="1">2</td>
                <td align="left" colspan="1" rowspan="1">248.2</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">ccTSA (k-mer = 45)</td>
                <td align="left" colspan="1" rowspan="1">103</td>
                <td align="left" colspan="1" rowspan="1">104.8</td>
                <td align="left" colspan="1" rowspan="1">58</td>
                <td align="left" colspan="1" rowspan="1">42.5</td>
                <td align="left" colspan="1" rowspan="1">51</td>
                <td align="left" colspan="1" rowspan="1">1,565.0</td>
                <td align="left" colspan="1" rowspan="1">6</td>
                <td align="left" colspan="1" rowspan="1">238.6</td>
              </tr>
              <tr>
                <td align="left" colspan="9" rowspan="1">R.sphaeroides</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">ABySS</td>
                <td align="left" colspan="1" rowspan="1">1915</td>
                <td align="left" colspan="1" rowspan="1">5.9</td>
                <td align="left" colspan="1" rowspan="1">55</td>
                <td align="left" colspan="1" rowspan="1">4.2</td>
                <td align="left" colspan="1" rowspan="1">1701</td>
                <td align="left" colspan="1" rowspan="1">9</td>
                <td align="left" colspan="1" rowspan="1">3</td>
                <td align="left" colspan="1" rowspan="1">5</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">SOAPdenovo</td>
                <td align="left" colspan="1" rowspan="1">204</td>
                <td align="left" colspan="1" rowspan="1">131.7</td>
                <td align="left" colspan="1" rowspan="1">414</td>
                <td align="left" colspan="1" rowspan="1">14.3</td>
                <td align="left" colspan="1" rowspan="1">166</td>
                <td align="left" colspan="1" rowspan="1">660</td>
                <td align="left" colspan="1" rowspan="1">3</td>
                <td align="left" colspan="1" rowspan="1">658</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">Velvet</td>
                <td align="left" colspan="1" rowspan="1">583</td>
                <td align="left" colspan="1" rowspan="1">15.7</td>
                <td align="left" colspan="1" rowspan="1">35</td>
                <td align="left" colspan="1" rowspan="1">14.5</td>
                <td align="left" colspan="1" rowspan="1">178</td>
                <td align="left" colspan="1" rowspan="1">353</td>
                <td align="left" colspan="1" rowspan="1">6</td>
                <td align="left" colspan="1" rowspan="1">270</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">ccTSA (k-mer = 31)</td>
                <td align="left" colspan="1" rowspan="1">350</td>
                <td align="left" colspan="1" rowspan="1">36.2</td>
                <td align="left" colspan="1" rowspan="1">592</td>
                <td align="left" colspan="1" rowspan="1">9.3</td>
                <td align="left" colspan="1" rowspan="1">144</td>
                <td align="left" colspan="1" rowspan="1">341.8</td>
                <td align="left" colspan="1" rowspan="1">23</td>
                <td align="left" colspan="1" rowspan="1">149.1</td>
              </tr>
              <tr>
                <td align="left" colspan="1" rowspan="1">ccTSA (k-mer = 29)</td>
                <td align="left" colspan="1" rowspan="1">360</td>
                <td align="left" colspan="1" rowspan="1">47.3</td>
                <td align="left" colspan="1" rowspan="1">206</td>
                <td align="left" colspan="1" rowspan="1">16.8</td>
                <td align="left" colspan="1" rowspan="1">254</td>
                <td align="left" colspan="1" rowspan="1">154.3</td>
                <td align="left" colspan="1" rowspan="1">12</td>
                <td align="left" colspan="1" rowspan="1">82.2</td>
              </tr>
            </tbody>
          </table></alternatives><table-wrap-foot>
            <fn id="nt103">
              <label/>
              <p>Two organisms, S. aureus and R.sphaeroides, were used. We used the following quality metrics, which were used for the GAGE evaluation study: the number, NG50, and corrected NG50 of the contigs and scaffolds from the assemblers as well as the number of errors. The number of misjoins and indel errors larger than or equal to 5 base pairs was counted as the errors for contigs, and the number of misjoins became the errors for scaffolds.</p>
            </fn>
          </table-wrap-foot></table-wrap>
        <p>NG50 is not the only quality metric of the assembly results. We report other metrics, such as N20, N50, N80, the largest contig length, and the covered genome ratio (CGR), of ccTSA on 75 bp reads with the Illumina error model in <xref ref-type="fig" rid="pone-0039232-g004">Figure 4</xref>. On a given k-mer length, the aggregate contig length was the largest, followed by the longest contig length, N80, N50, NG50, and N20 on most cases as expected. The CGR of the generated contigs was higher than 95% on most k-mer lengths, which shows the usefulness of ccTSA as a sequence assembler. The CGR values ccTSA produced were also similar to those from other assemblers, as shown in <xref ref-type="supplementary-material" rid="pone.0039232.s001">Figure S1</xref>.</p>
        <fig id="pone-0039232-g007" position="float">
          <object-id pub-id-type="doi">10.1371/journal.pone.0039232.g007</object-id>
          <label>Figure 7</label>
          <caption>
            <title>An overview of the execution flow of ccTSA.</title>
            <p>ccTSA reads short reads listed in FASTA/FASTQ files, generates k-mers from each read, and push those k-mers to a k-mer coverage table. After processing all the short reads, ccTSA optionally prunes k-mers, builds a de Bruijn graph using the remaining k-mers, merges contiguous nodes without junction, finds preferred links, resolves conflicts among preferred links, and produces contigs by traversing the graph.</p>
          </caption>
          <graphic mimetype="image" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.g007" xlink:type="simple"/>
        </fig>
        <p>Above results showed that the assembly quality, such as the NG50 and the CGR, of ccTSA was on par with or surpassed that of other sequence assemblers. We then compared the performance of the assemblers, where ccTSA provided huge advantages over the others in sequencing speed. <xref ref-type="fig" rid="pone-0039232-g005">Figure 5</xref> shows the execution time of ccTSA, Velvet, SOAPdenovo, and ABySS, when we increased the number of utilized hardware threads from 1 to 32. On each dataset, we used the k-mer length that gave the highest NG50 value, which was also the function of the assembler. The sequencing speed was improved by utilizing multiple threads on all the assemblers and it scaled better on larger datasets, but the sequencing speed of ccTSA was substantially better than other assemblers. ccTSA was 23.1, 5.6, and 13.3 times faster than Velvet, SOAPdenovo, and ABySS, respectively, on E.coli-Exact-36 bp reads, 13.0, 4.6, and 17.9 times faster than Velvet, SOAPdenovo, and ABySS on E.coli-Illumina-75 bp reads, and 9.7, 5.3, and 16.6 times faster than Velvet, SOAPdenono, and ABySS on L.major-Illumina-75 bp reads, when 16 hardware threads were used. The sequencing speed of ccTSA also scaled better than others. When the number of threads was increased from 1 to 16, the sequencing speed of ccTSA improved 9.0 times while that of Velvet, SOAPdenovo, and ABySS improved 2.8, 5.3, and 3.3 times on L.major-Illumina-75 bp reads. <xref ref-type="table" rid="pone-0039232-t002">Table 2</xref> summarized the contig length, quality, sequencing speed, and memory usage of the assemblers. Even though ccTSA was substantially faster than others, it used more main memory than others except SOAPdenovo on many datasets. Because a genome could have billions of base pairs, it is important to lower the memory usage.</p>
        <fig id="pone-0039232-g008" position="float">
          <object-id pub-id-type="doi">10.1371/journal.pone.0039232.g008</object-id>
          <label>Figure 8</label>
          <caption>
            <title>A snippet of a de Bruijn graph consisting of k-mer nodes and links.</title>
            <p>In Figure A, k-mer nodes are connected to neighbors through links. Figure B illustrates how to calculate the weight of an edge in a k-mer node. Currently, the weight of an edge on each side is computed by adding the coverage of the neighbor k-mer connected through the edge with the maximum coverage value among the k-mers connected to the neighbor k-mer on the same side.</p>
          </caption>
          <graphic mimetype="image" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.g008" xlink:type="simple"/>
        </fig>
        <p>We implemented a feature in ccTSA that trades the memory usage during execution for the quality of the generated contigs. This feature is based on the observation that the histogram of the coverage values on a k-mer coverage table reveals that a large portion of k-mers have low coverage values, mostly from base-call errors. If we prune these low coverage k-mers in the middle of building the table periodically instead of pruning them after all reads are processed, we can considerably lower the memory usage at the cost of slightly worse assembly quality due to the small possibility that the k-mers to be pruned are not from errors. If we increase the pruning frequency, low coverage k-mers are pruned more often so that ccTSA uses less memory, but the quality gets lowered as well. On the contrary, lowering pruning frequency leads to more memory usage, but better contig quality. <xref ref-type="fig" rid="pone-0039232-g006">Figure 6</xref> showed that pruning the k-mers with coverage value 1 after processing every 50 M reads lowered the memory usage and execution time by 47.3% and 9.5%, respectively, at the cost of 5.6% degradation in NG50 compared to the default option that pruned the k-mers with coverage value 1 after finishing coverage table construction on C.elegans-Illumina-75 bp reads. Changing the pruning frequency to every 20 M reads further lowered the memory usage and execution time by 43.4% and 6.7% at the cost of additional 5.1% degradation in NG50.</p>
        <fig id="pone-0039232-g009" position="float">
          <object-id pub-id-type="doi">10.1371/journal.pone.0039232.g009</object-id>
          <label>Figure 9</label>
          <caption>
            <title>Conflict resolution between neighbor k-mer nodes.</title>
            <p>Preferred neighbors of a k-mer node, up to one on each side, are shown as thick, red-colored arrows in Figure A. There is a conflict between the ATTGG node and the CATTG node. ATTGG directs CATTG as a preferred neighbor, but CATTG directs ATTGC as a preferred neighbor. Because CATTG has a higher k-mer coverage value, the link between ATTGG and CATTG is disconnected and ATTGG finds a new preferred edge among the remaining one, which directs TATTG (Figure B).</p>
          </caption>
          <graphic mimetype="image" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.g009" xlink:type="simple"/>
        </fig>
        <p><xref ref-type="table" rid="pone-0039232-t003">Table 3</xref> shows the assembly quality of ccTSA and the other assemblers on S.aureus and R.sphaeroides. ABySS, SOAPdenovo, and Velvet could exploit paired-end reads and generate scaffolds. We used SSPACE, a separate scaffolding tool, to take the output contigs from ccTSA and generate scaffolds. We configured ccTSA not to prune k-mers. We used the following quality metrics, which were used for the GAGE evaluation study: the number, NG50, and corrected NG50 of the contigs and scaffolds from the assemblers as well as the number of errors. The number of misjoins and indel errors larger than or equal to 5 base pairs was counted as the errors for contigs, and the number of misjoins became the errors for scaffolds. We broke contigs and scaffolds at each error and reported the broken ones as the corrected NG50 values. As for the results of ABySS, SOAPdenovo, and Velvet, We listed the values reported in the GAGE evaluation paper <xref ref-type="bibr" rid="pone.0039232-Salzberg1">[4]</xref>. When we set the k-mer length to 31, which was the number used at the GAGE paper, the quality values of ccTSA were better than those of ABySS and comparable to those of SOAPdenovo and Velvet. By changing the k-mer length, we could find the configurations that had better quality values. For example, when we set the k-mer length to 45 base pairs, the NG50 value of S.aureus scaffolds was 1.56 million base pairs, which was much longer than those of other assemblers.</p>
      </sec>
    </sec>
    <sec id="s3" sec-type="methods">
      <title>Methods</title>
      <p>In this section, we first provide an overview of the algorithms implemented in ccTSA. Then, we explain the techniques that exploit the characteristics of contemporary computer systems to effectively parallelize and save the memory usage of ccTSA.</p>
      <sec id="s3a">
        <title>Execution Flow of ccTSA</title>
        <p>ccTSA reads input files, each of which is composed of the short fragments (reads) of an original DNA sequence, and generates an output file that contains the result of sequence assembly. Sequencing machines <xref ref-type="bibr" rid="pone.0039232-Elaine1">[3]</xref> occasionally make mistakes in reading base-pairs, which are called base-calling errors, and some k-mers are mapped to the multiple regions of the original sequence, which are called repeats. As a result, it is not always possible for a sequence assembler to perfectly reconstruct the original sequence. So the output file of ccTSA typically consists of multiple DNA sequences called contigs and none of the contigs might be mapped to some regions of the original sequence. Currently, ccTSA can read FASTA and FASTQ files and writes the generated contigs to a FASTA file.</p>
        <p><xref ref-type="fig" rid="pone-0039232-g007">Figure 7</xref> illustrates an overview of the execution flow of ccTSA, which consists of multiple phases. First, it reads the series of short reads and extracts k-mers from each read. Because a k-mer consists of k nucleotides, a read that has fewer than k nucleotides is discarded. ccTSA also discards k-mers that have ambiguous or unidentified nucleotides. It checks a dictionary called a k-mer coverage table, which has a k-mer as a key and its coverage as a value, to see if the extracted k-mer exists in the table. If so, its coverage value is incremented by one. If not, the k-mer is added to the table with the coverage value 1. Note that k-mer coverage is different from the sequence coverage of the original DNA sequence. The former is the number of a k-mer instance from the sequenced reads, while the latter stands for how many times a nucleotide in the original sequence appears at the reads.</p>
        <p>After all the reads are processed, ccTSA optionally prunes k-mers with too low or high coverage values. Assuming that the original sequence consists of g nucleotides, the k-mer coverage table would have (g–k+1) entries if the sequence has no repeats and the reads have no base-calling errors. If a k-mer generated from a sequenced read contains one or more base-calling errors, the k-mer typically has very low coverage because it is unlikely that the original DNA sequence includes the k-mer. When the base-calling error rate of the reads is high, the k-mer coverage table has much more than (g–m+1) entries. If the coverage table has more entries, more memory space is required and it takes more time to access and update the table. Assuming that the coverage of the original DNA sequence is sufficiently high, most of low coverage k-mers are due to base-calling errors and most of high coverage k-mers are from the original sequence. As a result, pruning these low coverage k-mers can be useful for removing the base-calling errors, saving memory usage and improving sequencing speed. However, because the coverage of the original sequence is not uniform over all the nucleotides, some of the low coverage k-mers could be from the original sequence hence pruned incorrectly. This lowers the average length of the generated contigs, but it would be possible to restore them during phases after assembly, such as the scaffolding phase, which will be further discussed later in this section. k-mers with very high coverage are typically from repeats, so we can optionally mark them as repeats and exclude them hereafter.</p>
        <p>Remaining k-mers become k-mer nodes, among which the nodes that share k-1 nucleotides are linked together through edges building a de Bruijn graph. Because there are 4 types (Adenine, Thymine, Guanine, and Cytosine) of nucleotides in DNA, a k-mer node has up to 8 neighbors, 4 to the left side that share the first k-1 nucleotides and 4 to the right side that share the last k-1 ones. A node that has multiple neighbors to either side is called a junction node. After linking, the k-mers that are connected without any junction are merged, forming a contig node.</p>
        <p>Then, for each side of a node, the weights of the edges are computed and the neighbor with the highest weight is called a preferred neighbor. The weight of an edge represents the likelihood of the neighbor, which is highly correlated to the coverage of the neighbor nodes. As of now, the weight of an edge on each side is computed by adding the coverage of the neighbor k-mer connected through the edge with the maximum coverage value among the k-mers connected to the neighbor k-mer on the same side (<xref ref-type="fig" rid="pone-0039232-g008">Figure 8</xref>). This gives a priority to the neighbor node with higher k-mer coverage, at the same time prefers a longer path and enables ccTSA not to miss a strong or more likely path that is connected through a low coverage k-mer. ccTSA is designed to easily implement other ways to calculate weights.</p>
        <p>After finding preferred neighbors, we check each junction node JN1 whether its preferred neighbor JN2 also points JN1 back as a preferred neighbor. If not, we call that there is a conflict between JN1 and JN2, which is resolved as follows: if the coverage of JN1 is higher, we enforce JN2 to point JN1 as a preferred neighbor; if the coverage of JN2 is higher, we disconnect the edge between JN1 and JN2, find the preferred neighbor among the remaining edges, and repeat the above steps until there is still a conflict. Our conflict resolution algorithm (<xref ref-type="fig" rid="pone-0039232-g009">Figure 9</xref>) is simpler than those of other assemblers such as tip removal and tour bus algorithms <xref ref-type="bibr" rid="pone.0039232-Daniel1">[6]</xref> in Velvet, ABySS, and SOAPdenovo. It is a future work to refine the conflict resolution algorithm. After all conflicts are resolved, finally, contigs are generated by traversing the nodes connected through preferred neighbors. Unlike other assemblers, ccTSA does not exploit paired-end reads to orient and align multiple contigs into a single super-contig or scaffold. ccTSA can leverage a separate tool, such as SSPACE <xref ref-type="bibr" rid="pone.0039232-Marteb1">[19]</xref>, or the part of other assemblers to perform this scaffolding and finishing phase.</p>
      </sec>
      <sec id="s3b">
        <title>Optimizations</title>
        <p>Continuous improvement in semiconductor process technology enables a single chip to integrate billions of transistors and a rack server to have dozens of computing cores and terabytes of shared memory <xref ref-type="bibr" rid="pone.0039232-Hennessy1">[11]</xref>. We assume that the entire working set of ccTSA fits in a shared memory space. This simplifies programming and provides better performance than the systems that distribute k-mer entries across a cluster of computers connected over a network such as InfiniBand or Ethernet <xref ref-type="bibr" rid="pone.0039232-Hennessy1">[11]</xref>. Any computing core can access any k-mer entry through low latency (tens of nanoseconds) memory loads and stores in a shared memory system, while the k-mer information must be encapsulated by request and reply packets and transferred over a high latency (a few microseconds or more) network. Because the size of a k-mer entry is rather small, the overhead of packing and unpacking the entry is relatively high, further reducing program speed.</p>
        <p>We apply several optimization techniques to ccTSA. To reduce execution time, we parallelize the phases where we construct the k-mer coverage table, populate and link k-mer nodes, and merge consecutive k-mers without junction, which take 99% of the single threaded execution of ccTSA on average over the Illumina-75 bp-80x datasets from 4 organism explained in the <xref ref-type="sec" rid="s2">Results and Discussion</xref> section. When each phase is started, we first divide workload into many small chunks, each having the same size, and spawn multiple worker threads. Each worker repeats the process of receiving a chunk, processing it, and asking for another chunk that is not processed yet until all the chunks are processed. Because time for a thread to access data heavily depends on the address, the internal status of a complicated memory system within a processor, and interaction with concurrent accesses from other threads, time to process a chunk is not the same either <xref ref-type="bibr" rid="pone.0039232-Culler1">[12]</xref>. As a result, statically dividing the workload into the worker threads suffers from the load balancing problem, while dynamically assigning chunks to idle threads leads to better performance <xref ref-type="bibr" rid="pone.0039232-Culler1">[12]</xref>. As more worker threads are used, the performance advantage of the dynamic load balancing method becomes even higher. At the k-mer coverage construction phase, the workload is the sequences of short reads. We compose the k-mer coverage table of thousands of hash maps and use two different hash functions to identify a hash map and an entry in the hash map. Each hash map is protected by a mutex to prevent a simultaneous access to a hash map by multiple worker threads from destroying the data structure. Because there are much more hash maps than the worker threads and hash-map update is a simple operation, the worker threads rarely access the same hash map at the same time. As a result, the mutex operations do not incur significant performance overheads. Still, it is possible to further alleviate the overheads. Because a mutex is designed to protect a block of memory, not just a single word, it is heavier than an atomic CPU operation, which reads, modifies, and writes a word atomically. When the length of a k-mer is shorter than 32 base pairs, it can be represented as a single 64-bit word. Jellyfish <xref ref-type="bibr" rid="pone.0039232-Marais1">[22]</xref> exploited this to replace the mutex operations into atomic memory operations, such as compare-and-swaps, in building concurrent hash maps and updating k-mer coverage values, and achieved a higher k-mer coverage construction performance for short k-mers. At the k-mer node populating, linking, and merging phases, each hash map becomes a chunk. Mutexes are not needed for these phases because no data is updated concurrently by the multiple threads.</p>
        <p>To save memory usage, ccTSA compares a k-mer with its reverse complement and only stores the value which is earlier in the lexicographical order. It utilizes bit fields extensively and has different data structures for the k-mer nodes with and without junctions. It includes a custom memory allocator <xref ref-type="bibr" rid="pone.0039232-Berger1">[14]</xref>, which provides multiple allocation classes. Each class is implemented as a chain of memory blocks. When the custom allocator is used to allocate an object, the object is categorized into a class and stored at the last block of the class. If the block does not have enough free space, the default memory allocator in C++ is used to allocate a block to the class. It cannot deallocate a single object, but can quickly deallocate all the objects of a certain class simply by freeing the blocks of the class. ccTSA utilizes this custom allocator in pruning low coverage k-mers by having separate tables for low coverage and high coverage k-mers, assigning the low coverage k-mer objects and the k-mer coverage table for them to a same class, and deallocating the class. The remaining k-mer coverage table has fewer entries than the table without pruning, which has fast access time. So pruning also helps reducing execution time. We can even prune low coverage k-mers in the middle of building the k-mer coverage table, not just at the end, which provides an interesting tradeoff between the memory footprint and assembly quality, which is evaluated in the <xref ref-type="sec" rid="s2">Results and Discussion </xref>section.</p>
      </sec>
      <sec id="s3c">
        <title>Availability and Future Directions</title>
        <p>ccTSA is written in C++ and can be run on Unix-like systems. Source code is freely available from <ext-link ext-link-type="uri" xlink:href="http://code.google.com/p/cctsa/" xlink:type="simple">http://code.google.com/p/cctsa/</ext-link>. ccTSA can be extended to multiple directions. First, alternative data structures and algorithms can be explored in search of better sequencing speed and lower memory usage. Second, ccTSA does not target current General-Purpose computing on Graphics Processing Units (GPGPUs) <xref ref-type="bibr" rid="pone.0039232-Hennessy1">[11]</xref> because they do not provide enough memory capacity. However, it would be interesting to see if ccTSA can take advantage of their high computation power and memory bandwidth once future GPGPUs or many integrated core systems address the memory capacity issue. Third, ccTSA can be integrated with other scaffolding tools or extended to exploit paired-end reads to further orient and align the contigs.</p>
      </sec>
    </sec>
    <sec id="s4">
      <title>Supporting Information</title>
      <supplementary-material id="pone.0039232.s001" mimetype="image/tiff" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.s001" xlink:type="simple">
        <label>Figure S1</label>
        <caption>
          <p>The covered genome ratio of assemblers on E.coli and L.major 80x with various k-mer values. (A) E.coli, Exact, and 36 bp, (B) E.coli, Illumina, and 75 bp, and (C) L.major, Illumina, and 75 bp. The covered genome ratio (CGR) was more than 95% over most k-mer values regardless of the assemblers used.</p>
          <p>(TIFF)</p>
        </caption>
      </supplementary-material>
      <supplementary-material id="pone.0039232.s002" mimetype="image/tiff" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.s002" xlink:type="simple">
        <label>Table S1</label>
        <caption>
          <p>Datasets used for generating synthetic reads. The chromosome data of Caenorhabditis elegans (C.elegans), Escherichia coli str. K-12 substr. DH10B (E.coli), Leishmania major strain Friedlin (L.major), and Saccharomyces cerevisiae S288c (S. cerevisiae) were downloaded from NCBI Genome Sequence. Detailed information of L.major is listed in <xref ref-type="supplementary-material" rid="pone.0039232.s003">Table S2</xref>.</p>
          <p>(TIFF)</p>
        </caption>
      </supplementary-material>
      <supplementary-material id="pone.0039232.s003" mimetype="image/tiff" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.s003" xlink:type="simple">
        <label>Table S2</label>
        <caption>
          <p>Datasets used for generating synthetic reads. The chromosome data of Leishmania major strain Friedlin (L.major) were downloaded from NCBI Genome Sequence. Detailed information of C.elegans, E.coli, and S.cerevisiae is listed in <xref ref-type="supplementary-material" rid="pone.0039232.s002">Table S1</xref>.</p>
          <p>(TIFF)</p>
        </caption>
      </supplementary-material>
      <supplementary-material id="pone.0039232.s004" mimetype="image/tiff" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.s004" xlink:type="simple">
        <label>Table S3</label>
        <caption>
          <p>MetaSim options used to generate synthetic reads.</p>
          <p>(TIFF)</p>
        </caption>
      </supplementary-material>
      <supplementary-material id="pone.0039232.s005" mimetype="image/tiff" position="float" xlink:href="info:doi/10.1371/journal.pone.0039232.s005" xlink:type="simple">
        <label>Table S4</label>
        <caption>
          <p>Parameters and configuration files used for BLAST+, Velvet, ABySS, SOAPdenovo, ccTSA, and SSPACE.</p>
          <p>(TIFF)</p>
        </caption>
      </supplementary-material>
    </sec>
  </body>
  <back>
    <ack>
      <p>We gratefully acknowledge Sungwoo Choo and DongYul Lee for their help on generating synthetic reads and executing the assemblers.</p>
    </ack>
    <ref-list>
      <title>References</title>
      <ref id="pone.0039232-Miller1">
        <label>1</label>
        <element-citation publication-type="journal" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Miller</surname><given-names>JR</given-names></name><name name-style="western"><surname>Koren</surname><given-names>S</given-names></name><name name-style="western"><surname>Sutton</surname><given-names>G</given-names></name></person-group>             <year>2010</year>             <article-title>Assembly algorithms for next-generation sequencing data. Genomics.</article-title>             <volume>95(6)</volume>             <fpage>315</fpage>             <lpage>27</lpage>          </element-citation>
      </ref>
      <ref id="pone.0039232-Butler1">
        <label>2</label>
        <element-citation publication-type="journal" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Butler</surname><given-names>J</given-names></name><name name-style="western"><surname>MacCallum</surname><given-names>I</given-names></name><name name-style="western"><surname>Kleber</surname><given-names>M</given-names></name><name name-style="western"><surname>Shlyakhter</surname><given-names>IA</given-names></name><name name-style="western"><surname>Belmonte</surname><given-names>MK</given-names></name><etal/></person-group>             <year>2008</year>             <article-title>ALLPATHS: de novo assembly of whole-genome shotgun microreads. Genome Research.</article-title>             <volume>18(5)</volume>             <fpage>810</fpage>             <lpage>20</lpage>          </element-citation>
      </ref>
      <ref id="pone.0039232-Elaine1">
        <label>3</label>
        <element-citation publication-type="other" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Elaine</surname><given-names>RM</given-names></name></person-group>             <year>2008</year>             <article-title>Next-Generation DNA Sequencing Methods. Annu. Rev. Genom. Human Genet. 9: 387–402.</article-title>             <comment>doi: 10.1146/annurev.genom.9.081307.164359</comment>           </element-citation>
      </ref>
      <ref id="pone.0039232-Salzberg1">
        <label>4</label>
        <element-citation publication-type="other" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Salzberg</surname><given-names>SL</given-names></name><name name-style="western"><surname>Phillippy</surname><given-names>AM</given-names></name><name name-style="western"><surname>Zimin</surname><given-names>A</given-names></name><name name-style="western"><surname>Puiu</surname><given-names>D</given-names></name><name name-style="western"><surname>Magoc</surname><given-names>T</given-names></name><etal/></person-group>             <year>2011</year>             <article-title>GAGE: A critical evaluation of genome assemblies and assembly algorithms. Genome Research.</article-title>             <comment>doi: 10.1101/gr.131383.111</comment>           </element-citation>
      </ref>
      <ref id="pone.0039232-Smith1">
        <label>5</label>
        <element-citation publication-type="journal" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Smith</surname><given-names>TF</given-names></name></person-group>             <year>1980</year>             <article-title>Identification of common molecular subsequences. J. Mol. Bio.</article-title>             <volume>147(1)</volume>             <fpage>195</fpage>             <lpage>197</lpage>          </element-citation>
      </ref>
      <ref id="pone.0039232-Daniel1">
        <label>6</label>
        <element-citation publication-type="journal" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Daniel</surname><given-names>RZ</given-names></name><name name-style="western"><surname>Birney</surname><given-names>E</given-names></name></person-group>             <year>2008</year>             <article-title>Velvet: Algorithms for de novo short read assembly using de Bruijn graphs. Genome Research.</article-title>             <volume>18(5)</volume>             <fpage>821</fpage>             <lpage>829</lpage>          </element-citation>
      </ref>
      <ref id="pone.0039232-Simpson1">
        <label>7</label>
        <element-citation publication-type="other" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Simpson</surname><given-names>JT</given-names></name><name name-style="western"><surname>Wong</surname><given-names>K</given-names></name><name name-style="western"><surname>Jackman</surname><given-names>SD</given-names></name><name name-style="western"><surname>Schein</surname><given-names>JE</given-names></name><name name-style="western"><surname>Jones</surname><given-names>SJ</given-names></name><etal/></person-group>             <year>2009</year>             <article-title>ABySS: A parallel assembler for short read sequence data. Genome Research. 19(6): 1117–1123.</article-title>             <comment>doi: 10.1101/gr.089532.108</comment>           </element-citation>
      </ref>
      <ref id="pone.0039232-Li1">
        <label>8</label>
        <element-citation publication-type="journal" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Li</surname><given-names>R</given-names></name><name name-style="western"><surname>Zhu</surname><given-names>H</given-names></name><name name-style="western"><surname>Ruan</surname><given-names>J</given-names></name><name name-style="western"><surname>Qian</surname><given-names>W</given-names></name><name name-style="western"><surname>Fang</surname><given-names>X</given-names></name><etal/></person-group>             <year>2009</year>             <article-title>De novo assembly of human genomes with massively parallel short read sequencing. Genome Research.</article-title>             <volume>20(2)</volume>             <fpage>265</fpage>             <lpage>72</lpage>          </element-citation>
      </ref>
      <ref id="pone.0039232-Jackson1">
        <label>9</label>
        <element-citation publication-type="other" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Jackson</surname><given-names>BG</given-names></name><name name-style="western"><surname>Regennitter</surname><given-names>M</given-names></name><name name-style="western"><surname>Yang</surname><given-names>X</given-names></name><name name-style="western"><surname>Schnable</surname><given-names>PS</given-names></name><name name-style="western"><surname>Aluru</surname><given-names>S</given-names></name></person-group>             <year>2010</year>             <article-title>Parallel de novo assembly of large genomes from high-throughput short reads. 2010 IEEE International Symposium on Parallel &amp; Distributed Processing (IPDPS).</article-title>             <comment>doi: 10.1109/IPDPS.2010.5470397</comment>           </element-citation>
      </ref>
      <ref id="pone.0039232-Wenyu1">
        <label>10</label>
        <element-citation publication-type="other" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Wenyu</surname><given-names>Z</given-names></name><name name-style="western"><surname>Jiajia</surname><given-names>C</given-names></name><name name-style="western"><surname>Yang</surname><given-names>Y</given-names></name><name name-style="western"><surname>Yifei</surname><given-names>T</given-names></name><name name-style="western"><surname>Jing</surname><given-names>S</given-names></name><etal/></person-group>             <year>2011</year>             <article-title>A Practical Comparison of De Novo Genome Assembly Software Tools for Next-Generation Sequencing Technologies. PLoS ONE. 6(3): e17915.</article-title>             <comment>doi: 10.1371/journal.pone.0017915</comment>           </element-citation>
      </ref>
      <ref id="pone.0039232-Hennessy1">
        <label>11</label>
        <element-citation publication-type="other" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Hennessy</surname><given-names>JL</given-names></name><name name-style="western"><surname>Patterson</surname><given-names>DA</given-names></name></person-group>             <year>2011</year>             <article-title>Computer Architecture, 5th Edition: A Quantitative Approach. Morgan Kaufmann.</article-title>             <source>708 p</source>          </element-citation>
      </ref>
      <ref id="pone.0039232-Culler1">
        <label>12</label>
        <element-citation publication-type="other" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Culler</surname><given-names>D</given-names></name><name name-style="western"><surname>Singh</surname><given-names>JP</given-names></name><name name-style="western"><surname>Gupta</surname><given-names>A</given-names></name></person-group>             <year>1998</year>             <article-title>Parallel Computer Architecture: A Hardware/Software Approach. Morgan Kaufmann.</article-title>             <source>1056 p</source>          </element-citation>
      </ref>
      <ref id="pone.0039232-Pevzner1">
        <label>13</label>
        <element-citation publication-type="journal" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Pevzner</surname><given-names>PA</given-names></name><name name-style="western"><surname>Tang</surname><given-names>H</given-names></name><name name-style="western"><surname>Waterman</surname><given-names>MS</given-names></name></person-group>             <year>2001</year>             <article-title>An Eulerian path approach to DNA fragment assembly. Proc. Natl. Acad. Sci.</article-title>             <volume>98</volume>             <fpage>9748</fpage>             <lpage>9753</lpage>          </element-citation>
      </ref>
      <ref id="pone.0039232-Berger1">
        <label>14</label>
        <element-citation publication-type="other" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Berger</surname><given-names>ED</given-names></name><name name-style="western"><surname>Zorn</surname><given-names>BG</given-names></name><name name-style="western"><surname>McKinley</surname><given-names>KS</given-names></name></person-group>             <year>2002</year>             <article-title>Reconsidering custom memory allocation. ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications.</article-title>             <comment>doi: 10.1145/582419.582421</comment>           </element-citation>
      </ref>
      <ref id="pone.0039232-Richter1">
        <label>15</label>
        <element-citation publication-type="other" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Richter</surname><given-names>DC</given-names></name><name name-style="western"><surname>Ott</surname><given-names>F</given-names></name><name name-style="western"><surname>Auch</surname><given-names>AF</given-names></name><name name-style="western"><surname>Schmid</surname><given-names>R</given-names></name><name name-style="western"><surname>Huson</surname><given-names>DH</given-names></name></person-group>             <year>2008</year>             <article-title>MetaSim-A Sequencing Simulator for Genomics and Metagenomics. PLoS ONE.</article-title>             <comment>doi: 10.1371/journal.pone.0003373</comment>           </element-citation>
      </ref>
      <ref id="pone.0039232-Plantagora1">
        <label>16</label>
        <element-citation publication-type="other" xlink:type="simple">             <article-title>Plantagora Template website.</article-title>             <comment>Available: <ext-link ext-link-type="uri" xlink:href="http://www.plantagora.org/tools_downloads/read_simulation.html" xlink:type="simple">http://www.plantagora.org/tools_downloads/read_simulation.html</ext-link>.</comment>             <comment>Accessed 2012 Feb 1.</comment>          </element-citation>
      </ref>
      <ref id="pone.0039232-Kelley1">
        <label>17</label>
        <element-citation publication-type="other" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Kelley</surname><given-names>DR</given-names></name><name name-style="western"><surname>Schatz</surname><given-names>MC</given-names></name><name name-style="western"><surname>Salzberg</surname><given-names>SL</given-names></name></person-group>             <year>2010</year>             <article-title>Quake: Quality-aware detection and correction of sequencing errors. Genome Biol 11: R116.</article-title>             <comment>doi: 10.1186/gb-2010–11–11-r116</comment>          </element-citation>
      </ref>
      <ref id="pone.0039232-Gnerre1">
        <label>18</label>
        <element-citation publication-type="journal" xlink:type="simple">             <article-title>Gnerre S, Maccallum I, Przybylski D, Ribeiro FJ, Burton JN, et al. 2011. High-quality draft assemblies of mammalian genomes from massively parallel sequence data.</article-title>             <source>Proc Natl Acad Sci</source>             <volume>108</volume>             <fpage>1513</fpage>             <lpage>1518</lpage>          </element-citation>
      </ref>
      <ref id="pone.0039232-Marteb1">
        <label>19</label>
        <element-citation publication-type="other" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Marteb</surname><given-names>B</given-names></name><name name-style="western"><surname>Christiaan</surname><given-names>VH</given-names></name><name name-style="western"><surname>Hans</surname><given-names>JJ</given-names></name><name name-style="western"><surname>Derek</surname><given-names>B</given-names></name><name name-style="western"><surname>Walter</surname><given-names>P</given-names></name></person-group>             <year>2010</year>             <article-title>Scaffolding pre-assembled contigs using SSPACE. Bioinformatics. 27(4): 578–579.</article-title>             <comment>doi: 10.1093/bioinformatics/btq683</comment>           </element-citation>
      </ref>
      <ref id="pone.0039232-Zhang1">
        <label>20</label>
        <element-citation publication-type="journal" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Zhang</surname><given-names>Z</given-names></name><name name-style="western"><surname>Schwartz</surname><given-names>S</given-names></name><name name-style="western"><surname>Wagner</surname><given-names>L</given-names></name><name name-style="western"><surname>Miller</surname><given-names>W</given-names></name></person-group>             <year>2000</year>             <article-title>A greedy algorithm for aligning DNA sequences. J Comput Biol.</article-title>             <volume>7(1–2)</volume>             <fpage>203</fpage>             <lpage>14</lpage>          </element-citation>
      </ref>
      <ref id="pone.0039232-Stephen1">
        <label>21</label>
        <element-citation publication-type="other" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Stephen</surname><given-names>FA</given-names></name><name name-style="western"><surname>Warren</surname><given-names>G</given-names></name><name name-style="western"><surname>Webb</surname><given-names>M</given-names></name><name name-style="western"><surname>Eugene</surname><given-names>WM</given-names></name><name name-style="western"><surname>David</surname><given-names>JL</given-names></name></person-group>             <year>1990</year>             <article-title>Basic local alignment search tool. J. Mol. Bio. 215(3): 403–410.</article-title>             <comment>doi: 10.1006/jmbi.1990.9999</comment>           </element-citation>
      </ref>
      <ref id="pone.0039232-Marais1">
        <label>22</label>
        <element-citation publication-type="other" xlink:type="simple">             <person-group person-group-type="author"><name name-style="western"><surname>Marçais</surname><given-names>G</given-names></name><name name-style="western"><surname>Kingsford</surname><given-names>C</given-names></name></person-group>             <year>2011</year>             <article-title>A fast, lock-free approach for efficient parallel counting of occurrences of k-mers. Bioinformatics. 27 (6): 764–770.</article-title>             <comment>doi: 10.1093/bioinformatics/btr011</comment>           </element-citation>
      </ref>
    </ref-list>
    
  </back>
</article>