# Path: nanopore/mappers/abstractMapper.py
# class AbstractMapper(Target):
#     """Base class for mappers. Inherit this class to create a mapper
#     """
#     def __init__(self, readFastqFile, readType, referenceFastaFile, outputSamFile, emptyHmmFile=None):
#         Target.__init__(self)
#         self.readFastqFile = readFastqFile
#         self.referenceFastaFile = referenceFastaFile
#         self.outputSamFile = outputSamFile
#         self.readType = readType
#         self.emptyHmmFile=emptyHmmFile
#         
#     def chainSamFile(self):
#         """Converts the sam file so that there is at most one global alignment of each read
#         """ 
#         tempSamFile = os.path.join(self.getLocalTempDir(), "temp.sam")
#         system("cp %s %s" % (self.outputSamFile, tempSamFile))
#         chainSamFile(tempSamFile, self.outputSamFile, self.readFastqFile, self.referenceFastaFile)
#     
#     def realignSamFile(self, gapGamma=0.5, matchGamma=0.0, doEm=False,  useTrainedModel=False, trainedModelFile="blasr_hmm_0.txt"):
#         """Chains and then realigns the resulting global alignments.
#         """
#         tempSamFile = os.path.join(self.getGlobalTempDir(), "temp.sam")
#         if useTrainedModel and doEm:
#             raise RuntimeError("Attempting to train stock model")
#         system("cp %s %s" % (self.outputSamFile, tempSamFile))
#         if doEm:
#             hmmFile = self.emptyHmmFile
#         elif useTrainedModel:
#             hmmFile = os.path.join(pathToBaseNanoporeDir(), "nanopore", "mappers", trainedModelFile)
#         else:
#             hmmFile = None
#         self.addChildTargetFn(realignSamFileTargetFn, args=(tempSamFile, self.outputSamFile, 
#                                                             self.readFastqFile, self.referenceFastaFile, gapGamma, matchGamma, hmmFile, doEm))
# 
# Path: nanopore/mappers/last_params.py
# class LastParams(Last):
#     def run(self):
#         Last.run(self, params="-s 2 -T 0 -Q 0 -a 1")
# 
# Path: nanopore/mappers/lastzParams.py
# class LastzParams(Lastz):
#     def run(self):
#         #scoreFile = os.path.join(pathToBaseNanoporeDir(), "nanopore", "mappers", "last_em_575_M13_2D_scores.txt")
#         #Lastz.run(self, args="--hspthresh=1200 --gappedthresh=1500  --seed=match12 --scores=%s" % scoreFile)
#         Lastz.run(self, args="--hspthresh=1800 --gap=100,100")
# 
# Path: nanopore/mappers/bwa_params.py
# class BwaParams(Bwa):
#     def run(self):
#         Bwa.run(self, args="-x pacbio")
# 
# Path: nanopore/mappers/blasr_params.py
# class BlasrParams(Blasr):
#     def run(self):
#         Blasr.run(self, args="-sdpTupleSize 8 -bestn 1 -m 0")
#         #system("blasr %s %s -sdpTupleSize 8 -bestn 1 -clipping hard -nproc 8 -sam -out %s -m 0" % (self.readFastqFile, self.referenceFastaFile, self.outputSamFile))
# 
# Path: nanopore/analyses/utils.py
# def combineSamFiles(baseSamFile, extraSamFiles, outputSamFile):
#     """Combines the lines from multiple sam files into one sam file
#     """
#     sam = pysam.Samfile(baseSamFile, "r" )
#     outputSam = pysam.Samfile(outputSamFile, "wh", template=sam)
#     sam.close()
#     for samFile in [ baseSamFile  ] + extraSamFiles:
#         sam = pysam.Samfile(samFile, "r" )
#         for line in sam:
#             outputSam.write(line)
#         sam.close()
#     outputSam.close()


from nanopore.mappers.abstractMapper import AbstractMapper
from nanopore.mappers.last_params import LastParams
from nanopore.mappers.lastzParams import LastzParams
from nanopore.mappers.bwa_params import BwaParams
from nanopore.mappers.blasr_params import BlasrParams
from nanopore.analyses.utils import combineSamFiles
import pysam
import os



class CombinedMapper(AbstractMapper):
    def run(self):
        #Make child mapping job for each mapper
        mappers=[ LastParams, LastzParams, BwaParams, BlasrParams]
        tempSamFiles = []
        tempHmmFiles = []
        for mapper in mappers:
            tempSamFiles.append(os.path.join(self.getGlobalTempDir(), "mapping_%s.sam" % mapper.__name__))
            tempHmmFiles.append(os.path.join(self.getGlobalTempDir(), "mapping_%s.hmm" % mapper.__name__))
            self.addChildTarget(mapper(self.readFastqFile, self.readType, self.referenceFastaFile, tempSamFiles[-1], tempHmmFiles[-1]))
        #Now make a follow on to cat together the different alignments
        self.setFollowOnFn(combineSamFiles, args=(tempSamFiles[0], tempSamFiles[1:], self.outputSamFile))

class CombinedMapperChain2(AbstractMapper):
    def run(self):
        self.chainSamFile()

class CombinedMapperChain(AbstractMapper):
    def run(self, followOnMapper=CombinedMapperChain2):
        self.addChildTarget(CombinedMapper(self.readFastqFile, self.readType, self.referenceFastaFile, self.outputSamFile, self.emptyHmmFile))
        self.setFollowOnTarget(followOnMapper(self.readFastqFile, self.readType, self.referenceFastaFile, self.outputSamFile, self.emptyHmmFile))


