Collect coverage reports.
337490
def collect(args):
    """"""
    excl_paths = exclude_paths(args)

    report = {}
    if args.repo_token:
        report['repo_token'] = args.repo_token

    report['service_name'] = args.service_name
    report['service_job_id'] = args.service_job_id

    if os.getenv('COVERALLS_PARALLEL', False):
        report['parallel'] = 'true'

    args.exclude_lines_pattern.extend([
        r'\bLCOV_EXCL_LINE\b',
        r'^\s*};?\s*$',
        r'^\s*(inline|static)'
        ])

    discovered_files = set()
    src_files = {}
    abs_root = os.path.abspath(args.root)
    if args.lcov_file:
        info_lines = [line.rstrip('\n') for line in open(args.lcov_file, 'r')]
        line_iter = iter(info_lines)
        new_file_re = re.compile('SF:(.*)')
        line_coverage_re = re.compile('DA:(\d+),(\d+)');
        for line in line_iter:
            new_file_match = new_file_re.match(line)
            if new_file_match:
                src_report = {}
                filepath = new_file_match.group(1)
                if args.root:
                    filepath = os.path.relpath(filepath, args.root)
                abs_filepath = os.path.join(abs_root, filepath)
                src_report['name'] = str(posix_path(filepath))
                with io.open(abs_filepath, mode='rb') as src_file:
                    src_report['source_digest'] = hashlib.md5(src_file.read()).hexdigest()
                src_report['coverage'] = parse_lcov_file_info(args, abs_filepath, line_iter, line_coverage_re, "end_of_record")
                src_files[filepath] = src_report
            elif line != "TN:":
                print('Invalid info file')
                print('line: ' + line)
                sys.exit(0)
    else:
        for root, dirs, files in os.walk(args.root, followlinks=args.follow_symlinks):
            dirs[:] = filter_dirs(root, dirs, excl_paths)

            root_is_libtool_dir = is_libtool_dir(root)
            for filepath in files:
                if os.path.splitext(filepath)[1] == '.gcov':
                    gcov_path = os.path.join(os.path.join(root, filepath))
                    with open(gcov_path, mode='rb') as fobj:
                        source_file_line = fobj.readline().decode('utf-8', 'replace')
                        source_file_path = source_file_line.split(':')[-1].strip()
                        if not os.path.isabs(source_file_path):
                            if args.build_root:
                                source_file_path = os.path.join(
                                    args.build_root, source_file_path)
                            elif root_is_libtool_dir:
                                source_file_path = os.path.abspath(
                                    libtool_source_file_path(
                                        root, source_file_path))
                            else:
                                if not source_file_path.startswith(os.path.pardir + os.path.sep) and \
                                        os.path.dirname(source_file_path):
                                    the_root = abs_root
                                else:
                                    the_root = root
                                source_file_path = os.path.abspath(
                                    os.path.join(the_root, source_file_path))
                        src_path = os.path.relpath(source_file_path, abs_root)
                        if src_path.startswith(os.path.pardir + os.path.sep):
                            continue
                        if is_excluded_path(args, source_file_path):
                            continue

                        src_report = {}
                        src_report['name'] = posix_path(src_path)
                        discovered_files.add(src_path)
                        with io.open(source_file_path, mode='rb') as src_file:
                            src_report['source_digest'] = hashlib.md5(src_file.read()).hexdigest()

                        src_report['coverage'] = parse_gcov_file(args, fobj, gcov_path)
                        if src_path in src_files:
                            src_files[src_path] = combine_reports(src_files[src_path], src_report)
                        else:
                            src_files[src_path] = src_report

    report['source_files'] = list(src_files.values())
    # Also collects the source files that have no coverage reports.
    if not args.lcov_file:
        report['source_files'].extend(
            collect_non_report_files(args, discovered_files))

    # Use the root directory to get information on the Git repository
    report['git'] = gitrepo.gitrepo(abs_root)
    return report
1314503
def get_report(self, value):
        """"""
        if self.multiselect:
            value = value or []
            children = []

            for child in value:
                children.append(self.cast_to_report(child))

            return children

        return self.cast_to_report(value)
