def preprocess(self, preargs):
        self.base = preargs[0]
        self.fwd = preargs[1]
        self.rev = preargs[2]
        self.datadir = preargs[3]

        #Run quality control ananlysis and quality based trimming
        qcdir = os.path.abspath(self.datadir) + '/qc'
        if not os.path.exists(qcdir):
            os.mkdir(qcdir)
        self.fwd, self.rev = trimgalore.run_qc(self.fwd, self.rev, qcdir, 
            self.base)

        #Run alignment
        self.bamfile = bowtie.bowtie(self.fwd, self.rev, self.datadir, 
            self.base)
        
        #Run picard tools 
        self.bamfile = picard.addreadgroup(self.bamfile, self.base)
        self.bamfile, self.metrics = picard.markdup(self.bamfile)

        #Run GATK realignment and quality recalibration
        self.interval = gatk.target(self.bamfile)
        self.bamfile = gatk.realigner(self.bamfile, self.interval)
        self.table = gatk.baserecal(self.bamfile)
        self.bamfile = gatk.printreads(self.bamfile, self.table)
        self.gvcf = gatk.haplocaller(self.bamfile)
        return(self.gvcf)
    def align(self, alargs):
        # Run alignment
        self.base = alargs[0]
        self.fwd = alargs[1]
        self.rev = alargs[2]
        self.datadir = alargs[3]
        self.bamfile = bowtie.bowtie(self.fwd, self.rev, self.datadir, self.base)

        # Run picard tools
        self.bamfile = picard.addreadgroup(self.bamfile, self.base)
        self.bamfile, self.metrics = picard.markdup(self.bamfile)

        # Run GATK realignment and quality recalibration
        self.interval = gatk.target(self.bamfile)
        self.bamfile = gatk.realigner(self.bamfile, self.interval)
        self.table = gatk.baserecal(self.bamfile)
        self.bamfile = gatk.printreads(self.bamfile, self.table)
        self.vcf = gatk.haplocaller(self.bamfile)
        print(self.vcf)