# Path: checkm/common.py
# def reassignStdOut(outFile):
#     """Redirect standard out to a file."""
#     oldStdOut = sys.stdout
#     if(outFile != ''):
#         try:
#             # redirect stdout to a file
#             sys.stdout = open(outFile, 'w')
#         except:
#             logger = logging.getLogger('timestamp')
#             logger.error("Error diverting stdout to file: " + outFile)
#             sys.exit(1)
# 
#     return oldStdOut
# 
# def restoreStdOut(outFile, oldStdOut):
#     """Redirect standard out back to system standard out."""
#     if(outFile != ''):
#         try:
#             # redirect stdout to a file
#             sys.stdout.close()
#             sys.stdout = oldStdOut
#         except:
#             logger = logging.getLogger('timestamp')
#             logger.error("Error restoring stdout ", outFile)
#             sys.exit(1)
# 
# def binIdFromFilename(filename):
#     """Extract bin id from bin filename."""
#     binId = os.path.basename(filename)
#     binId = os.path.splitext(binId)[0]
# 
#     return binId
# 
# Path: checkm/util/seqUtils.py
# def readFasta(fastaFile, trimHeader=True):
#     '''Read sequences from FASTA file.'''
#     try:
#         if fastaFile.endswith('.gz'):
#             openFile = gzip.open
#         else:
#             openFile = open
# 
#         seqs = {}
#         for line in openFile(fastaFile):
#             # skip blank lines
#             if not line.strip():
#                 continue
# 
#             if line[0] == '>':
#                 if trimHeader:
#                     seqId = line[1:].split(None, 1)[0]
#                 else:
#                     seqId = line[1:].rstrip()
#                 seqs[seqId] = []
#             else:
#                 seqs[seqId].append(line[0:-1])
# 
#         for seqId, seq in seqs.items():
#             seqs[seqId] = ''.join(seq)
#     except:
#         logger = logging.getLogger('timestamp')
#         logger.error("Failed to process sequence file: {}".format(fastaFile))
#         sys.exit(1)
# 
#     return seqs


import sys
import os
import multiprocessing as mp
import logging
import ntpath
import traceback
import pysam
from collections import defaultdict
from checkm.defaultValues import DefaultValues
from checkm.common import reassignStdOut, restoreStdOut, binIdFromFilename
from checkm.util.seqUtils import readFasta
from numpy import mean, sqrt
###############################################################################






class CoverageStruct():
    def __init__(self, seqLen, mappedReads, coverage):
        self.seqLen = seqLen
        self.mappedReads = mappedReads
        self.coverage = coverage


class Coverage():
    """Calculate coverage of all sequences."""
    def __init__(self, threads):
        self.logger = logging.getLogger('timestamp')

        self.totalThreads = threads

    def run(self, binFiles, bamFiles, outFile, bAllReads, minAlignPer, maxEditDistPer, minQC):
        """Calculate coverage of sequences for each BAM file."""

        # determine bin assignment of each sequence
        self.logger.info('Determining bin assignment of each sequence.')

        seqIdToBinId = {}
        seqIdToSeqLen = {}
        for binFile in binFiles:

# Path: checkm/common.py
# def reassignStdOut(outFile):
#     """Redirect standard out to a file."""
#     oldStdOut = sys.stdout
#     if(outFile != ''):
#         try:
#             # redirect stdout to a file
#             sys.stdout = open(outFile, 'w')
#         except:
#             logger = logging.getLogger('timestamp')
#             logger.error("Error diverting stdout to file: " + outFile)
#             sys.exit(1)
# 
#     return oldStdOut
# 
# def restoreStdOut(outFile, oldStdOut):
#     """Redirect standard out back to system standard out."""
#     if(outFile != ''):
#         try:
#             # redirect stdout to a file
#             sys.stdout.close()
#             sys.stdout = oldStdOut
#         except:
#             logger = logging.getLogger('timestamp')
#             logger.error("Error restoring stdout ", outFile)
#             sys.exit(1)
# 
# def binIdFromFilename(filename):
#     """Extract bin id from bin filename."""
#     binId = os.path.basename(filename)
#     binId = os.path.splitext(binId)[0]
# 
#     return binId
# 
# Path: checkm/util/seqUtils.py
# def readFasta(fastaFile, trimHeader=True):
#     '''Read sequences from FASTA file.'''
#     try:
#         if fastaFile.endswith('.gz'):
#             openFile = gzip.open
#         else:
#             openFile = open
# 
#         seqs = {}
#         for line in openFile(fastaFile):
#             # skip blank lines
#             if not line.strip():
#                 continue
# 
#             if line[0] == '>':
#                 if trimHeader:
#                     seqId = line[1:].split(None, 1)[0]
#                 else:
#                     seqId = line[1:].rstrip()
#                 seqs[seqId] = []
#             else:
#                 seqs[seqId].append(line[0:-1])
# 
#         for seqId, seq in seqs.items():
#             seqs[seqId] = ''.join(seq)
#     except:
#         logger = logging.getLogger('timestamp')
#         logger.error("Failed to process sequence file: {}".format(fastaFile))
#         sys.exit(1)
# 
#     return seqs


# Path: checkm/coverage.py
import sys
import os
import multiprocessing as mp
import logging
import ntpath
import traceback
import pysam
from collections import defaultdict
from checkm.defaultValues import DefaultValues
from checkm.common import reassignStdOut, restoreStdOut, binIdFromFilename
from checkm.util.seqUtils import readFasta
from numpy import mean, sqrt

###############################################################################






class CoverageStruct():
    def __init__(self, seqLen, mappedReads, coverage):
        self.seqLen = seqLen
        self.mappedReads = mappedReads
        self.coverage = coverage


class Coverage():
    """Calculate coverage of all sequences."""
    def __init__(self, threads):
        self.logger = logging.getLogger('timestamp')

        self.totalThreads = threads

    def run(self, binFiles, bamFiles, outFile, bAllReads, minAlignPer, maxEditDistPer, minQC):
        """Calculate coverage of sequences for each BAM file."""

        # determine bin assignment of each sequence
        self.logger.info('Determining bin assignment of each sequence.')

        seqIdToBinId = {}
        seqIdToSeqLen = {}
        for binFile in binFiles:

            binId = binIdFromFilename(binFile)