1113669
private function collectFunction(array $start, array $end, array $declaration, int $coverage = 0) : void
    {
        $this->fileCoverage['fnMap'][] = [
            'name' => '(anonymous_' . $this->funcCount . ')',
            'decl' => $declaration,
            'loc' => ['start' => $start, 'end' => $end],
        ];

        $this->fileCoverage['f'][] = $coverage;

        // Collect statements as well, one for entire function, one just for function declaration
        $this->collectStatement($start, $end, $coverage);
        $this->collectStatement($declaration['start'], $declaration['end'], $coverage);

        ++$this->funcCount;
    }
662011
def report(config, output, use, output_dir, accounts,
           field, no_default_fields, tags, region, debug, verbose,
           policy, policy_tags, format, resource, cache_path):
    """"""
    accounts_config, custodian_config, executor = init(
        config, use, debug, verbose, accounts, tags, policy,
        resource=resource, policy_tags=policy_tags)

    resource_types = set()
    for p in custodian_config.get('policies'):
        resource_types.add(p['resource'])
    if len(resource_types) > 1:
        raise ValueError("can only report on one resource type at a time")
    elif not len(custodian_config['policies']) > 0:
        raise ValueError("no matching policies found")

    records = []
    with executor(max_workers=WORKER_COUNT) as w:
        futures = {}
        for a in accounts_config.get('accounts', ()):
            for r in resolve_regions(region or a.get('regions', ())):
                futures[w.submit(
                    report_account,
                    a, r,
                    custodian_config,
                    output_dir,
                    cache_path,
                    debug)] = (a, r)

        for f in as_completed(futures):
            a, r = futures[f]
            if f.exception():
                if debug:
                    raise
                log.warning(
                    "Error running policy in %s @ %s exception: %s",
                    a['name'], r, f.exception())
            records.extend(f.result())

    log.debug(
        "Found %d records across %d accounts and %d policies",
        len(records), len(accounts_config['accounts']),
        len(custodian_config['policies']))

    if format == 'json':
        dumps(records, output, indent=2)
        return

    prefix_fields = OrderedDict(
        (('Account', 'account'), ('Region', 'region'), ('Policy', 'policy')))
    config = Config.empty()
    factory = resource_registry.get(list(resource_types)[0])

    formatter = Formatter(
        factory.resource_type,
        extra_fields=field,
        include_default_fields=not(no_default_fields),
        include_region=False,
        include_policy=False,
        fields=prefix_fields)

    rows = formatter.to_csv(records, unique=False)
    writer = UnicodeWriter(output, formatter.headers())
    writer.writerow(formatter.headers())
    writer.writerows(rows)
152191
def post_build_time_coverage(self):
        """"""
        from ambry.util.datestimes import expand_to_years

        years = set()

        # From the bundle about
        if self.metadata.about.time:
            for year in expand_to_years(self.metadata.about.time):
                years.add(year)

        # From the bundle name
        if self.identity.btime:
            for year in expand_to_years(self.identity.btime):
                years.add(year)

        # From all of the partitions
        for p in self.partitions:
            years |= set(p.time_coverage)
178275
def report(self):
        """"""
        print('\n{}{}{}'.format(c.Style.BRIGHT, c.Fore.CYAN, 'Report:'))
        # report headers
        print('{!s:<85}{!s:<20}'.format('', 'Validations'))
        print(
            '{!s:<60}{!s:<25}{!s:<10}{!s:<10}'.format(
                'Profile:', 'Execution:', 'Passed:', 'Failed:'
            )
        )
        for r in self.reports:
            d = r.data
            if not d.get('selected'):
                continue

            # execution
            execution_color = c.Fore.RED
            execution_text = 'Failed'
            if d.get('execution_success'):
                execution_color = c.Fore.GREEN
                execution_text = 'Passed'

            # pass count
            pass_count_color = c.Fore.GREEN
            pass_count = d.get('validation_pass_count', 0)
            # fail count
            fail_count = d.get('validation_fail_count', 0)
            fail_count_color = c.Fore.GREEN
            if fail_count > 0:
                fail_count_color = c.Fore.RED

            # report row
            print(
                '{!s:<60}{}{!s:<25}{}{!s:<10}{}{!s:<10}'.format(
                    d.get('name'),
                    execution_color,
                    execution_text,
                    pass_count_color,
                    pass_count,
                    fail_count_color,
                    fail_count,
                )
            )

        # write report to disk
        if self.args.report:
            with open(self.args.report, 'w') as outfile:
                outfile.write(str(self.reports))
