<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0" xml:lang="en">
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>Software for Computing and Annotating Genomic Ranges</title>
        <author>Michael Lawrence</author>
        <author>Wolfgang Huber</author>
        <author>Hervé Pagès</author>
        <author>Patrick Aboyoun</author>
        <author>Marc Carlson</author>
        <author>Robert Gentleman</author>
        <author>Martin T. Morgan</author>
        <author>Vincent J. Carey</author>
      </titleStmt>
      <publicationStmt>
        <p>Tag layer of the DHSS Meta-Tagging Project. The article text is reproduced from the
           staged copy named in sourceDesc and is not altered; the tags are held separately in
           standOff so that overlapping and nested spans are preserved.</p>
      </publicationStmt>
      <sourceDesc>
        <bibl>
          <title>Software for Computing and Annotating Genomic Ranges</title>
          <date>2013</date>
          <publisher>PLoS Computational Biology</publisher>
          <idno type="DOI">10.1371/journal.pcbi.1003118</idno>
          
          <idno type="record">lawrence2013-genomic-ranges-software</idno>
          <note type="staged-file">lawrence2013-genomic-ranges-software.txt, the project's staged copy</note>
          <note type="text-sha1">680c646eb8dcabf4ac4f9d51d9f922128c8e1d73</note>
          <note type="rights">cc-by</note>
        </bibl>
      </sourceDesc>
    </fileDesc>
    <profileDesc>
      <textClass><keywords><term>genomics</term></keywords></textClass>
      <particDesc>
        <person xml:id="paper"><p>the paper's own words</p></person>
        <person xml:id="tagger"><p>the tag layer; a sentence written by the tagger about the
          paper, always anchored to a quotation but not itself a quotation</p></person>
      </particDesc>
    </profileDesc>
    <revisionDesc>
      <change when="2026-10-06"
              who="build_paper_edition.py">173 spans located by searching the stored text for the quote's exact words, allowing any whitespace between them</change>
    </revisionDesc>
  </teiHeader>
  <standOff>
    <spanGrp type="tags">
      <span xml:id="t0" from="#a1" to="#a2" type="object_of_study" ana="#object_of_study" resp="#paper">software infrastructure for representing, computing on, annotating, and integrating genomic ranges in R</span>
      <span xml:id="t1" from="#a9" to="#a10" type="research_question" ana="#research_question" resp="#paper">how to make range-based genomic analysis efficient, interoperable, reproducible, and statistically integrated across packages and data types</span>
      <span xml:id="t2" from="#a15" to="#a18" type="contribution" ana="#contribution" resp="#paper">the IRanges, GenomicRanges, and GenomicFeatures infrastructure with scalable range structures, operations, annotation access, and experiment containers</span>
      <span xml:id="t3" from="#a1" to="#a2" type="claim_type" ana="#claim_type" resp="#paper">method</span>
      <span xml:id="t4" from="#a3" to="#a4" type="phenomenon" ana="#phenomenon" resp="#paper">genome-coordinate integration, interval overlap, hierarchical range structure, compressed coverage, genomic annotation, and reproducible cross-package analysis</span>
      <span xml:id="t5" from="#a15" to="#a18" type="method" ana="#method" resp="#paper">system-or-tool-building<term>system-or-tool-building</term></span>
      <span xml:id="t6" from="#a3" to="#a4" type="mechanisms" ana="#mechanisms[0]" resp="#tagger" cert="0.95">Represents annotations and measurements on the same coordinate intervals.<term>common genome-range scaffold</term></span>
      <span xml:id="t7" from="#a13" to="#a14" type="mechanisms" ana="#mechanisms[1]" resp="#tagger" cert="0.95">Communicates structure definitions to R and delegates integrity and dispatch to the language.<term>formal range classes</term></span>
      <span xml:id="t8" from="#a9" to="#a10" type="mechanisms" ana="#mechanisms[2]" resp="#tagger" cert="0.95">Allows routines across packages to interoperate without repeated conversion.<term>shared in-memory data structures</term></span>
      <span xml:id="t9" from="#a31" to="#a32" type="mechanisms" ana="#mechanisms[3]" resp="#tagger" cert="0.95">Uses one interface with class-specific behavior for simple and genomic ranges.<term>generic-function specialization</term></span>
      <span xml:id="t10" from="#a27" to="#a28" type="mechanisms" ana="#mechanisms[4]" resp="#tagger" cert="0.95">Indexes ranges once and answers vectorized queries in logarithmic time.<term>interval-tree overlap detection</term></span>
      <span xml:id="t11" from="#a29" to="#a30" type="mechanisms" ana="#mechanisms[5]" resp="#tagger" cert="0.95">Adds sequence name, strand, and reference-build tracking to range objects.<term>genomic semantic metadata</term></span>
      <span xml:id="t12" from="#a33" to="#a34" type="mechanisms" ana="#mechanisms[6]" resp="#tagger" cert="0.95">Groups exons, transcripts, or alignment segments into GRangesList elements.<term>compound-feature lists</term></span>
      <span xml:id="t13" from="#a35" to="#a36" type="mechanisms" ana="#mechanisms[7]" resp="#tagger" cert="0.95">Distills UCSC, Biomart, and GTF/GFF sources into a TranscriptDb schema.<term>annotation-source normalization</term></span>
      <span xml:id="t14" from="#a39" to="#a40" type="mechanisms" ana="#mechanisms[8]" resp="#tagger" cert="0.95">Stores annotations in a DataFrame capable of vector-like genomic columns.<term>complex-column metadata</term></span>
      <span xml:id="t15" from="#a49" to="#a50" type="mechanisms" ana="#mechanisms[9]" resp="#tagger" cert="0.95">Compresses repeated genome-length vector values behind a standard vector API.<term>run-length encoding</term></span>
      <span xml:id="t16" from="#a51" to="#a52" type="mechanisms" ana="#mechanisms[10]" resp="#tagger" cert="0.95">Converts gapped read alignments to GRanges or GRangesList according to the desired unit.<term>alignment coercion</term></span>
      <span xml:id="t17" from="#a55" to="#a56" type="mechanisms" ana="#mechanisms[11]" resp="#tagger" cert="0.95">Counts overlaps into a matrix and retains region, sample, and experiment annotations.<term>feature-by-sample summarization</term></span>
      <span xml:id="t18" from="#a19" to="#a20" type="limitations" ana="#limitations[0]" resp="#tagger" cert="0.95">File-format interoperability can yield heterogeneous workflows that are hard to maintain and reproduce.</span>
      <span xml:id="t19" from="#a29" to="#a30" type="limitations" ana="#limitations[1]" resp="#tagger" cert="0.95">IRanges alone omits chromosome, strand, and other genomic semantics.</span>
      <span xml:id="t20" from="#a11" to="#a12" type="limitations" ana="#limitations[2]" resp="#tagger" cert="0.95">Whether exons should be individual ranges or compound transcripts depends on the use case.</span>
      <span xml:id="t21" from="#a51" to="#a52" type="limitations" ana="#limitations[3]" resp="#tagger" cert="0.95">The best alignment structure depends on whether analysis counts pairs, reads, or gap-separated segments.</span>
      <span xml:id="t22" from="#a57" to="#a58" type="limitations" ana="#limitations[4]" resp="#tagger" cert="0.95">CTCF binding inferences require explicit treatment of base-calling and mapping errors plus wet-lab validation.</span>
      <span xml:id="t23" from="#a59" to="#a60" type="limitations" ana="#limitations[5]" resp="#tagger" cert="0.95">Aberrant quality distributions and batch-specific quality scales required exclusion and correction.</span>
      <span xml:id="t24" from="#a63" to="#a64" type="limitations" ana="#limitations[6]" resp="#tagger" cert="0.9">Off-SNP imbalance calls were frequently low quality and unlikely to replicate.</span>
      <span xml:id="t25" from="#a65" to="#a66" type="limitations" ana="#limitations[7]" resp="#tagger" cert="0.9">Apparent allele imbalance mixes biology with sequencing and read-mapping artifacts.</span>
      <span xml:id="t26" from="#a69" to="#a70" type="limitations" ana="#limitations[8]" resp="#tagger" cert="0.95">The infrastructure still lacked better range visualizations for RNA-seq and variant-calling diagnostics.</span>
      <span xml:id="t27" from="#a69" to="#a70" type="limitations" ana="#limitations[9]" resp="#tagger" cert="0.95">Growing data volume creates continuing demand for more efficient and parallel algorithms.</span>
      <span xml:id="t28" from="#a43" to="#a44" type="controls" ana="#controls[0]" resp="#tagger" cert="0.95">GFP antibody sample<note>eliminates: non-specific ChIP enrichment</note></span>
      <span xml:id="t29" from="#a71" to="#a72" type="controls" ana="#controls[1]" resp="#tagger" cert="0.95">funders&#x27; role<note>eliminates: funder control over design, analysis, publication, or manuscript preparation · outcome: held</note></span>
      <span xml:id="t30" from="#a1" to="#a2" type="concepts" ana="#concepts[0]" resp="#paper" cert="0.95">Bioconductor infrastructure<term>Bioconductor infrastructure</term></span>
      <span xml:id="t31" from="#a1" to="#a2" type="concepts" ana="#concepts[1]" resp="#paper" cert="0.95">annotated genomic ranges<term>annotated genomic ranges</term></span>
      <span xml:id="t32" from="#a15" to="#a18" type="concepts" ana="#concepts[2]" resp="#paper" cert="0.95">IRanges<term>IRanges</term></span>
      <span xml:id="t33" from="#a15" to="#a18" type="concepts" ana="#concepts[3]" resp="#paper" cert="0.95">GenomicRanges<term>GenomicRanges</term></span>
      <span xml:id="t34" from="#a15" to="#a18" type="concepts" ana="#concepts[4]" resp="#paper" cert="0.95">GenomicFeatures<term>GenomicFeatures</term></span>
      <span xml:id="t35" from="#a15" to="#a18" type="concepts" ana="#concepts[5]" resp="#paper" cert="0.95">core of the infrastructure<term>core of the infrastructure</term></span>
      <span xml:id="t36" from="#a1" to="#a2" type="concepts" ana="#concepts[6]" resp="#paper" cert="0.95">scalable data structures<term>scalable data structures</term></span>
      <span xml:id="t37" from="#a1" to="#a2" type="concepts" ana="#concepts[7]" resp="#paper" cert="0.95">transcript structures<term>transcript structures</term></span>
      <span xml:id="t38" from="#a1" to="#a2" type="concepts" ana="#concepts[8]" resp="#paper" cert="0.95">read alignments<term>read alignments</term></span>
      <span xml:id="t39" from="#a1" to="#a2" type="concepts" ana="#concepts[9]" resp="#paper" cert="0.95">coverage vectors<term>coverage vectors</term></span>
      <span xml:id="t40" from="#a1" to="#a2" type="concepts" ana="#concepts[10]" resp="#paper" cert="0.95">overlap detection<term>overlap detection</term></span>
      <span xml:id="t41" from="#a1" to="#a2" type="concepts" ana="#concepts[11]" resp="#paper" cert="0.95">nearest neighbor detection<term>nearest neighbor detection</term></span>
      <span xml:id="t42" from="#a1" to="#a2" type="concepts" ana="#concepts[12]" resp="#paper" cert="0.95">range operations<term>range operations</term></span>
      <span xml:id="t43" from="#a3" to="#a4" type="concepts" ana="#concepts[13]" resp="#paper" cert="0.95">linear sequence<term>linear sequence</term></span>
      <span xml:id="t44" from="#a3" to="#a4" type="concepts" ana="#concepts[14]" resp="#paper" cert="0.95">annotations<term>annotations</term></span>
      <span xml:id="t45" from="#a3" to="#a4" type="concepts" ana="#concepts[15]" resp="#paper" cert="0.95">primary experimental measurements<term>primary experimental measurements</term></span>
      <span xml:id="t46" from="#a3" to="#a4" type="concepts" ana="#concepts[16]" resp="#paper" cert="0.95">common scaffold<term>common scaffold</term></span>
      <span xml:id="t47" from="#a3" to="#a4" type="concepts" ana="#concepts[17]" resp="#paper" cert="0.95">genomic data analysis<term>genomic data analysis</term></span>
      <span xml:id="t48" from="#a7" to="#a8" type="concepts" ana="#concepts[18]" resp="#paper" cert="0.95">intersection<term>intersection</term></span>
      <span xml:id="t49" from="#a7" to="#a8" type="concepts" ana="#concepts[19]" resp="#paper" cert="0.95">union<term>union</term></span>
      <span xml:id="t50" from="#a7" to="#a8" type="concepts" ana="#concepts[20]" resp="#paper" cert="0.95">complement<term>complement</term></span>
      <span xml:id="t51" from="#a9" to="#a10" type="concepts" ana="#concepts[21]" resp="#paper" cert="0.95">specialized, formal data structures<term>specialized, formal data structures</term></span>
      <span xml:id="t52" from="#a9" to="#a10" type="concepts" ana="#concepts[22]" resp="#paper" cert="0.95">application programming interface (API)<term>application programming interface (API)</term></span>
      <span xml:id="t53" from="#a9" to="#a10" type="concepts" ana="#concepts[23]" resp="#paper" cert="0.95">interoperability<term>interoperability</term></span>
      <span xml:id="t54" from="#a9" to="#a10" type="concepts" ana="#concepts[24]" resp="#paper" cert="0.95">abstraction<term>abstraction</term></span>
      <span xml:id="t55" from="#a9" to="#a10" type="concepts" ana="#concepts[25]" resp="#paper" cert="0.95">robust, maintainable software<term>robust, maintainable software</term></span>
      <span xml:id="t56" from="#a11" to="#a12" type="concepts" ana="#concepts[26]" resp="#paper" cert="0.95">per-range metadata<term>per-range metadata</term></span>
      <span xml:id="t57" from="#a13" to="#a14" type="concepts" ana="#concepts[27]" resp="#paper" cert="0.95">generic function<term>generic function</term></span>
      <span xml:id="t58" from="#a13" to="#a14" type="concepts" ana="#concepts[28]" resp="#paper" cert="0.95">method<term>method</term></span>
      <span xml:id="t59" from="#a21" to="#a22" type="concepts" ana="#concepts[29]" resp="#paper" cert="0.95">range<term>range</term></span>
      <span xml:id="t60" from="#a21" to="#a22" type="concepts" ana="#concepts[30]" resp="#paper" cert="0.95">ordered set of consecutive integers<term>ordered set of consecutive integers</term></span>
      <span xml:id="t61" from="#a23" to="#a24" type="concepts" ana="#concepts[31]" resp="#paper" cert="0.95">IRanges class<term>IRanges class</term></span>
      <span xml:id="t62" from="#a29" to="#a30" type="concepts" ana="#concepts[32]" resp="#paper" cert="0.95">GRanges class<term>GRanges class</term></span>
      <span xml:id="t63" from="#a29" to="#a30" type="concepts" ana="#concepts[33]" resp="#paper" cert="0.95">reference genome sequence<term>reference genome sequence</term></span>
      <span xml:id="t64" from="#a33" to="#a34" type="concepts" ana="#concepts[34]" resp="#paper" cert="0.95">GRangesList<term>GRangesList</term></span>
      <span xml:id="t65" from="#a33" to="#a34" type="concepts" ana="#concepts[35]" resp="#paper" cert="0.95">compound feature<term>compound feature</term></span>
      <span xml:id="t66" from="#a37" to="#a38" type="concepts" ana="#concepts[36]" resp="#paper" cert="0.95">TranscriptDb<term>TranscriptDb</term></span>
      <span xml:id="t67" from="#a39" to="#a40" type="concepts" ana="#concepts[37]" resp="#paper" cert="0.95">DataFrame<term>DataFrame</term></span>
      <span xml:id="t68" from="#a39" to="#a40" type="concepts" ana="#concepts[38]" resp="#paper" cert="0.95">primary data<term>primary data</term></span>
      <span xml:id="t69" from="#a39" to="#a40" type="concepts" ana="#concepts[39]" resp="#paper" cert="0.95">metadata<term>metadata</term></span>
      <span xml:id="t70" from="#a41" to="#a42" type="concepts" ana="#concepts[40]" resp="#paper" cert="0.95">coverage<term>coverage</term></span>
      <span xml:id="t71" from="#a41" to="#a42" type="concepts" ana="#concepts[41]" resp="#paper" cert="0.95">number of features in the data set overlapping each position in the genome<term>number of features in the data set overlapping each position in the genome</term></span>
      <span xml:id="t72" from="#a49" to="#a50" type="concepts" ana="#concepts[42]" resp="#paper" cert="0.95">Rle<term>Rle</term></span>
      <span xml:id="t73" from="#a49" to="#a50" type="concepts" ana="#concepts[43]" resp="#paper" cert="0.95">run-length encoded vector<term>run-length encoded vector</term></span>
      <span xml:id="t74" from="#a51" to="#a52" type="concepts" ana="#concepts[44]" resp="#paper" cert="0.95">BAM file<term>BAM file</term></span>
      <span xml:id="t75" from="#a51" to="#a52" type="concepts" ana="#concepts[45]" resp="#paper" cert="0.95">GappedAlignments<term>GappedAlignments</term></span>
      <span xml:id="t76" from="#a55" to="#a56" type="concepts" ana="#concepts[46]" resp="#paper" cert="0.95">SummarizedExperiment<term>SummarizedExperiment</term></span>
      <span xml:id="t77" from="#a55" to="#a56" type="concepts" ana="#concepts[47]" resp="#paper" cert="0.95">ExpressionSet<term>ExpressionSet</term></span>
      <span xml:id="t78" from="#a59" to="#a60" type="concepts" ana="#concepts[48]" resp="#paper" cert="0.95">allele-specific protein-DNA binding<term>allele-specific protein-DNA binding</term></span>
      <span xml:id="t79" from="#a63" to="#a64" type="concepts" ana="#concepts[49]" resp="#paper" cert="0.95">alternate nucleotide proportion<term>alternate nucleotide proportion</term></span>
      <span xml:id="t80" from="#a63" to="#a64" type="concepts" ana="#concepts[50]" resp="#paper" cert="0.95">ANP<term>ANP</term></span>
      <span xml:id="t81" from="#a63" to="#a64" type="concepts" ana="#concepts[51]" resp="#paper" cert="0.95">base-call quality<term>base-call quality</term></span>
      <span xml:id="t82" from="#a65" to="#a66" type="concepts" ana="#concepts[52]" resp="#paper" cert="0.95">technical artifacts<term>technical artifacts</term></span>
      <span xml:id="t83" from="#a67" to="#a68" type="concepts" ana="#concepts[53]" resp="#paper" cert="0.95">growing ecosystem of packages<term>growing ecosystem of packages</term></span>
      <span xml:id="t84" from="#a69" to="#a70" type="concepts" ana="#concepts[54]" resp="#paper" cert="0.95">core infrastructure for sequence analysis<term>core infrastructure for sequence analysis</term></span>
      <span xml:id="t85" from="#a69" to="#a70" type="concepts" ana="#concepts[55]" resp="#paper" cert="0.95">parallel computing<term>parallel computing</term></span>
      <span xml:id="t86" from="#a19" to="#a20" type="concepts" ana="#concepts[56]" resp="#paper" cert="0.95">other software tools<term>other software tools</term></span>
      <span xml:id="t87" from="#a45" to="#a46" type="concepts" ana="#concepts[57]" resp="#paper" cert="0.95">ctcfReads object<term>ctcfReads object</term></span>
      <span xml:id="t88" from="#a45" to="#a46" type="concepts" ana="#concepts[58]" resp="#paper" cert="0.95">GRanges<term>GRanges</term></span>
      <span xml:id="t89" from="#a53" to="#a54" type="concepts" ana="#concepts[59]" resp="#paper" cert="0.95">countOverlaps<term>countOverlaps</term></span>
      <span xml:id="t90" from="#a55" to="#a56" type="concepts" ana="#concepts[60]" resp="#paper" cert="0.95">summarizeOverlaps<term>summarizeOverlaps</term></span>
      <span xml:id="t91" from="#a21" to="#a22" type="unhoused_relations" ana="#unhoused_relations[0]" resp="#tagger" cert="0.95">range → ordered set of consecutive integers<note>The paper uses the term range to denote an ordered set of consecutive integers.</note></span>
      <span xml:id="t92" from="#a23" to="#a24" type="unhoused_relations" ana="#unhoused_relations[1]" resp="#tagger" cert="0.95">GenomicRanges → IRanges<note>GenomicRanges builds on IRanges by adding biological semantics.</note></span>
      <span xml:id="t93" from="#a9" to="#a10" type="unhoused_relations" ana="#unhoused_relations[2]" resp="#tagger" cert="0.95">same data structures → cumbersome conversions<note>Shared structures remove the need for cumbersome cross-package conversions.</note></span>
      <span xml:id="t94" from="#a45" to="#a46" type="unhoused_relations" ana="#unhoused_relations[3]" resp="#tagger" cert="0.95">tracking chromosome information → genome-assembly mixing errors<note>Chromosome tracking guards against mixing assemblies.</note></span>
      <span xml:id="t95" from="#a37" to="#a38" type="unhoused_relations" ana="#unhoused_relations[4]" resp="#tagger" cert="0.95">TranscriptDb class → database<note>The annotation database is represented by TranscriptDb.</note></span>
      <span xml:id="t96" from="#a49" to="#a50" type="unhoused_relations" ana="#unhoused_relations[5]" resp="#tagger" cert="0.95">Rle → run-length encoded vector<note>Rle represents a run-length encoded vector.</note></span>
      <span xml:id="t97" from="#a53" to="#a54" type="unhoused_relations" ana="#unhoused_relations[6]" resp="#tagger" cert="0.95">summarizeOverlaps → reads that map to multiple features<note>summarizeOverlaps discards reads mapping to multiple features.</note></span>
      <span xml:id="t98" from="#a63" to="#a64" type="unhoused_relations" ana="#unhoused_relations[7]" resp="#tagger" cert="0.9">base-call quality → replication<note>Low base-call quality implies that off-SNP imbalance findings are unlikely to replicate.</note></span>
      <span xml:id="t99" from="#a65" to="#a66" type="unhoused_relations" ana="#unhoused_relations[8]" resp="#tagger" cert="0.9">technical artifacts → apparent imbalances<note>Technical artifacts contribute to the mixture observed as apparent allelic imbalance.</note></span>
      <span xml:id="t100" from="#a33" to="#a34" type="unhoused_relations" ana="#unhoused_relations[9]" resp="#tagger" cert="0.95">GRangesList → GRanges objects<note>Multiple GRanges objects are combined into a GRangesList.</note></span>
      <span xml:id="t101" from="#a3" to="#a4" type="senses" ana="#senses[0]" resp="#tagger" cert="0.95">genome as a coordinate scaffold linking processed annotations and primary measurements</span>
      <span xml:id="t102" from="#a21" to="#a22" type="senses" ana="#senses[1]" resp="#tagger" cert="0.95">range as an ordered integer interval rather than an informal genomic region</span>
      <span xml:id="t103" from="#a9" to="#a10" type="senses" ana="#senses[2]" resp="#tagger" cert="0.95">range API as conceptual language hiding optimized implementation detail</span>
      <span xml:id="t104" from="#a9" to="#a10" type="senses" ana="#senses[3]" resp="#tagger" cert="0.95">interoperability as shared in-memory structures across Bioconductor packages</span>
      <span xml:id="t105" from="#a29" to="#a30" type="senses" ana="#senses[4]" resp="#tagger" cert="0.95">GRanges as IRanges plus chromosome, strand, and reference-build semantics</span>
      <span xml:id="t106" from="#a33" to="#a34" type="senses" ana="#senses[5]" resp="#tagger" cert="0.95">GRangesList as hierarchy-preserving compound-feature representation</span>
      <span xml:id="t107" from="#a41" to="#a42" type="senses" ana="#senses[6]" resp="#tagger" cert="0.95">coverage as the count of features overlapping each genomic position</span>
      <span xml:id="t108" from="#a49" to="#a50" type="senses" ana="#senses[7]" resp="#tagger" cert="0.95">Rle as compressed storage with ordinary-vector behavior</span>
      <span xml:id="t109" from="#a55" to="#a56" type="senses" ana="#senses[8]" resp="#tagger" cert="0.95">SummarizedExperiment as coordinated feature, sample, region, and experiment data</span>
      <span xml:id="t110" from="#a65" to="#a66" type="senses" ana="#senses[9]" resp="#tagger" cert="0.95">allelic imbalance as a signal requiring separation of biology from technical artifacts</span>
      <span xml:id="t111" from="#a1" to="#a2" type="claim_relations" ana="#claim_relations[0]" resp="#tagger" cert="0.95">builds-on → R statistical computing and Bioconductor extensions<note>note: The infrastructure integrates range data with established R facilities.</note></span>
      <span xml:id="t112" from="#a23" to="#a24" type="claim_relations" ana="#claim_relations[1]" resp="#tagger" cert="0.95">extends → IRanges with biological sequence and strand semantics<note>note: GenomicRanges builds on the general range package.</note></span>
      <span xml:id="t113" from="#a19" to="#a20" type="claim_relations" ana="#claim_relations[2]" resp="#tagger" cert="0.95">contrasts-with → file-centered UNIX range workflows<note>note: The paper contrasts in-memory integration with heterogeneous scripts and files.</note></span>
      <span xml:id="t114" from="#a67" to="#a68" type="claim_relations" ana="#claim_relations[3]" resp="#tagger" cert="0.95">supports → shared range structures as a cross-package foundation<note>note: The direct dependent-package count documents adoption.</note></span>
      <span xml:id="t115" from="#a65" to="#a66" type="claim_relations" ana="#claim_relations[4]" resp="#tagger" cert="0.95">qualifies → allele-dependent CTCF calls as direct biological findings<note>note: The authors attribute the observed imbalance to a mixture of biology and artifacts.</note></span>
      <span xml:id="t116" from="#a16" to="#a17" type="concept_edges" ana="#concept_edges[0]" resp="#tagger" cert="0.95">IRanges —part-of→ core of the infrastructure<note>the relation itself is separately evidenced · strength of the relation: 1 · note: Direct package containment. · the relation stated: IRanges is included in the core infrastructure.</note><term>IRanges</term><term>core of the infrastructure</term></span>
      <span xml:id="t117" from="#a16" to="#a17" type="concept_edges" ana="#concept_edges[1]" resp="#tagger" cert="0.95">GenomicRanges —part-of→ core of the infrastructure<note>the relation itself is separately evidenced · strength of the relation: 1 · note: Direct package containment. · the relation stated: GenomicRanges is included in the core infrastructure.</note><term>GenomicRanges</term><term>core of the infrastructure</term></span>
      <span xml:id="t118" from="#a16" to="#a17" type="concept_edges" ana="#concept_edges[2]" resp="#tagger" cert="0.95">GenomicFeatures —part-of→ core of the infrastructure<note>the relation itself is separately evidenced · strength of the relation: 1 · note: Direct package containment. · the relation stated: GenomicFeatures is included in the core infrastructure.</note><term>GenomicFeatures</term><term>core of the infrastructure</term></span>
      <span xml:id="t119" from="#a19" to="#a20" type="concept_edges" ana="#concept_edges[3]" resp="#tagger" cert="0.95">Bioconductor infrastructure —contrasted-with→ other software tools<note>the relation itself is separately evidenced · strength of the relation: 0.95 · note: Flat methodological comparison. · the relation stated: The Bioconductor infrastructure is contrasted with file-centered command-line tools.</note><term>Bioconductor infrastructure</term><term>other software tools</term></span>
      <span xml:id="t120" from="#a29" to="#a30" type="concept_edges" ana="#concept_edges[4]" resp="#tagger" cert="0.95">GenomicRanges —distinct-from→ IRanges<note>the relation itself is separately evidenced · strength of the relation: 0.95 · note: Explicit missing-feature distinction. · the relation stated: IRanges omits chromosome and strand while GenomicRanges adds genomic semantics.</note><term>GenomicRanges</term><term>IRanges</term></span>
      <span xml:id="t121" from="#a51" to="#a52" type="concept_edges" ana="#concept_edges[5]" resp="#tagger" cert="0.95">GRanges —distinct-from→ GRangesList<note>the relation itself is separately evidenced · strength of the relation: 0.95 · note: Flat representation distinction. · the relation stated: GRanges holds ungapped extents whereas GRangesList retains gaps.</note><term>GRanges</term><term>GRangesList</term></span>
      <span xml:id="t122" from="#a53" to="#a54" type="concept_edges" ana="#concept_edges[6]" resp="#tagger" cert="0.95">countOverlaps —contrasted-with→ summarizeOverlaps<note>the relation itself is separately evidenced · strength of the relation: 0.95 · note: Flat method comparison. · the relation stated: summarizeOverlaps discards multi-feature reads unlike countOverlaps.</note><term>countOverlaps</term><term>summarizeOverlaps</term></span>
      <span xml:id="t123" from="#a55" to="#a56" type="concept_edges" ana="#concept_edges[7]" resp="#tagger" cert="0.95">SummarizedExperiment —distinct-from→ ExpressionSet<note>the relation itself is separately evidenced · strength of the relation: 0.95 · note: The paper explicitly names the primary difference. · the relation stated: SummarizedExperiment differs from ExpressionSet by being based on IRanges.
