# Source code for pybedtools.contrib.bigwig

    """
    Module to help create scaled bigWig files from BAM
    """
    import pybedtools
    import os
    import subprocess

    try:
        FileNotFoundError
    except NameError:
        # python2
        FileNotFoundError = OSError

    def mapped_read_count(bam, force=False):
        """
        Scale is cached in a bam.scale file containing the number of mapped reads.
        Use force=True to override caching.
        """
        scale_fn = bam + '.scale'
        if os.path.exists(scale_fn) and not force:
            for line in open(scale_fn):
                if line.startswith('#'):
                    continue
                readcount = float(line.strip())
                return readcount

        cmds = ['samtools',
                'view',
                '-c',
                '-F', '0x4',
                bam]
        p = subprocess.Popen(cmds, stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        stdout, stderr = p.communicate()
        if p.returncode:
            raise ValueError('samtools says: %s' % stderr)

        readcount = float(stdout)

        # write to file so the next time you need the lib size you can access
        # it quickly
        if not os.path.exists(scale_fn):
            fout = open(scale_fn, 'w')
            fout.write(str(readcount) + '\n')
            fout.close()
        return readcount

    def bedgraph_to_bigwig(bedgraph, genome, output):
        genome_file = pybedtools.chromsizes_to_file(pybedtools.chromsizes(genome))
        cmds = [
            'bedGraphToBigWig',
            bedgraph.fn,
            genome_file,
            output]
        try:
            p = subprocess.Popen(cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout, stderr = p.communicate()
        except FileNotFoundError:
            raise FileNotFoundError(
                "bedGraphToBigWig was not found on the path. This is an external "
                "tool from UCSC which can be downloaded from "
                "http://hgdownload.soe.ucsc.edu/admin/exe/. Alternatatively, use "
                "`conda install ucsc-bedgraphtobigwig`"
            )

        if p.returncode:
            raise ValueError("cmds: %s\nstderr:%s\nstdout:%s"
                             % (" ".join(cmds), stderr, stdout))
        return output

    def bigwig_to_bedgraph(fn, chrom=None, start=None, end=None, udcDir=None):
        cmds = [
            'bigWigToBedGraph',
            fn]
        if chrom is not None:
            cmds.extend(['-chrom', chrom])
        if start is not None:
            cmds.extend(['-start', start])
        if end is not None:
            cmds.extend(['-end', end])
        if udcDir is not None:
            cmds.extend(['-udcDir', udcDir])

        outfn = pybedtools.BedTool._tmp()
        cmds.append(outfn)

        try:
            p = subprocess.Popen(cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout, stderr = p.communicate()
        except FileNotFoundError:
            raise FileNotFoundError(
                "bigWigToBedGraph was not found on the path. This is an external "
                "tool from UCSC which can be downloaded from "
                "http://hgdownload.soe.ucsc.edu/admin/exe/. Alternatatively, use "
                "`conda install ucsc-bedgraphtobigwig`"
            )
        if p.returncode:
            raise ValueError("cmds: %s\nstderr:%s\nstdout:%s"
                             % (" ".join(cmds), stderr, stdout))
        return pybedtools.BedTool(outfn)

    def wig_to_bigwig(wig, genome, output):
        genome_file = pybedtools.chromsizes_to_file(pybedtools.chromsizes(genome))
        cmds = [
            'wigToBigWig',
            wig.fn,
            genome_file,
            output]

        try:
            p = subprocess.Popen(cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout, stderr = p.communicate()
        except FileNotFoundError:
            raise FileNotFoundError(
                "bigWigToBedGraph was not found on the path. This is an external "
                "tool from UCSC which can be downloaded from "
                "http://hgdownload.soe.ucsc.edu/admin/exe/. Alternatatively, use "
                "`conda install ucsc-bedgraphtobigwig`"
            )
        if p.returncode:
            raise ValueError('cmds: %s\nstderr:%s\nstdout:%s'
                             % (' '.join(cmds), stderr, stdout))
        return output

    def bam_to_bigwig(bam, genome, output, scale=False):
        """
        Given a BAM file `bam` and assembly `genome`, create a bigWig file scaled
        such that the values represent scaled reads -- that is, reads per million
        mapped reads.

        (Disable this scaling step with scale=False; in this case values will
        indicate number of reads)

        Assumes that `bedGraphToBigWig` from UCSC tools is installed; see
        http://genome.ucsc.edu/goldenPath/help/bigWig.html for more details on the
        format.
        """
        genome_file = pybedtools.chromsizes_to_file(pybedtools.chromsizes(genome))
        kwargs = dict(bg=True, split=True, g=genome_file)
        if scale:
            readcount = mapped_read_count(bam)
            _scale = 1 / (readcount / 1e6)
            kwargs['scale'] = _scale
        x = pybedtools.BedTool(bam).genome_coverage(**kwargs)
        cmds = [
            'bedGraphToBigWig',
            x.fn,
            genome_file,
            output]
        try:
            p = subprocess.Popen(cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
            stdout, stderr = p.communicate()
        except FileNotFoundError:
            raise FileNotFoundError(
                "bedGraphToBigWig was not found on the path. This is an external "
                "tool from UCSC which can be downloaded from "
                "http://hgdownload.soe.ucsc.edu/admin/exe/. Alternatatively, use "
                "`conda install ucsc-bedgraphtobigwig`"
            )

        if p.returncode and  'bedSort' in stderr:
            print('BAM header was not sorted; sorting bedGraph')
            y = x.sort()
            cmds[1] = y.fn
            try:
                p = subprocess.Popen(cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
                stdout, stderr = p.communicate()
            except FileNotFoundError:
                raise FileNotFoundError(
                    "bedSort was not found on the path. This is an external "
                    "tool from UCSC which can be downloaded from "
                    "http://hgdownload.soe.ucsc.edu/admin/exe/. Alternatatively, use "
                    "`conda install ucsc-bedgraphtobigwig`"
                )

        if p.returncode:
            raise ValueError('cmds: %s\nstderr: %s\nstdout: %s'
                             % (' '.join(cmds), stderr, stdout))