544628
function (collector, options) {
	var summaries = [];
	var thresholds = options.thresholds;

	var files = collector.files();
	files.forEach(function(file) {
		summaries.push(istanbul.utils.summarizeFileCoverage(
				collector.fileCoverageFor(file)));
	});

	var finalSummary = istanbul.utils.mergeSummaryObjects.apply(null,
			summaries);

	grunt.util._.each(thresholds, function (threshold, metric) {
		var actual = finalSummary[metric];
		if(!actual) {
			grunt.warn('unrecognized metric: ' + metric);
		}
		if(actual.pct < threshold) {
			grunt.warn('expected ' + metric + ' coverage to be at least '
					+ threshold + '% but was ' + actual.pct + '%');
		}
	});
}
640937
def coverage(args):
    
    p = OptionParser(coverage.__doc__)
    p.add_option("-c", dest="cutoff", default=0.5, type="float",
            help="only report query with coverage greater than [default: %default]")

    opts, args = p.parse_args(args)

    if len(args) != 1:
        sys.exit(not p.print_help())

    coordsfile, = args
    fp = open(coordsfile)

    coords = []
    for row in fp:
        try:
            c = CoordsLine(row)
        except AssertionError:
            continue
        coords.append(c)

    coords.sort(key=lambda x: x.query)

    coverages = []
    for query, lines in groupby(coords, key=lambda x: x.query):
        cumulative_cutoff = sum(x.querycov for x in lines)
        coverages.append((query, cumulative_cutoff))

    coverages.sort(key=lambda x: (-x[1], x[0]))
    for query, cumulative_cutoff in coverages:
        if cumulative_cutoff < opts.cutoff:
            break
        print("{0}\t{1:.2f}".format(query, cumulative_cutoff))
577084
def _generate_index_report(self, index, query_analysis):
        """"""

        all_fields = []
        equiv_fields = []
        sort_fields = []
        range_fields = []

        for query_field in query_analysis['analyzedFields']:
            all_fields.append(query_field['fieldName'])
            if query_field['fieldType'] is EQUIV_TYPE:
                equiv_fields.append(query_field['fieldName'])
            elif query_field['fieldType'] is SORT_TYPE:
                sort_fields.append(query_field['fieldName'])
            elif query_field['fieldType'] is RANGE_TYPE:
                range_fields.append(query_field['fieldName'])

        max_equiv_seq = len(equiv_fields)
        max_sort_seq = max_equiv_seq + len(sort_fields)
        max_range_seq = max_sort_seq + len(range_fields)

        coverage = 'none'
        query_fields_covered = 0
        query_field_count = query_analysis['fieldCount']
        supported = True
        ideal_order = True
        for index_field in index['key']:
            field_name = index_field[0]

            if index_field[1] == '2d':
                supported = False
                break

            if field_name not in all_fields:
                break

            if query_fields_covered == 0:
                coverage = 'partial'

            if query_fields_covered < max_equiv_seq:
                if field_name not in equiv_fields:
                    ideal_order = False
            elif query_fields_covered < max_sort_seq:
                if field_name not in sort_fields:
                    ideal_order = False
            elif query_fields_covered < max_range_seq:
                if field_name not in range_fields:
                    ideal_order = False
            query_fields_covered += 1
        if query_fields_covered == query_field_count:
            coverage = 'full'

        # INDEX REPORT
        return OrderedDict({
            'coverage': coverage,
            'idealOrder': ideal_order,
            'queryFieldsCovered': query_fields_covered,
            'index': index,
            'supported': supported
        })