Audit 2026-09-28: DOUBTFUL - read against its full span and kept, but the span says SummarizedExperiment follows the same pattern as ExpressionSet with one primary difference; distinct-from is loose.</note><term>SummarizedExperiment</term><term>ExpressionSet</term></span>
      <span xml:id="t124" from="#a41" to="#a42" type="concept_edges" ana="#concept_edges[8]" resp="#tagger" cert="0.95">coverage —operationalised-as→ number of features in the data set overlapping each position in the genome<note>the relation itself is separately evidenced · strength of the relation: 1 · note: Exact operational definition. · the relation stated: Coverage is defined as the number of overlapping features at each genomic position.</note><term>coverage</term><term>number of features in the data set overlapping each position in the genome</term></span>
      <span xml:id="t125" from="#a63" to="#a64" type="concept_edges" ana="#concept_edges[9]" resp="#tagger" cert="0.95">alternate nucleotide proportion —same-as→ ANP<note>the relation itself is separately evidenced · strength of the relation: 1 · note: Parenthetical naming equivalence. · the relation stated: Alternate nucleotide proportion is abbreviated ANP.</note><term>alternate nucleotide proportion</term><term>ANP</term></span>
      <span xml:id="t126" from="#a9" to="#a10" type="concept_edges" ana="#concept_edges[10]" resp="#tagger" cert="0.95">abstraction —causes→ robust, maintainable software<note>direction on the measure: increases · the relation itself is separately evidenced · strength of the relation: 0.9 · note: The causal sentence attributes the outcome jointly to the listed benefits. · the relation stated: Abstraction and related benefits lead to more robust, maintainable software.