# Path: nanopore/mappers/abstractMapper.py
# class AbstractMapper(Target):
#     """Base class for mappers. Inherit this class to create a mapper
#     """
#     def __init__(self, readFastqFile, readType, referenceFastaFile, outputSamFile, emptyHmmFile=None):
#         Target.__init__(self)
#         self.readFastqFile = readFastqFile
#         self.referenceFastaFile = referenceFastaFile
#         self.outputSamFile = outputSamFile
#         self.readType = readType
#         self.emptyHmmFile=emptyHmmFile
#         
#     def chainSamFile(self):
#         """Converts the sam file so that there is at most one global alignment of each read
#         """ 
#         tempSamFile = os.path.join(self.getLocalTempDir(), "temp.sam")
#         system("cp %s %s" % (self.outputSamFile, tempSamFile))
#         chainSamFile(tempSamFile, self.outputSamFile, self.readFastqFile, self.referenceFastaFile)
#     
#     def realignSamFile(self, gapGamma=0.5, matchGamma=0.0, doEm=False,  useTrainedModel=False, trainedModelFile="blasr_hmm_0.txt"):
#         """Chains and then realigns the resulting global alignments.
#         """
#         tempSamFile = os.path.join(self.getGlobalTempDir(), "temp.sam")
#         if useTrainedModel and doEm:
#             raise RuntimeError("Attempting to train stock model")
#         system("cp %s %s" % (self.outputSamFile, tempSamFile))
#         if doEm:
#             hmmFile = self.emptyHmmFile
#         elif useTrainedModel:
#             hmmFile = os.path.join(pathToBaseNanoporeDir(), "nanopore", "mappers", trainedModelFile)
#         else:
#             hmmFile = None
#         self.addChildTargetFn(realignSamFileTargetFn, args=(tempSamFile, self.outputSamFile, 
#                                                             self.readFastqFile, self.referenceFastaFile, gapGamma, matchGamma, hmmFile, doEm))
# 
# Path: nanopore/mappers/last_params.py
# class LastParams(Last):
#     def run(self):
#         Last.run(self, params="-s 2 -T 0 -Q 0 -a 1")
# 
# Path: nanopore/mappers/lastzParams.py
# class LastzParams(Lastz):
#     def run(self):
#         #scoreFile = os.path.join(pathToBaseNanoporeDir(), "nanopore", "mappers", "last_em_575_M13_2D_scores.txt")
#         #Lastz.run(self, args="--hspthresh=1200 --gappedthresh=1500  --seed=match12 --scores=%s" % scoreFile)
#         Lastz.run(self, args="--hspthresh=1800 --gap=100,100")
# 
# Path: nanopore/mappers/bwa_params.py
# class BwaParams(Bwa):
#     def run(self):
#         Bwa.run(self, args="-x pacbio")
# 
# Path: nanopore/mappers/blasr_params.py
# class BlasrParams(Blasr):
#     def run(self):
#         Blasr.run(self, args="-sdpTupleSize 8 -bestn 1 -m 0")
#         #system("blasr %s %s -sdpTupleSize 8 -bestn 1 -clipping hard -nproc 8 -sam -out %s -m 0" % (self.readFastqFile, self.referenceFastaFile, self.outputSamFile))
# 
# Path: nanopore/analyses/utils.py
# def combineSamFiles(baseSamFile, extraSamFiles, outputSamFile):
#     """Combines the lines from multiple sam files into one sam file
#     """
#     sam = pysam.Samfile(baseSamFile, "r" )
#     outputSam = pysam.Samfile(outputSamFile, "wh", template=sam)
#     sam.close()
#     for samFile in [ baseSamFile  ] + extraSamFiles:
#         sam = pysam.Samfile(samFile, "r" )
#         for line in sam:
#             outputSam.write(line)
#         sam.close()
#     outputSam.close()


# Path: nanopore/mappers/combinedMapper.py
from nanopore.mappers.abstractMapper import AbstractMapper
from nanopore.mappers.last_params import LastParams
from nanopore.mappers.lastzParams import LastzParams
from nanopore.mappers.bwa_params import BwaParams
from nanopore.mappers.blasr_params import BlasrParams
from nanopore.analyses.utils import combineSamFiles
import pysam
import os




class CombinedMapper(AbstractMapper):
    def run(self):
        #Make child mapping job for each mapper
        mappers=[ LastParams, LastzParams, BwaParams, BlasrParams]
        tempSamFiles = []
        tempHmmFiles = []
        for mapper in mappers:
            tempSamFiles.append(os.path.join(self.getGlobalTempDir(), "mapping_%s.sam" % mapper.__name__))
            tempHmmFiles.append(os.path.join(self.getGlobalTempDir(), "mapping_%s.hmm" % mapper.__name__))
            self.addChildTarget(mapper(self.readFastqFile, self.readType, self.referenceFastaFile, tempSamFiles[-1], tempHmmFiles[-1]))
        #Now make a follow on to cat together the different alignments
        self.setFollowOnFn(combineSamFiles, args=(tempSamFiles[0], tempSamFiles[1:], self.outputSamFile))

class CombinedMapperChain2(AbstractMapper):
    def run(self):
        self.chainSamFile()

class CombinedMapperChain(AbstractMapper):
    def run(self, followOnMapper=CombinedMapperChain2):
        self.addChildTarget(CombinedMapper(self.readFastqFile, self.readType, self.referenceFastaFile, self.outputSamFile, self.emptyHmmFile))
        self.setFollowOnTarget(followOnMapper(self.readFastqFile, self.readType, self.referenceFastaFile, self.outputSamFile, self.emptyHmmFile))


class CombinedMapperRealign2(AbstractMapper):