503346
def get_training_coverage(self):
        
        total = len(self.training_results)
        i = sum(1 for data in self.training_results.values() if not isinstance(data, basestring))
        return i/float(total)
1052562
def collect_impl(self):
        

        for c in DistChange.collect_impl(self):
            if isinstance(c, DistJarChange):
                if c.is_change():
                    ln = DistJarReport.report_name
                    nr = self.reporter.subreporter(c.entry, ln)
                    c = DistJarReport(c.ldata, c.rdata, c.entry, nr)
            elif isinstance(c, DistClassChange):
                if c.is_change():
                    ln = DistClassReport.report_name
                    nr = self.reporter.subreporter(c.entry, ln)
                    c = DistClassReport(c.ldata, c.rdata, c.entry, nr)
            yield c
134752
protected void collectByCover(DBIDRef cur, ModifiableDoubleDBIDList candidates, double fmax, ModifiableDoubleDBIDList collect) {
    assert (collect.size() == 0) : "Not empty";
    DoubleDBIDListIter it = candidates.iter().advance(); // Except first = cur!
    while(it.valid()) {
      assert (!DBIDUtil.equal(cur, it));
      final double dist = distance(cur, it);
      if(dist <= fmax) { // Collect
        collect.add(dist, it);
        candidates.removeSwap(it.getOffset());
      }
      else {
        it.advance(); // Keep in candidates, outside cover radius.
      }
    }
  }
493207
def search(self):
        """"""
        # Retrieve all Or filters pertinent to the special coverage query.
        should_filters = [
            es_filter.Terms(pk=self.query.get("included_ids", [])),
            es_filter.Terms(pk=self.query.get("pinned_ids", []))
        ]
        should_filters += self.get_group_filters()

        # Compile list of all Must filters.
        must_filters = [
            es_filter.Bool(should=should_filters),
            ~es_filter.Terms(pk=self.query.get("excluded_ids", []))
        ]

        return Content.search_objects.search().filter(es_filter.Bool(must=must_filters))
190286
function(app, options) {
  app.post(WRITE_COVERAGE,
    bodyParser,
    (req, res) => {
      let map = istanbul.libCoverage.createCoverageMap();
      coverageHandler(map, options, req, res);
    },
    logError);
}
828810
def worker_collectreport(self, node, rep):
        
        assert not rep.passed
        self._failed_worker_collectreport(node, rep)