Audit 2026-09-28: DOUBTFUL - read against its full span and kept, but the span says efficiency, interoperability and abstraction TOGETHER lead to robust, maintainable software; the cause is shared.</note><term>abstraction</term><term>robust, maintainable software</term></span>
      <span xml:id="t127" from="#a45" to="#a46" type="concept_edges" ana="#concept_edges[11]" resp="#tagger" cert="0.95">ctcfReads object —is-a→ GRanges<note>the relation itself is separately evidenced · strength of the relation: 1 · note: Direct categorical statement. · the relation stated: The ctcfReads object is a GRanges.</note><term>ctcfReads object</term><term>GRanges</term></span>
      <span xml:id="t128" from="#a3" to="#a4" type="content_tags" ana="#content_tags.findings[0]" resp="#tagger" cert="0.95">Treating annotations and measurements as genome ranges provides a common scaffold for integration.</span>
      <span xml:id="t129" from="#a5" to="#a6" type="content_tags" ana="#content_tags.findings[1]" resp="#tagger" cert="0.95">Range operations underlie gene-model manipulation, coverage, peak annotation, and expression estimation.</span>
      <span xml:id="t130" from="#a9" to="#a10" type="content_tags" ana="#content_tags.findings[2]" resp="#tagger" cert="0.95">Explicit range APIs improve efficiency, readability, interoperability, and maintainability.</span>
      <span xml:id="t131" from="#a13" to="#a14" type="content_tags" ana="#content_tags.findings[3]" resp="#tagger" cert="0.95">Shared formal classes let the language regulate access, integrity, and method dispatch.</span>
      <span xml:id="t132" from="#a15" to="#a18" type="content_tags" ana="#content_tags.findings[4]" resp="#tagger" cert="0.95">The three core packages directly support more than eighty other Bioconductor packages.</span>
      <span xml:id="t133" from="#a19" to="#a20" type="content_tags" ana="#content_tags.findings[5]" resp="#tagger" cert="0.95">Command-line, file-centered workflows can be difficult to maintain and reproduce.</span>
      <span xml:id="t134" from="#a27" to="#a28" type="content_tags" ana="#content_tags.findings[6]" resp="#tagger" cert="0.95">Interval-tree overlap queries are vectorized and implemented in C to avoid expensive R iteration.</span>
      <span xml:id="t135" from="#a29" to="#a30" type="content_tags" ana="#content_tags.findings[7]" resp="#tagger" cert="0.95">GenomicRanges adds chromosome, strand, and genome-build semantics absent from simple IRanges.</span>
      <span xml:id="t136" from="#a31" to="#a32" type="content_tags" ana="#content_tags.findings[8]" resp="#tagger" cert="0.95">Method specialization provides one interface over different data structures and makes user code more robust.</span>
      <span xml:id="t137" from="#a35" to="#a36" type="content_tags" ana="#content_tags.findings[9]" resp="#tagger" cert="0.95">GenomicFeatures normalizes multiple annotation sources behind a reproducible database API.</span>
      <span xml:id="t138" from="#a49" to="#a50" type="content_tags" ana="#content_tags.findings[10]" resp="#tagger" cert="0.95">Run-length encoding compresses genome-length vectors while preserving an ordinary-vector interface.</span>
      <span xml:id="t139" from="#a55" to="#a56" type="content_tags" ana="#content_tags.findings[11]" resp="#tagger" cert="0.95">SummarizedExperiment stores feature-by-sample summaries together with region, sample, and experiment annotations.</span>
      <span xml:id="t140" from="#a63" to="#a64" type="content_tags" ana="#content_tags.findings[12]" resp="#tagger" cert="0.9">The CTCF example yielded thousands of allele-dependent sites but exposed quality-linked replication risk.</span>
      <span xml:id="t141" from="#a65" to="#a66" type="content_tags" ana="#content_tags.findings[13]" resp="#tagger" cert="0.9">Observed CTCF imbalances likely mix biological signal with sequencing and mapping artifacts.</span>
      <span xml:id="t142" from="#a67" to="#a68" type="content_tags" ana="#content_tags.findings[14]" resp="#tagger" cert="0.95">More than eighty packages formed a dependent ecosystem around the ranges infrastructure.</span>
      <span xml:id="t143" from="#a21" to="#a22" type="content_tags" ana="#content_tags.definitions[0]" resp="#tagger" cert="0.95">an ordered set of consecutive integers<term>range</term></span>
      <span xml:id="t144" from="#a41" to="#a42" type="content_tags" ana="#content_tags.definitions[1]" resp="#tagger" cert="0.95">the count of features overlapping every genomic position<term>coverage</term></span>
      <span xml:id="t145" from="#a13" to="#a14" type="content_tags" ana="#content_tags.definitions[2]" resp="#tagger" cert="0.95">a function dispatching to a class-dependent implementation<term>generic function</term></span>
      <span xml:id="t146" from="#a13" to="#a14" type="content_tags" ana="#content_tags.definitions[3]" resp="#tagger" cert="0.95">the implementation selected by generic-function dispatch<term>method</term></span>
      <span xml:id="t147" from="#a33" to="#a34" type="content_tags" ana="#content_tags.definitions[4]" resp="#tagger" cert="0.95">a list whose elements are compound GRanges features<term>GRangesList</term></span>
      <span xml:id="t148" from="#a39" to="#a40" type="content_tags" ana="#content_tags.definitions[5]" resp="#tagger" cert="0.95">annotations about the primary range data<term>metadata</term></span>
      <span xml:id="t149" from="#a49" to="#a50" type="content_tags" ana="#content_tags.definitions[6]" resp="#tagger" cert="0.95">a class representing a run-length encoded vector<term>Rle</term></span>
      <span xml:id="t150" from="#a55" to="#a56" type="content_tags" ana="#content_tags.definitions[7]" resp="#tagger" cert="0.95">a matrix of feature-by-sample summaries plus annotations<term>SummarizedExperiment</term></span>
      <span xml:id="t151" from="#a63" to="#a64" type="content_tags" ana="#content_tags.definitions[8]" resp="#tagger" cert="0.95">departure of alternate nucleotide proportion from fifty percent<term>allelic imbalance</term></span>
      <span xml:id="t152" from="#a1" to="#a2" type="content_tags" ana="#content_tags.quantities[0]" resp="#tagger" cert="0.95">three — packages at the core of the infrastructure</span>
      <span xml:id="t153" from="#a1" to="#a2" type="content_tags" ana="#content_tags.quantities[1]" resp="#tagger" cert="0.95">more than 80 — Bioconductor packages directly supported</span>
      <span xml:id="t154" from="#a3" to="#a4" type="content_tags" ana="#content_tags.quantities[2]" resp="#tagger" cert="0.95">two — broad genomic-data categories</span>
      <span xml:id="t155" from="#a43" to="#a44" type="content_tags" ana="#content_tags.quantities[3]" resp="#tagger" cert="0.95">35 nt — original CTCF and GFP read length</span>
      <span xml:id="t156" from="#a43" to="#a44" type="content_tags" ana="#content_tags.quantities[4]" resp="#tagger" cert="0.95">24 nt — effective read length after quality trimming</span>
      <span xml:id="t157" from="#a47" to="#a48" type="content_tags" ana="#content_tags.quantities[5]" resp="#tagger" cert="0.95">120 nt — assumed fragment length in the CTCF demonstration</span>
      <span xml:id="t158" from="#a59" to="#a60" type="content_tags" ana="#content_tags.quantities[6]" resp="#tagger" cert="0.95">22 — CTCF ChIP-seq experiments initially collected</span>
      <span xml:id="t159" from="#a59" to="#a60" type="content_tags" ana="#content_tags.quantities[7]" resp="#tagger" cert="0.95">16 — BAM files retained after quality-score exclusion</span>
      <span xml:id="t160" from="#a59" to="#a60" type="content_tags" ana="#content_tags.quantities[8]" resp="#tagger" cert="0.95">12 — distinct individuals represented by retained BAM files</span>
      <span xml:id="t161" from="#a61" to="#a62" type="content_tags" ana="#content_tags.quantities[9]" resp="#tagger" cert="0.95">19655 — locations with evidence of allele-dependent CTCF binding</span>
      <span xml:id="t162" from="#a61" to="#a62" type="content_tags" ana="#content_tags.quantities[10]" resp="#tagger" cert="0.95">50750 — binding events over twelve individuals</span>
      <span xml:id="t163" from="#a61" to="#a62" type="content_tags" ana="#content_tags.quantities[11]" resp="#tagger" cert="0.95">12691 — events coincident with known polymorphisms</span>
      <span xml:id="t164" from="#a61" to="#a62" type="content_tags" ana="#content_tags.quantities[12]" resp="#tagger" cert="0.95">6964 — events at locations with no dbSNP report</span>
      <span xml:id="t165" from="#a63" to="#a64" type="content_tags" ana="#content_tags.quantities[13]" resp="#tagger" cert="0.95">41% — stated low-quality frequency for off-SNP calls with ANP below 20 percent</span>
      <span xml:id="t166" from="#a11" to="#a12" type="content_tags" ana="#content_tags.variables[0]" resp="#tagger" cert="0.95">chromosome name<term>chromosome name</term></span>
      <span xml:id="t167" from="#a11" to="#a12" type="content_tags" ana="#content_tags.variables[1]" resp="#tagger" cert="0.95">strand<term>strand</term></span>
      <span xml:id="t168" from="#a25" to="#a26" type="content_tags" ana="#content_tags.variables[2]" resp="#tagger" cert="0.95">start<term>start</term></span>
      <span xml:id="t169" from="#a25" to="#a26" type="content_tags" ana="#content_tags.variables[3]" resp="#tagger" cert="0.95">end<term>end</term></span>
      <span xml:id="t170" from="#a41" to="#a42" type="content_tags" ana="#content_tags.variables[4]" resp="#tagger" cert="0.95">coverage<term>coverage</term></span>
      <span xml:id="t171" from="#a63" to="#a64" type="content_tags" ana="#content_tags.variables[5]" resp="#tagger" cert="0.95">alternate nucleotide proportion<term>alternate nucleotide proportion</term></span>
      <span xml:id="t172" from="#a63" to="#a64" type="content_tags" ana="#content_tags.variables[6]" resp="#tagger" cert="0.95">base-call quality<term>base-call quality</term></span>
    </spanGrp>
  </standOff>
  <text>
    <body>
        <p><anchor xml:id="a0"/> Software for Computing and Annotating Genomic Ranges</p>
        <p>Abstract</p>
        <p><anchor xml:id="a1"/>We describe Bioconductor infrastructure for representing and computing on annotated genomic ranges and integrating genomic data with the statistical computing features of R and its extensions. At the core of the infrastructure are three packages: IRanges , GenomicRanges , and GenomicFeatures . These packages provide scalable data structures for representing annotated ranges on the genome, with special support for transcript structures, read alignments and coverage vectors. Computational facilities include efficient algorithms for overlap and nearest neighbor detection, coverage calculation and other range operations. This infrastructure directly supports more than 80 other Bioconductor packages, including those for sequence analysis, differential expression analysis and visualization.<anchor xml:id="a2"/></p>
        <p>This is a PLOS Computational Biology Software Article.</p>
        <p>Introduction</p>
        <p><anchor xml:id="a3"/>The genome is typically represented as a linear sequence, split over multiple chromosomes, and data are linked to the genome by occupying a range of positions on the sequence. These data fall into two broad categories. First, there are the annotations, such as gene models, transcription factor binding site predictions, GC percentage, polymorphisms, and conservation scores. Such annotations are highly processed and are often served by public databases such as NCBI or EBI. Second, there are primary experimental measurements, such as read alignments from high-throughput sequencing. Data integration, within and between those two categories, is made possible by treating the data as ranges on the genome, which acts as a common scaffold. Thus, ranges play a central role in genomic data analysis, and statistical tools should consider ranges to be as fundamental as quantitative and categorical data types.<anchor xml:id="a4"/></p>
        <p><anchor xml:id="a5"/>For example, ranges are integral to the manipulation of gene model annotations. Examples include deriving candidate promoter regions, finding introns, calculating the total exonic length of a transcript or finding the exonic regions that are unique to a particular transcript in an alternatively spliced gene. Ranges also play a central role in the analysis of experimental data, where they are used to represent read alignments. In the analysis of ChIP-seq data, it is typical to calculate the depth of alignment coverage, which then serves as input to calling algorithms which output peaks as ranges. These ranges are then annotated according to their overlap with and proximity to other ranges, such as gene structures. Similarly, for RNA-seq data, analysts measure gene expression based on counting the alignments overlapping exons.<anchor xml:id="a6"/></p>
        <p><anchor xml:id="a7"/>All these analyses depend on specialized, range-based algorithms and data structures. For example, computations on gene models involve set operations on ranges, including intersection, union and complement. Coverage calculation is important for detecting regions of enrichment and for producing visual summaries. Overlap and nearest neighbor detection is fundamental to the annotation of ChIP-seq peaks, estimating expression from RNA-seq data and many other integrative analyses.<anchor xml:id="a8"/></p>
        <p><anchor xml:id="a9"/>The primary argument for storing ranges in specialized, formal data structures is efficiency, in terms of both implementation and language. The notion of ranges can be made explicit in the application programming interface (API), permitting the expression of algorithms in a succinct and readable language that illustrates concepts instead of exposing implementation details. Another goal is interoperability: by using the same data structures, multiple routines, spread across different packages, can operate on the data without cumbersome conversions. Also, a data structure can be accessed through an abstraction that hides the details of the optimized implementation, and this results in looser coupling between components. Together, these benefits lead to more robust, maintainable software.<anchor xml:id="a10"/></p>
        <p><anchor xml:id="a11"/>Data structures should support the storage of per-range metadata, because genomic data is multivariate and consists of much more than the ranges alone. This enables the storage of gene identifiers and other symbols with the gene ranges, and the peak heights or confidence scores with the peak ranges. Some metadata merit special treatment, such as the chromosome name and the strand. Also necessary is a data structure for storing summaries and processing results for a common set of ranges across multiple samples. Such a structure would hold, for example, the RNA-seq per-exon counts or a set of variant calls. Finally, there should be support for storing hierarchies of ranges, at least for one level of nesting, to represent, for example, the nesting of exons into transcripts. Whether it is appropriate to treat the exons as individual ranges or the transcript as a compound range depends on the use case; both should be supported.<anchor xml:id="a12"/></p>
        <p><anchor xml:id="a13"/>These data structures are represented as classes, through which we communicate the formal definition of each data structure to the programming language. One benefit is that we can defer the regulation of data access and the tracking of data integrity to the language. In the case of functional object-oriented languages, there is another benefit: we can implement behaviors as methods on generic functions. A generic function is one that dispatches to a particular implementation, termed a method, based on the classes of passed arguments. This means that the same API will exhibit specialized behavior depending on the input. For example calling start on a range data structure would return the starting positions for the ranges, while calling the same function on a base R time-series object would behave differently.<anchor xml:id="a14"/></p>
        <p><anchor xml:id="a15"/>This paper describes the infrastructure in Bioconductor [1] for the integrative statistical analysis of range-based genomic data. Main features include scalable data structures for annotated genomic ranges and genome-length vectors, and efficient algorithms for overlap detection and other range operations. <anchor xml:id="a16"/>The packages that form the core of the infrastructure include IRanges , GenomicRanges and GenomicFeatures .<anchor xml:id="a17"/> Source code for the packages is included in the supplement, under Software S1 , S2 , and S3 , respectively. The IRanges package provides the fundamental range data structures and operations, while GenomicRanges builds upon it to add biological semantics to the metadata, including explicit treatment of sequence name and strand. Finally, GenomicFeatures enables access to and manipulation of gene models and other annotations. Together, these packages support more than 80 other packages in Bioconductor.<anchor xml:id="a18"/></p>
        <p><anchor xml:id="a19"/>Other software tools provide facilities for working with genomic ranges, e.g., bedtools [2] and cisGenome [3] . Those provide UNIX command-line interfaces and rely on common file formats (which are often incompletely specified) to interoperate with other tools, leading to workflows embodied as: collections of heterogeneous scripts, system dependencies and data files. Such workflows can be difficult to maintain and challenging to reproduce. In contrast, the Bioconductor infrastructure is tightly integrated with other R packages through in-memory data structures, while still supporting interaction with external tools. The Bioconductor package genomeIntervals provides data structures for representing genomic ranges and utilities, such as overlap detection, that have much in common with the tools described here, but our tools are more extensive and have been more widely adopted.<anchor xml:id="a20"/></p>
        <p>Design and Implementation</p>
        <p>Working with Simple Ranges</p>
        <p><anchor xml:id="a21"/>We use the term “range” to denote an ordered set of consecutive integers.<anchor xml:id="a22"/> A range is represented by a pair of integers satisfying . In Figure 1 , and correspond to the start and end columns, respectively. The “width” of a range is given by , so a range for a single integer (modeling, for example, a single nucleotide position) has .</p>
        <p>Tabular (top) and visual (bottom) representation of the exons for the human KRAS gene, derived from the UCSC known gene annotation. In the table, the columns seqnames , start and end locate the exons in the genome. The strand column indicates the direction of transcription. The exons are grouped into transcripts by tx_id , and the exon IDs are given by exon_id . Virtually all genomic data sets fit this pattern: genomic location, followed by a series of columns, often including strand and/or score, that annotate that location. In the plot, the rectangles represent exonic regions, and the arrows represent the introns, as well as the strand.</p>
        <p><anchor xml:id="a23"/>The IRanges package, which is designed to be general and thus avoids biology-specific considerations, introduces the IRanges class to represent a vector of ranges. The GenomicRanges package builds on IRanges to include biologically relevant features such as strand and sequence (e.g., chromosome) name.<anchor xml:id="a24"/></p>
        <p>In Figure 1 , we show a table of the exons of the human gene KRAS . The tx_id column indicates the transcripts to which each exon belongs. A single IRanges object can store those exon ranges, and this model is appropriate for per-exon analyses.</p>
        <p>The IRanges class supports the basic R vector API, including the length accessor, extraction and subsetting functions like [[ and [ , concatenation with c, etc. This will hold true for all vector-like objects in the range infrastructure.</p>
        <p><anchor xml:id="a25"/>The available range operations are listed in Table 1 . The IRanges object supports direct manipulation of the start, end and width of the contained ranges. In applications, many of these operations follow recurrent patterns, and manipulating start and end directly can be needlessly tedious and error-prone. For this reason, shift , resize and similar frequently useful range operations are provided. Ranges can be simplified and summarized with several functions, including range , reduce and disjoin . Figure 2 illustrates the latter two. It is often appropriate to conceive of an IRanges object as a mathematical set of integers, or, in the biological context, a set of nucleotide positions. gaps (complement), union , intersect and setdiff support this notion. For example, taking the union of two transcripts would yield the ranges covered by any KRAS exon. The flank function could be used to demarcate putative promoter regions of transcripts.<anchor xml:id="a26"/></p>
        <p>Summary of the Ranges API.</p>
        <p>Illustration of the reduce and disjoin operations on the last exon from each of the KRAS transcripts.</p>
        <p><anchor xml:id="a27"/>A recurrent operation is overlap detection; various instances are illustrated in Figure 3 . In later sections, we apply overlap counting for finding the percentage of ChIP-seq peaks that overlap a promoter, counting the number of RNA-seq reads for each transcript, and other tasks. The findOverlaps function uses an efficient interval tree algorithm [4] to detect overlaps between two IRanges objects, as well as the more complex range-based data structures introduced later. The algorithm supports several types of overlap, including those defined by Allen&#x27;s Interval Algebra [5] . The one-time cost of constructing the interval tree is , and queries are performed in logarithmic time. In accordance with the vectorized semantics of R, if multiple queries are submitted, they are efficiently processed in batch, without restarting at the root of the tree for each query. The language of implementation is C, which avoids the potentially expensive iteration over the tree in R.<anchor xml:id="a28"/></p>
        <p>Illustration of overlap (top) and adjacency (bottom) relationships. The any mode detects hits with partial or complete overlap, while within requires that the query range represents a subregion of the subject range.</p>
        <p>Working with Genomic Ranges</p>
        <p><anchor xml:id="a29"/>The IRanges class encodes only the start and end of ranges but not the chromosome, strand nor other information that is important in genomic applications. The GenomicRanges package adds biological semantics on top of IRanges . At its core is the GRanges class. Each element of a GRanges instance includes a chromosome identifier and strand designation. Each data set is associated with a particular, versioned reference genome sequence consisting of a discrete set of chromosomes or contigs, along with their lengths, if known. The GRanges class thus fully represents the data in Figure 1 , and encourages best-practices (e.g., tracking genome build) to minimize book-keeping errors.<anchor xml:id="a30"/></p>
        <p><anchor xml:id="a31"/>The GRanges class supports many of the same range operations as IRanges and specializes them for genomic data. We achieved API specialization by implementing methods for both classes on the same generic functions. In general, we believe method specialization is an effective practice for providing the same interface on top of different data structures. Abstracting implementation details leads to user code that is more robust and easier to write and maintain.<anchor xml:id="a32"/></p>
        <p>The GRanges methods give special consideration to the chromosome and, when appropriate, the strand. For instance, the findOverlaps generic has methods for both IRanges and GRanges , and the GRanges method is specifically able to take advantage of the chromosome information when detecting overlaps. Operations that depend on a notion of direction optionally consider strand. For example, the resize function will resize from the start or end of the ranges in a IRanges object. For a GRanges object, resize will take the start to be the leftmost position for positive strand features and the rightmost position for negative strand features.</p>
        <p><anchor xml:id="a33"/>Some types of genomic data, for example gene models or aligned paired-end reads, have a hierarchical structure. To represent this, multiple GRanges objects may be combined into a GRangesList , where each GRanges is considered a compound feature. GRangesList groups transcripts by gene, groups exons by transcript, and represents read alignments, where each alignment consists of multiple segments separated by gaps. For example, we group the KRAS exons by transcript using a GRangesList . A note on performance: although the user interface presents each element of a GRangesList as a GRanges , internally there is only a single GRanges , along with an assoicated partitioning that forms the list elements.<anchor xml:id="a34"/></p>
        <p>For a GRangesList , overlap detection reports a hit at the element level, i.e., when any range within an element overlaps a query range. See Figure 4 for an illustration. This semantic is convenient, for example, when counting the total number of RNA-seq read pairs overlapping the exonic regions of each transcript. In that case, both the reads and the transcripts are GRangesList objects.</p>
        <p>Illustration of overlap computations between two GRangesList objects. Each set of rectangles linked by solid lines represents a compound range, i.e., an element of the list. Ranges in the query (top) are being matched against ranges in the subject (bottom). The labels between them indicate the type of overlap (any, within, none).</p>
        <p>Accessing Gene Models</p>
        <p><anchor xml:id="a35"/>Recalling our KRAS gene model example, there are multiple models for representing transcript structures, and the applicability of each depends on the use case. To support the analyst in asking a broad range of questions, there is a need for a mechanism that draws from a data source of gene annotations and returns them in a variety of different data models. The GenomicFeatures package fills that role by distilling multiple data sources into a single database schema and wrapping that database in an API that returns, for example, the exons grouped by gene, or the bounds for every transcript. The databases are implemented in SQLite and are thus accessible from environments outside of R. For reproducibility, a database may be encapsulated in a redistributable R package.<anchor xml:id="a36"/></p>
        <p><anchor xml:id="a37"/>The database is represented by the TranscriptDb class and stores the range of each exon, the coding range, the transcript ID, the gene ID, and metadata about the source of the transcript information. The GenomicFeatures package provides an automated mechanism for constructing a TranscriptDb object from tracks defined in the UCSC genome browser, Biomart, or GTF/GFF files. Bioconductor provides pre-built packages for the most widely adopted gene models, like the UCSC known gene annotations on hg19. These packages follow a standard naming convention, e.g., TxDb.Hsapiens.UCSC.hg19.knownGene .<anchor xml:id="a38"/></p>
        <p>There are functions for performing common queries that return the exons, coding regions, and transcript boundaries as a GRanges object. Transcript and gene-level groupings are preserved by GRangesList objects. The ranges in Figure 1 were derived from the TxDb.Hsapiens.UCSC.hg19.knownGene package using the following call to the function exons:</p>
        <p>&gt; library(“TxDb.Hsapiens.UCSC.hg19.knownGene”)</p>
        <p>&gt; library(“org.Hs.eg.db”)</p>
        <p>&gt; kras_gene &lt;- org.Hs.egSYMBOL2EG$KRAS</p>
        <p>&gt; kras_exons &lt;- exons(TxDb.Hsapiens.UCSC.hg19.knownGene,</p>
        <p>+ vals = list(gene_id = kras_gene),</p>
        <p>+ columns = c(“tx_id”, “exon_id”))</p>
        <p>To retrieve the exons corresponding to a particular transcript, such as transcript 48666 of KRAS, we call exonsBy , which returns a GRangesList of exons grouped by transcript, and extract the element corresponding to the desired transcript identifier:</p>
        <p>&gt; exonsByTx &lt;- exonsBy(TxDb.Hsapiens.UCSC.hg19.knownGene)</p>
        <p>&gt; krasA &lt;- exonsByTx[[“48666”]]</p>
        <p>The contents of krasA are shown in Table 2 .</p>
        <p>Contents of the krasA object, representing the exons in isoform A of KRAS.</p>
        <p>Associating Annotations with Ranges</p>
        <p>Figure 1 demonstrates how genomic data consist of both ranges and uni- or multivariate annotations on those ranges. In that table, the annotations are the exon ID and a variable grouping the exons into transcripts. If we had read alignments from an RNA-seq experiment, we might use countOverlaps to generate a read count for each exon. Other examples of annotation would include the reference and alternate bases for a single nucleotide variant (SNV) or the position weight matrix (PWM) score for a putative transcription factor binding site.</p>
        <p><anchor xml:id="a39"/>Every multi-element data structure in the IRanges suite supports the storage of per-element metadata: data about data. In this case, the metadata are the annotations, and the primary data are the ranges being annotated. This includes all of the data structures for storing ranges, such as IRanges, GRanges and GRangesList . The metadata are stored in a DataFrame with as many rows as there are elements in the object. We introduce a DataFrame class that behaves similarly to the base R data.frame , but supports storage of complex vector-like objects (e.g., a DNAStringSet , representing DNA sequences, or a GRanges ) in columns.<anchor xml:id="a40"/></p>
        <p>Working with Coverage and Similar Vectors</p>
        <p><anchor xml:id="a41"/>A common method of summarizing a genomic data set is to calculate the coverage, i.e., the number of features in the data set overlapping each position in the genome. This is useful in ChIP-seq analysis, where many peak detection methods operate on the coverage.<anchor xml:id="a42"/></p>
        <p><anchor xml:id="a43"/>For this example, mouse genomic DNA was cross-linked with DNA-binding proteins, fragmented and precipitated with an antibody for CTCF. An antibody for GFP was used for the control. The CTCF and GFP samples were each sequenced in a single lane on an Illumina sequencer, which generated reads 35 nt in length [6] . We excluded the last 11 nt of each read due to insufficient quality, so the effective read length was 24 nt. The reads were aligned to the mm9 build of the mouse genome using MAQ. We parsed the MAQ output using the ShortRead package [7] , and the alignments for three chromosomes (chr10, chr11 and chr12) were extracted for use as a demonstration data set in the chipseq package [8] .<anchor xml:id="a44"/></p>
        <p>&gt; library(“chipseq”)</p>
        <p>&gt; data(“cstest”)</p>
        <p>&gt; ctcfReads &lt;- cstest$ctcf</p>
        <p><anchor xml:id="a45"/>The ctcfReads object, listed in Table 3 , is a GRanges holding the read alignments from the CTCF sample. The GRanges stores the chromosome names, ranges, and strand for each alignment, as well as a list of chromosome names and lengths for the mm9 genome. Tracking the chromosome information guards against errors that could arise, for example, from mixing data across genome assemblies.<anchor xml:id="a46"/></p>
        <p>Ranges for the first three reads in the ctcfReads object, storing the read alignments for the CTCF sample.</p>
        <p><anchor xml:id="a47"/>Each read represents only 24 nt from one end of a fragment of DNA. Since it was the fragment, but not necessarily the sequenced region, that was cross-linked to CTCF, we need to consider the entire fragment when predicting binding sites. We assume that the fragment length was approximately 120 nt and call resize to extend our read ranges to fragment-sized ranges:<anchor xml:id="a48"/></p>
        <p>&gt; ctcfFragments &lt;- resize(ctcfReads, 120)</p>
        <p>Note that the strand of the alignment was automatically taken into account.</p>
        <p>The coverage function calculates the coverage for a set of ranges. We calculate the coverage on the CTCF fragments from our ChIP-seq data set as follows:</p>
        <p>&gt; ctcfCoverage &lt;- coverage(ctcfFragments)</p>
        <p>&gt; ctcfCoverage10 &lt;- ctcfCoverage$chr10</p>
        <p>The ctcfCoverage object is a list, with one coverage vector per chromosome. For simplicity, we extract the element corresponding to “chr10”. The ctcfCoverage10 object is of class Rle .</p>
        <p><anchor xml:id="a49"/>Vectors along the genome tend to have many repeated values. For the sake of compactness, we compress the data using a run-length encoding compression scheme. Through the R class system, we abstract this efficient implementation behind an API that supports the features of ordinary R vectors; the complexity is hidden from the user. The Rle class represents a run-length encoded vector and provides features beyond those of ordinary vectors. For example, one can use ranges to extract values from an Rle . This integrates range-based datasets with data in chromosome-length vectors. To demonstrate, we find the position of the maximum coverage on chr10, and, in order to display the coverage in context, we extract a 5000 nt region centered around that position:<anchor xml:id="a50"/></p>
        <p>&gt; maxPos &lt;- which.max(ctcfCoverage10)</p>
        <p>&gt; roi &lt;- resize(IRanges(maxPos, width = 1), 5000, “center”)</p>
        <p>&gt; roiCoverage &lt;- ctcfCoverage$chr10[roi]</p>
        <p>The roiCoverage vector is plotted in Figure 5 and shows how the coverage relates to the gene context.</p>
        <p>Visualization of the coverage of bases by GFP- and CTCF-bound fragments (top) in the context of part of the gene model for Rrp1, Entrez gene 18114 (bottom).</p>
        <p>Next, we wish to find peaks in the coverage vector by slicing it at a fixed threshold. We call the slice function and pass it a cutoff of 8:</p>
        <p>&gt; ctcfPeaks &lt;- slice(ctcfCoverage10, lower = 8)</p>
        <p>The resulting coverage slices are ranges and and we rely on our data structures for managing and manipulating them. In particular, the ctcfPeaks object is a Views object, which combines the peak ranges with the original Rle coverage vector (another example of integrating ranges with vectors). Views has several utilities for summarizing the vector values within each range. We use these to summarize the coverage values within each peak:</p>
        <p>&gt; ctcfMaxs &lt;- viewMaxs(ctcfPeaks)</p>
        <p>&gt; ctcfSums &lt;- viewSums(ctcfPeaks)</p>
        <p>Accessing Read Alignments</p>
        <p><anchor xml:id="a51"/>Read alignments may be loaded from a BAM file as a GappedAlignments or GappedAlignmentPairs object, depending on whether the reads should be treated as paired. Both data structures store short read alignment results in terms of the position, chromosome, strand, CIGAR string (a compact representation of the gaps) and other information. Both also support some of the range operations and can be coerced to GRanges and GRangesList . The GRanges representation holds the ungapped extents of the read alignments, whereas the GRangesList represents the alignments as ranges with gaps, including the inter-read gap of a pair and the skipped regions in the reference (e.g., introns). The choice of data structure depends on, for example, whether one wants to count the overlapping pairs, reads, or aligned segments separated by gaps.<anchor xml:id="a52"/></p>
        <p>A frequent goal of RNA-seq experiments is to estimate the levels of gene expression. For this demonstration, we will simply count the number of read alignments overlapping the exonic regions of each transcript. We begin by loading a BAM file of read alignments from an RNA-seq experiment in yeast [9] . There are four samples, two of which are wildtype and two of which are RLP mutants. The leeBamViews package provides the alignments on chromosome XIII from positions 800000 to 900000.</p>
        <p>&gt; bams &lt;- getBamsFromLeeBamViews()</p>
        <p>&gt; ga &lt;- readGappedAlignments(bams [ 1 ] )</p>
        <p>&gt; reads &lt;- grglist(ga)</p>
        <p>The readGappedAlignments function loads the BAM file as a GappedAlignments object, which is then coerced to a GRangesList , where each read consists of one or more ranges, separated by intronic gaps.</p>
        <p>In the next step, we obtain the transcript annotations for yeast. Bioconductor provides a TranscriptDb object for the UCSC sacCer2 assembly, and we extract from it a GRangesList representing the transcripts, by calling exonsBy . In order to detect overlaps, the alignments and gene annotations need to have the same chromosome names; we correct for that with the calls to keepSeqlevels and renameSeqlevels .</p>
        <p>&gt; library(“TxDb.Scerevisiae.UCSC.sacCer2.sgdGene”)</p>
        <p>&gt; tx &lt;- exonsBy(TxDb.Scerevisiae.UCSC.sacCer2.sgdGene)</p>
        <p>&gt; tx &lt;- renameSeqlevels(keepSeqlevels(tx, “chrXIII”),</p>
        <p>+ c(chrXIII = “Scchr13”))</p>
        <p>Now that the data and annotations have been loaded, we count the number of read alignments in each genomic feature:</p>
        <p>&gt; counts &lt;- countOverlaps(tx, reads, ignore.strand = TRUE)</p>
        <p><anchor xml:id="a53"/>More complex counting algorithms are available via the summarizeOverlaps function, which counts over multiple samples and returns the results as a SummarizedExperiment object. Unlike the call to countOverlaps above, reads that map to multiple features are discarded.<anchor xml:id="a54"/></p>
        <p>Summarized Experiments</p>
        <p><anchor xml:id="a55"/>The typical workflow in a genomic data analysis is to reduce a complex raw data set, such as a set of RNA-seq read alignments, to a set of summaries, such as the number of reads aligned over each transcript or exon. Analogously, an exome-seq experiment yields variant calls at particular genomic ranges. It is often appropriate and convenient to store these summaries as a matrix, where the rows correspond to genes or some other genomic feature and the columns to samples. The SummarizedExperiment class is designed to hold such values, along with annotations on the genomic regions, the samples and the experiment as a whole. Its design follows the same pattern as the ExpressionSet in the Bioconductor microarray infrastructure; the primary difference is that SummarizedExperiment is based on IRanges data structures. A SummarizedExperiment may be constructed directly or generated by a function that executes a high-level workflow. For example, for a list of BAM files, the summarizeOverlaps function counts the overlaps between the read alignments and a database of transcripts.<anchor xml:id="a56"/></p>
        <p>Results</p>
        <p>In this section we describe range-based integrative computations related to the genetics of protein-DNA binding, and conclude with a topically organized list of Bioconductor packages that make essential use of the ranges infrastructure.</p>
        <p>Exploring Genetics of CTCF Binding</p>
        <p><anchor xml:id="a57"/>In the murine ChIP-seq example discussed previously, the ranges infrastructure was used to compute and display variation in read coverage over the mouse genome. In this example, we use tools based on the ranges infrastructure to examine both coverage and content of reads from a larger ChIP-seq experiment on human cell lines. Our basic intent is to show how the infrastructure can be used to evaluate the roles of genotype and genetic diversity in the genomic sequences where CTCF is reported to bind, with an understanding that ultimate inferences on protein binding locations and on base-call distributions over heterozygous loci will need to directly incorporate risks of base calling and read mapping errors, and will need to be followed up with wet-lab validation.<anchor xml:id="a58"/></p>
        <p><anchor xml:id="a59"/>For an investigation of the prevalence of allele-specific protein-DNA binding [10] , BAM files on 22 ChIP-seq experiments addressing CTCF binding to DNA from immortalized B-cells were collected from the ENCODE project portal. Exclusion of files with aberrant quality score distributions left 16 BAM files corresponding to 12 distinct individuals; two technical replicates were available for each of four individuals. Furthermore, different base-call quality score scales were used for two batches of samples; by subtracting 31 from the reported mean quality scores for one set of samples, approximately identical medians and interquartile ranges were established for mean quality scores for all retained samples. Base calls for reads bound at all genomic locations with positive coverage were tabulated using the VariantTools tallyVariants function, and reduced to locations exhibiting statistical evidence of allele-dependent CTCF binding using the callVariants function. Each of these variant assessment tools makes use of infrastructure derived from GSNAP [11] with key results materialized as GRanges instances. Table 4 depicts an excerpt from a callVariants output.<anchor xml:id="a60"/></p>
        <p>Partial output of countVariants applied to a BAM file from an ENCODE CTCF ChIP-seq experiment.</p>
        <p><anchor xml:id="a61"/>The genome-wide searches for allele-dependent CTCF binding events employed default settings for variant calling by VariantTools callVariants , which include criteria on minimum coverage, minimum diversity of read cycles at which base is found, and limitation of risk of strand bias. This process yielded a total of 19655 locations with evidence of allele-dependent CTCF binding, corresponding to 50750 events over the 12 individuals. We obtained GRanges representations of dbSNP build 137 with the scanVcf function of the VariantAnnotation . This facilitated distributed computation for partitioning allele-dependent CTCF binding events into 12691 coincident with known polymorphisms and 6964 at locations where no SNP has been reported in dbSNP.<anchor xml:id="a62"/></p>
        <p><anchor xml:id="a63"/>Allelic imbalance in CTCF binding corresponds to departure of the alternate nucleotide proportion (ANP) at a CTCF binding site from 50%. The upper panels of Figure 6 show the distributions of ANP stratified by coincidence of allele-dependent CTCF binding locations with locations of known SNP. The lower panels show identically stratified associations between ANP and mean base-call qualities for pileups over the allele-dependent binding locations. While the off-SNP locations show a proponderance of ANP below 20%, there is also an indication that base-call quality for such binding events is relatively low, implying that these findings would be unlikely to replicate. For example, among on-SNP allele-dependent binding calls with ANP below 20%, 5% had mean quality less than 5; the corresponding frequency for low-quality on-SNP allele-dependent binding locations calls was 41%.<anchor xml:id="a64"/></p>
        <p>Top panels: distributions of alternate nucleotide proportions for on- and off-SNP allele-dependent CTCF binding events. Bottom panels: relationships between average call quality values and alternate nucleotide proportions are depicted using a 2D density estimate (darker regions correspond to higher density.).</p>
        <p><anchor xml:id="a65"/>Figure 6 was constructed using the packages and features described above with very little programming effort needed to specialize the computations to this example. Most computational biologists and other interested investigators could easily carry out these steps. We can conclude that allelic imbalance in CTCF binding events is frequently detectable but, for the data considered, the apparent imbalances observed are likely a mix of real biology and technical artifacts originating from, e.g., sequencing and read mapping errors. Careful analysis of metadata collected in the variant-calling process may help to disentangle the key factors contributing to allele-dependent CTCF binding.<anchor xml:id="a66"/></p>
        <p>Software Based on the Infrastructure</p>
        <p><anchor xml:id="a67"/>There is a growing ecosystem of packages based on this infrastructure. By current count, more than 80 packages depend directly on the packages presented here. This includes packages for input and output of ranges ( rtracklayer , Rsamtools ) [12] , [13] , quality assessment ( ShortRead ) [7] , sequence analysis ( Biostrings ) [14] , variant calling ( VariantTools ) [15] , and other tasks. To summarize the different use cases addressed by dependent packages, Table 5 tabulates the descriptive labels chosen from a controlled vocabulary by the package authors.<anchor xml:id="a68"/></p>
        <p>Selected packages based on the Ranges infrastructure.</p>
        <p>Availability and Future Directions</p>
        <p><anchor xml:id="a69"/>All of the packages described, including IRanges , GenomicRanges and GenomicFeatures , form the core infrastructure for sequence analysis in Bioconductor and are available from the project website: http://bioconductor.org (see also Software S1 - S3 ). We aim to continue to support scientists in their drive to further science by asking increasingly complex and integrative questions about increasingly complex and heterogeneous data. For example, we are working towards better support for detecting alternative and novel splicing, measuring isoform-specific expression, annotating sequence variants, mapping between genome, transcript and protein coordinate spaces, and integrating transcript annotations with gene-level metadata. There is also an unmet need in the visualization of genomic ranges. In particular, we need better visualizations for relating RNA-seq coverage and junction counts to transcript structures, and for diagnosing read alignments in the context of variant calling. Finally, as datasets continue to expand in size, we continue to seek more efficient algorithms and data structures, and we are vigilant for opportunities to leverage parallel computing.<anchor xml:id="a70"/></p>
        <p>Supporting Information</p>
        <p>The IRanges package. The IRanges package provides efficient low-level and reusable S4 classes for storing and manipulating ranges of integers and compressed, genome-length vectors.</p>
        <p>(GZ)</p>
        <p>Click here for additional data file.</p>
        <p>The GenomicRanges package. The GenomicRanges package defines general purpose containers for storing genomic ranges as well as more specialized containers for storing alignments against a reference genome.</p>
        <p>(GZ)</p>
        <p>Click here for additional data file.</p>
        <p>The GenomicFeatures package. The GenomicFeatures package is a set of tools and methods for making and manipulating transcript-centric annotations.</p>
        <p>(GZ)</p>
        <p>Click here for additional data file.</p>
        <p>Funding Statement</p>
        <p><anchor xml:id="a71"/>This work was funded by the National Institutes of Health, National Human Genome Research Group through grants P41 HG004059 and U41 HG004059 and (for VJC) by National Heart, Lung and Blood Institute grants R01 HL086601, R01 HL093076 and R01 HL094635. The funders had no role in study design, data collection and analysis, decision to publish, or preparation of the manuscript.<anchor xml:id="a72"/></p>
        <p>References</p>
        <p>Associated Data</p>
        <p>Supplementary Materials</p>
        <p>The IRanges package. The IRanges package provides efficient low-level and reusable S4 classes for storing and manipulating ranges of integers and compressed, genome-length vectors.</p>
        <p>(GZ)</p>
        <p>Click here for additional data file.</p>
        <p>The GenomicRanges package. The GenomicRanges package defines general purpose containers for storing genomic ranges as well as more specialized containers for storing alignments against a reference genome.</p>
        <p>(GZ)</p>
        <p>Click here for additional data file.</p>
        <p>The GenomicFeatures package. The GenomicFeatures package is a set of tools and methods for making and manipulating transcript-centric annotations.</p>
        <p>(GZ)</p>
        <p>Click here for additional data file.<anchor xml:id="a73"/></p>
    </body>
  </text>
</TEI>
