# 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

        # calculate coverage of each BAM file
        coverageInfo = {}
        numFilesStarted = 0
        for bamFile in bamFiles:
            numFilesStarted += 1
            self.logger.info('Processing %s (%d of %d):' % (ntpath.basename(bamFile), numFilesStarted, len(bamFiles)))

            coverageInfo[bamFile] = mp.Manager().dict()
            coverageInfo[bamFile] = self.__processBam(bamFile, bAllReads, minAlignPer, maxEditDistPer, minQC, coverageInfo[bamFile])

        # redirect output
        self.logger.info('Writing coverage information to file.')
        oldStdOut = reassignStdOut(outFile)

        header = 'Sequence Id\tBin Id\tSequence length (bp)'
        for bamFile in bamFiles:
            header += '\tBam Id\tCoverage\tMapped reads'

        print(header)

        # get length of all seqs
        for bamFile, seqIds in coverageInfo.items():
            for seqId in seqIds.keys():
                seqIdToSeqLen[seqId] = seqIds[seqId].seqLen

        # write coverage stats for all scaffolds to file
        for seqId, seqLen in seqIdToSeqLen.items():
            rowStr = seqId + '\t' + seqIdToBinId.get(seqId, DefaultValues.UNBINNED) + '\t' + str(seqLen)
            for bamFile in bamFiles:

# 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


        # calculate coverage of each BAM file
        coverageInfo = {}
        numFilesStarted = 0
        for bamFile in bamFiles:
            numFilesStarted += 1
            self.logger.info('Processing %s (%d of %d):' % (ntpath.basename(bamFile), numFilesStarted, len(bamFiles)))

            coverageInfo[bamFile] = mp.Manager().dict()
            coverageInfo[bamFile] = self.__processBam(bamFile, bAllReads, minAlignPer, maxEditDistPer, minQC, coverageInfo[bamFile])

        # redirect output
        self.logger.info('Writing coverage information to file.')
        oldStdOut = reassignStdOut(outFile)

        header = 'Sequence Id\tBin Id\tSequence length (bp)'
        for bamFile in bamFiles:
            header += '\tBam Id\tCoverage\tMapped reads'

        print(header)

        # get length of all seqs
        for bamFile, seqIds in coverageInfo.items():
            for seqId in seqIds.keys():
                seqIdToSeqLen[seqId] = seqIds[seqId].seqLen

        # write coverage stats for all scaffolds to file
        for seqId, seqLen in seqIdToSeqLen.items():
            rowStr = seqId + '\t' + seqIdToBinId.get(seqId, DefaultValues.UNBINNED) + '\t' + str(seqLen)
            for bamFile in bamFiles:

                bamId = binIdFromFilename(bamFile)