741118
def report_sections(self):
    
    # Append to self.sections list

    if len(self.qualimap_bamqc_coverage_hist) > 0:
        # Chew back on histogram to prevent long flat tail
        # (find a sensible max x - lose 1% of longest tail)
        max_x = 0
        total_bases_by_sample = dict()
        for s_name, d in self.qualimap_bamqc_coverage_hist.items():
            total_bases_by_sample[s_name] = sum(d.values())
            cumulative = 0
            for count in sorted(d.keys(), reverse=True):
                cumulative += d[count]
                if cumulative / total_bases_by_sample[s_name] > 0.01:
                    max_x = max(max_x, count)
                    break

        rates_within_threshs = dict()
        for s_name, hist in self.qualimap_bamqc_coverage_hist.items():
            total = total_bases_by_sample[s_name]
            # Make a range of depths that isn't stupidly huge for high coverage expts
            depth_range = list(range(0, max_x + 1, math.ceil(float(max_x)/400.0) if max_x > 0 else 1))
            # Check that we have our specified coverages in the list
            for c in self.covs:
                if int(c) not in depth_range:
                    depth_range.append(int(c))
            # Calculate the coverage rates for this range of coverages
            rates_within_threshs[s_name] = _calculate_bases_within_thresholds(hist, total, depth_range)
            # Add requested coverage levels to the General Statistics table
            for c in self.covs:
                if int(c) in rates_within_threshs[s_name]:
                    self.general_stats_data[s_name]['{}_x_pc'.format(c)] = rates_within_threshs[s_name][int(c)]
                else:
                    self.general_stats_data[s_name]['{}_x_pc'.format(c)] = 0

        # Section 1 - BamQC Coverage Histogram
        coverage_histogram_helptext = '''
        For a set of DNA or RNA reads mapped to a reference sequence, such as a genome
        or transcriptome, the depth of coverage at a given base position is the number
        of high-quality reads that map to the reference at that position
        (<a href="https://doi.org/10.1038/nrg3642" target="_blank">Sims et al. 2014</a>).

        QualiMap groups the bases of a reference sequence by their depth of coverage
        (*0&#215;, 1&#215;, &#8230;, N&#215;*), then plots the number of bases of the
        reference (y-axis) at each level of coverage depth (x-axis). This plot shows
        the frequency of coverage depths relative to the reference sequence for each
        read dataset, which provides an indirect measure of the level and variation of
        coverage depth in the corresponding sequenced sample.

        If reads are randomly distributed across the reference sequence, this plot
        should resemble a Poisson distribution (<a href="https://doi.org/10.1016/0888-7543(88)90007-9"
        target="_blank">Lander & Waterman 1988</a>), with a peak indicating approximate
        depth of coverage, and more uniform coverage depth being reflected in a narrower
        spread. The optimal level of coverage depth depends on the aims of the
        experiment, though it should at minimum be sufficiently high to adequately
        address the biological question; greater uniformity of coverage is generally
        desirable, because it increases breadth of coverage for a given depth of
        coverage, allowing equivalent results to be achieved at a lower sequencing depth
        (<a href="https://doi.org/10.1002/gepi.20575" target="_blank">Sampson
        et al. 2011</a>; <a href="https://doi.org/10.1038/nrg3642" target="_blank">Sims
        et al. 2014</a>). However, it is difficult to achieve uniform coverage
        depth in practice, due to biases introduced during sample preparation
        (<a href="https://doi.org/10.1016/j.yexcr.2014.01.008" target="_blank">van
        Dijk et al. 2014</a>), sequencing (<a href="https://doi.org/10.1186/gb-2013-14-5-r51"
        target="_blank">Ross et al. 2013</a>) and read mapping
        (<a href="https://doi.org/10.1038/nrg3642" target="_blank">Sims et al. 2014</a>).

        This plot may include a small peak for regions of the reference sequence with
        zero depth of coverage. Such regions may be absent from the given sample (due
        to a deletion or structural rearrangement), present in the sample but not
        successfully sequenced (due to bias in sequencing or preparation), or sequenced
        but not successfully mapped to the reference (due to the choice of mapping
        algorithm, the presence of repeat sequences, or mismatches caused by variants
        or sequencing errors). Related factors cause most datasets to contain some
        unmapped reads (<a href="https://doi.org/10.1038/nrg3642" target="_blank">Sims
        et al. 2014</a>).'''
        self.add_section (
            name = 'Coverage histogram',
            anchor = 'qualimap-coverage-histogram',
            description = 'Distribution of the number of locations in the reference genome with a given depth of coverage.',
            helptext = coverage_histogram_helptext,
            plot = linegraph.plot(self.qualimap_bamqc_coverage_hist, {
                'id': 'qualimap_coverage_histogram',
                'title': 'Qualimap BamQC: Coverage histogram',
                'ylab': 'Genome bin counts',
                'xlab': 'Coverage (X)',
                'ymin': 0,
                'xmin': 0,
                'xmax': max_x,
                'xDecimals': False,
                'tt_label': '<b>{point.x}X</b>: {point.y}',
            })
        )
        # Section 2 - BamQC cumulative coverage genome fraction
        genome_fraction_helptext = '''
        For a set of DNA or RNA reads mapped to a reference sequence, such as a genome
        or transcriptome, the depth of coverage at a given base position is the number
        of high-quality reads that map to the reference at that position, while the
        breadth of coverage is the fraction of the reference sequence to which reads
        have been mapped with at least a given depth of coverage
        (<a href="https://doi.org/10.1038/nrg3642" target="_blank">Sims et al. 2014</a>).

        Defining coverage breadth in terms of coverage depth is useful, because
        sequencing experiments typically require a specific minimum depth of coverage
        over the region of interest (<a href="https://doi.org/10.1038/nrg3642"
        target="_blank">Sims et al. 2014</a>), so the extent of the reference sequence
        that is amenable to analysis is constrained to lie within regions that have
        sufficient depth. With inadequate sequencing breadth, it can be difficult to
        distinguish the absence of a biological feature (such as a gene) from a lack
        of data (<a href="https://doi.org/10.1101/gr.7050807" target="_blank">Green 2007</a>).

        For increasing coverage depths (*1&#215;, 2&#215;, &#8230;, N&#215;*),
        QualiMap calculates coverage breadth as the percentage of the reference
        sequence that is covered by at least that number of reads, then plots
        coverage breadth (y-axis) against coverage depth (x-axis). This plot
        shows the relationship between sequencing depth and breadth for each read
        dataset, which can be used to gauge, for example, the likely effect of a
        minimum depth filter on the fraction of a genome available for analysis.'''
        self.add_section (
            name = 'Cumulative genome coverage',
            anchor = 'qualimap-cumulative-genome-fraction-coverage',
            description = 'Percentage of the reference genome with at least the given depth of coverage.',
            helptext = genome_fraction_helptext,
            plot = linegraph.plot(rates_within_threshs, {
                'id': 'qualimap_genome_fraction',
                'title': 'Qualimap BamQC: Genome fraction covered by at least X reads',
                'ylab': 'Fraction of reference (%)',
                'xlab': 'Coverage (X)',
                'ymax': 100,
                'ymin': 0,
                'xmin': 0,
                'xmax': max_x,
                'xDecimals': False,
                'tt_label': '<b>{point.x}X</b>: {point.y:.2f}%',
            })
        )

    # Section 3 - Insert size histogram
    if len(self.qualimap_bamqc_insert_size_hist) > 0:
        insert_size_helptext = '''
        To overcome limitations in the length of DNA or RNA sequencing reads,
        many sequencing instruments can produce two or more shorter reads from
        one longer fragment in which the relative position of reads is
        approximately known, such as paired-end or mate-pair reads
        (<a href="https://doi.org/10.1146/annurev-anchem-062012-092628"
        target="_blank">Mardis 2013</a>). Such techniques can extend the reach
        of sequencing technology, allowing for more accurate placement of reads
        (<a href="https://doi.org/10.1146/annurev-genom-090413-025358"
        target="_blank">Reinert et al. 2015</a>) and better resolution of repeat
        regions (<a href="https://doi.org/10.1146/annurev-genom-090413-025358"
        target="_blank">Reinert et al. 2015</a>), as well as detection of
        structural variation (<a href="https://doi.org/10.1038/nrg2958"
        target="_blank">Alkan et al. 2011</a>) and chimeric transcripts
        (<a href="https://doi.org/10.1073/pnas.0904720106"
        target="_blank">Maher et al. 2009</a>).

        All these methods assume that the approximate size of an insert is known.
        (Insert size can be defined as the length in bases of a sequenced DNA or
        RNA fragment, excluding technical sequences such as adapters, which are
        typically removed before alignment.) This plot allows for that assumption
        to be assessed. With the set of mapped fragments for a given sample, QualiMap
        groups the fragments by insert size, then plots the frequency of mapped
        fragments (y-axis) over a range of insert sizes (x-axis). In an ideal case,
        the distribution of fragment sizes for a sequencing library would culminate
        in a single peak indicating average insert size, with a narrow spread
        indicating highly consistent fragment lengths.

        QualiMap calculates insert sizes as follows: for each fragment in which
        every read mapped successfully to the same reference sequence, it
        extracts the insert size from the `TLEN` field of the leftmost read
        (see the <a href="http://qualimap.bioinfo.cipf.es/doc_html/index.html"
        target="_blank">Qualimap 2 documentation</a>), where the `TLEN` (or
        'observed Template LENgth') field contains 'the number of bases from the
        leftmost mapped base to the rightmost mapped base'
        (<a href="https://samtools.github.io/hts-specs/" target="_blank">SAM
        format specification</a>). Note that because it is defined in terms of
        alignment to a reference sequence, the value of the `TLEN` field may
        differ from the insert size due to factors such as alignment clipping,
        alignment errors, or structural variation or splicing in a gap between
        reads from the same fragment.'''
        self.add_section (
            name = 'Insert size histogram',
            anchor = 'qualimap-insert-size-histogram',
            description = 'Distribution of estimated insert sizes of mapped reads.',
            helptext = insert_size_helptext,
            plot = linegraph.plot(self.qualimap_bamqc_insert_size_hist, {
                'id': 'qualimap_insert_size',
                'title': 'Qualimap BamQC: Insert size histogram',
                'ylab': 'Fraction of reads',
                'xlab': 'Insert Size (bp)',
                'ymin': 0,
                'xmin': 0,
                'tt_label': '<b>{point.x} bp</b>: {point.y}',
            })
        )

    # Section 4 - GC-content distribution
    if len(self.qualimap_bamqc_gc_content_dist) > 0:
        gc_content_helptext = '''
        GC bias is the difference between the guanine-cytosine content
        (GC-content) of a set of sequencing reads and the GC-content of the DNA
        or RNA in the original sample. It is a well-known issue with sequencing
        systems, and may be introduced by PCR amplification, among other factors
        (<a href="https://doi.org/10.1093/nar/gks001" target="_blank">Benjamini
        & Speed 2012</a>; <a href="https://doi.org/10.1186/gb-2013-14-5-r51"
        target="_blank">Ross et al. 2013</a>).

        QualiMap calculates the GC-content of individual mapped reads, then
        groups those reads by their GC-content (*1%, 2%, &#8230;, 100%*), and
        plots the frequency of mapped reads (y-axis) at each level of GC-content
        (x-axis). This plot shows the GC-content distribution of mapped reads
        for each read dataset, which should ideally resemble that of the
        original sample. It can be useful to display the GC-content distribution
        of an appropriate reference sequence for comparison, and QualiMap has an
        option to do this (see the <a href="http://qualimap.bioinfo.cipf.es/doc_html/index.html"
        target="_blank">Qualimap 2 documentation</a>).'''
        extra_series = []
        for i, (species_name, species_data) in enumerate(sorted(self.qualimap_bamqc_gc_by_species.items())):
            extra_series.append({
                'name': species_name,
                'data': list(species_data.items()),
                'dashStyle': 'Dash',
                'lineWidth': 1,
                'color': ['#000000', '#E89191'][i % 2],
            })
        if len(self.qualimap_bamqc_gc_content_dist) == 1:
            desc = 'The solid line represents the distribution of GC content of mapped reads for the sample.'
        else:
            desc = 'Each solid line represents the distribution of GC content of mapped reads for a given sample.'
        lg_config = {
            'id': 'qualimap_gc_content',
            'title': 'Qualimap BamQC: GC content distribution',
            'ylab': 'Fraction of reads',
            'xlab': 'GC content (%)',
            'ymin': 0,
            'xmin': 0,
            'xmax': 100,
            'tt_label': '<b>{point.x}%</b>: {point.y:.3f}'
        }
        if len(extra_series) == 1:
            desc += ' The dotted line represents a pre-calculated GC distribution for the reference genome.'
            lg_config['extra_series'] = extra_series
        elif len(extra_series) > 1:
            desc += ' Each dotted line represents a pre-calculated GC distribution for a specific reference genome.'
            lg_config['extra_series'] = extra_series

        self.add_section (
            name = 'GC content distribution',
            anchor = 'qualimap-gc-distribution',
            description = desc,
            helptext = gc_content_helptext,
            plot = linegraph.plot(self.qualimap_bamqc_gc_content_dist, lg_config)
        )
684075
def list
      files = Dir.glob("#{coverage_dir}/*.html")
      files.map { |file| File.basename(file) }
    end