コード例 #1
0
def main(g_params):#{{{
    submitjoblogfile = "%s/submitted_seq.log"%(path_log)
    runjoblogfile = "%s/runjob_log.log"%(path_log)
    finishedjoblogfile = "%s/finished_job.log"%(path_log)

    if not os.path.exists(path_cache):
        os.mkdir(path_cache)

    loop = 0
    while 1:
        if os.path.exists("%s/CACHE_CLEANING_IN_PROGRESS"%(path_result)):#pause when cache cleaning is in progress
            continue
        # load the config file if exists
        configfile = "%s/config/config.json"%(basedir)
        config = {}
        if os.path.exists(configfile):
            text = myfunc.ReadFile(configfile)
            config = json.loads(text)

        if rootname_progname in config:
            g_params.update(config[rootname_progname])

        if os.path.exists(black_iplist_file):
            g_params['blackiplist'] = myfunc.ReadIDList(black_iplist_file)

        os.environ['TZ'] = g_params['TZ']
        time.tzset()

        avail_computenode = webcom.ReadComputeNode(computenodefile) # return value is a dict
        g_params['vip_user_list'] = myfunc.ReadIDList2(vip_email_file,  col=0)
        num_avail_node = len(avail_computenode)

        webcom.loginfo("loop %d"%(loop), gen_logfile)

        isOldRstdirDeleted = False
        if loop % g_params['STATUS_UPDATE_FREQUENCY'][0] == g_params['STATUS_UPDATE_FREQUENCY'][1]:
            qdcom.RunStatistics_basic(webserver_root, gen_logfile, gen_errfile)
            isOldRstdirDeleted = webcom.DeleteOldResult(path_result, path_log,
                    gen_logfile, MAX_KEEP_DAYS=g_params['MAX_KEEP_DAYS'])
            webcom.CleanServerFile(path_static, gen_logfile, gen_errfile)

        if 'DEBUG_ARCHIVE' in g_params and g_params['DEBUG_ARCHIVE']:
            webcom.loginfo("Run ArchiveLogFile, path_log=%s, threshold_logfilesize=%d"%(path_log, threshold_logfilesize), gen_logfile)
        webcom.ArchiveLogFile(path_log, threshold_logfilesize=threshold_logfilesize) 

        qdcom.CreateRunJoblog(loop, isOldRstdirDeleted, g_params)

        # Get number of jobs submitted to the remote server based on the
        # runjoblogfile
        runjobidlist = myfunc.ReadIDList2(runjoblogfile,0)
        remotequeueDict = {}
        for node in avail_computenode:
            remotequeueDict[node] = []
        for jobid in runjobidlist:
            rstdir = "%s/%s"%(path_result, jobid)
            remotequeue_idx_file = "%s/remotequeue_seqindex.txt"%(rstdir)
            if os.path.exists(remotequeue_idx_file):
                content = myfunc.ReadFile(remotequeue_idx_file)
                lines = content.split('\n')
                for line in lines:
                    strs = line.split('\t')
                    if len(strs)>=5:
                        node = strs[1]
                        remotejobid = strs[2]
                        if node in remotequeueDict:
                            remotequeueDict[node].append(remotejobid)

        cntSubmitJobDict = {} # format of cntSubmitJobDict {'node_ip': [INT, INT, STR]}
        for node in avail_computenode:
            queue_method = avail_computenode[node]['queue_method']
            num_queue_job = len(remotequeueDict[node])
            if num_queue_job >= 0:
                cntSubmitJobDict[node] = [num_queue_job,
                        g_params['MAX_SUBMIT_JOB_PER_NODE'], queue_method]
            else:
                cntSubmitJobDict[node] = [g_params['MAX_SUBMIT_JOB_PER_NODE'],
                        g_params['MAX_SUBMIT_JOB_PER_NODE'], queue_method]

# entries in runjoblogfile includes jobs in queue or running
        hdl = myfunc.ReadLineByBlock(runjoblogfile)
        if not hdl.failure:
            lines = hdl.readlines()
            while lines != None:
                for line in lines:
                    strs = line.split("\t")
                    if len(strs) >= 11:
                        jobid = strs[0]
                        email = strs[4]
                        try:
                            numseq = int(strs[5])
                        except:
                            numseq = 1
                        try:
                            numseq_this_user = int(strs[10])
                        except:
                            numseq_this_user = 1
                        rstdir = "%s/%s"%(path_result, jobid)
                        finishtagfile = "%s/%s"%(rstdir, "runjob.finish")
                        status = strs[1]
                        webcom.loginfo("CompNodeStatus: %s"%(str(cntSubmitJobDict)), gen_logfile)

                        runjob_lockfile = "%s/%s/%s.lock"%(path_result, jobid, "runjob.lock")
                        if os.path.exists(runjob_lockfile):
                            msg = "runjob_lockfile %s exists, ignore the job %s" %(runjob_lockfile, jobid)
                            webcom.loginfo(msg, gen_logfile)
                            continue

                        #if IsHaveAvailNode(cntSubmitJobDict):
                        if not g_params['DEBUG_NO_SUBMIT']:
                            qdcom.SubmitJob(jobid, cntSubmitJobDict, numseq_this_user, g_params)
                        qdcom.GetResult(jobid, g_params) # the start tagfile is written when got the first result
                        qdcom.CheckIfJobFinished(jobid, numseq, email, g_params)

                lines = hdl.readlines()
            hdl.close()

        myfunc.WriteFile("sleep for %d seconds\n"%(g_params['SLEEP_INTERVAL']), gen_logfile, "a", True)
        time.sleep(g_params['SLEEP_INTERVAL'])
        loop += 1

    return 0
コード例 #2
0
def main(g_params):  #{{{
    argv = sys.argv
    numArgv = len(argv)
    if numArgv < 2:
        PrintHelp()
        return 1

    rmsg = ""
    outpath = ""
    jobid = ""
    datapath = ""
    numseq = -1
    numseq_this_user = -1
    email = ""
    host_ip = ""
    base_www_url = ""
    i = 1
    isNonOptionArg = False
    while i < numArgv:
        if isNonOptionArg == True:
            webcom.loginfo("Error! Wrong argument: %s" % (argv[i]),
                           gen_errfile)
            return 1
            isNonOptionArg = False
            i += 1
        elif argv[i] == "--":
            isNonOptionArg = True
            i += 1
        elif argv[i][0] == "-":
            if argv[i] in ["-h", "--help"]:
                PrintHelp()
                return 1
            elif argv[i] in ["-outpath", "--outpath"]:
                (outpath, i) = myfunc.my_getopt_str(argv, i)
            elif argv[i] in ["-email", "--email"]:
                (email, i) = myfunc.my_getopt_str(argv, i)
            elif argv[i] in ["-host", "--host"]:
                (host_ip, i) = myfunc.my_getopt_str(argv, i)
            elif argv[i] in ["-nseq", "--nseq"]:
                (numseq, i) = myfunc.my_getopt_int(argv, i)
            elif argv[i] in ["-nseq-this-user", "--nseq-this-user"]:
                (numseq_this_user, i) = myfunc.my_getopt_int(argv, i)
            elif argv[i] in ["-baseurl", "--baseurl"]:
                (base_www_url, i) = myfunc.my_getopt_str(argv, i)
            elif argv[i] in ["-jobid", "--jobid"]:
                (jobid, i) = myfunc.my_getopt_str(argv, i)
            elif argv[i] in ["-datapath", "--datapath"]:
                (datapath, i) = myfunc.my_getopt_str(argv, i)
            elif argv[i] in ["-force", "--force"]:
                g_params['isForceRun'] = True
                i += 1
            elif argv[i] in ["-only-get-cache", "--only-get-cache"]:
                g_params['isOnlyGetCache'] = True
                i += 1
            elif argv[i] in ["-q", "--q"]:
                g_params['isQuiet'] = True
                i += 1
            else:
                webcom.loginfo("Error! Wrong argument: %s" % (argv[i]),
                               gen_errfile)
                return 1
        else:
            webcom.loginfo("Error! Wrong argument: %s" % (argv[i]),
                           gen_errfile)
            return 1

    if outpath == "":
        webcom.loginfo("outpath not set. exit", gen_errfile)
        return 1
    elif not os.path.exists(outpath):
        cmd = ["mkdir", "-p", outpath]
        try:
            rmsg = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as e:
            print(e)
            print(rmsg)
            return 1

    if jobid == "":
        webcom.loginfo("%s: jobid not set. exit" % (sys.argv[0]), gen_errfile)
        return 1

    if datapath == "":
        webcom.loginfo("%s: datapath not set. exit" % (sys.argv[0]),
                       gen_errfile)
        return 1
    elif not os.path.exists(datapath):
        webcom.loginfo("%s: datapath does not exist. exit" % (sys.argv[0]),
                       gen_errfile)
        return 1
    elif not os.path.exists("%s/query.fa" % (datapath)):
        webcom.loginfo(
            "%s: file %s/query.fa does not exist. exit" %
            (sys.argv[0], datapath), gen_errfile)
        return 1

    g_params['debugfile'] = "%s/debug.log" % (outpath)

    webcom.loginfo("Go to SubmitJobToQueue()", g_params['debugfile'])
    return SubmitJobToQueue(jobid, datapath, outpath, numseq, numseq_this_user,
                            email, host_ip, base_www_url)
コード例 #3
0
def SubmitJobToQueue(
        jobid,
        datapath,
        outpath,
        numseq,
        numseq_this_user,
        email,  #{{{
        host_ip,
        base_www_url):
    myfunc.WriteFile("Entering SubmitJobToQueue()\n", g_params['debugfile'],
                     "a", True)
    fafile = "%s/query.fa" % (datapath)

    if numseq == -1:
        numseq = myfunc.CountFastaSeq(fafile)
    if numseq_this_user == -1:
        numseq_this_user = numseq

    query_parafile = "%s/query.para.txt" % (outpath)

    query_para = {}
    content = myfunc.ReadFile(query_parafile)
    para_str = content
    if content != "":
        query_para = json.loads(content)

    try:
        name_software = query_para['name_software']
    except KeyError:
        name_software = "prodres"

    runjob = "%s %s/run_job.py" % (python_exec, rundir)
    scriptfile = "%s/runjob,%s,%s,%s,%s,%d.sh" % (
        outpath, name_software, jobid, host_ip, email, numseq)
    code_str_list = []
    code_str_list.append("#!/bin/bash")
    code_str_list.append("source %s/bin/activate" % (virt_env_path))
    cmdline = "%s %s -outpath %s -tmpdir %s -jobid %s " % (
        runjob, fafile, outpath, datapath, jobid)
    if email != "":
        cmdline += "-email \"%s\" " % (email)
    if base_www_url != "":
        cmdline += "-baseurl \"%s\" " % (base_www_url)
    if g_params['isForceRun']:
        cmdline += "-force "
    if g_params['isOnlyGetCache']:
        cmdline += "-only-get-cache "
    code_str_list.append(cmdline)

    code = "\n".join(code_str_list)

    msg = "Writting scriptfile %s" % (scriptfile)
    webcom.loginfo(msg, g_params['debugfile'])

    myfunc.WriteFile(code, scriptfile, mode="w", isFlush=True)
    os.chmod(scriptfile, 0o755)

    webcom.loginfo("Getting priority", g_params['debugfile'])
    priority = myfunc.GetSuqPriority(numseq_this_user)

    if email in vip_user_list:
        priority = 999999999.0

    webcom.loginfo("priority=%d" % (priority), g_params['debugfile'])

    st1 = webcom.SubmitSlurmJob(datapath, outpath, scriptfile,
                                g_params['debugfile'])

    return st1
コード例 #4
0
def RunJob(infile, outpath, tmpdir, email, jobid, g_params):  #{{{
    all_begin_time = time.time()

    rootname = os.path.basename(os.path.splitext(infile)[0])
    starttagfile = "%s/runjob.start" % (outpath)
    runjob_errfile = "%s/runjob.err" % (outpath)
    runjob_logfile = "%s/runjob.log" % (outpath)
    app_logfile = "%s/app.log" % (outpath)
    finishtagfile = "%s/runjob.finish" % (outpath)
    failedtagfile = "%s/runjob.failed" % (outpath)
    query_parafile = "%s/query.para.txt" % (outpath)

    query_para = ""
    content = myfunc.ReadFile(query_parafile)
    if content != "":
        query_para = json.loads(content)

    rmsg = ""

    resultpathname = jobid

    outpath_result = "%s/%s" % (outpath, resultpathname)
    tmp_outpath_result = "%s/%s" % (tmpdir, resultpathname)

    tarball = "%s.tar.gz" % (resultpathname)
    zipfile = "%s.zip" % (resultpathname)
    tarball_fullpath = "%s.tar.gz" % (outpath_result)
    zipfile_fullpath = "%s.zip" % (outpath_result)
    resultfile_text = "%s/%s" % (outpath_result, "query.result.txt")
    mapfile = "%s/seqid_index_map.txt" % (outpath_result)
    finished_seq_file = "%s/finished_seqs.txt" % (outpath_result)

    for folder in [outpath_result, tmp_outpath_result]:
        try:
            os.makedirs(folder)
        except OSError:
            msg = "Failed to create folder %s" % (folder)
            myfunc.WriteFile(msg + "\n", gen_errfile, "a")
            return 1
    try:
        open(finished_seq_file, 'w').close()
    except:
        pass
#first getting result from caches
# ==================================

    maplist = []
    maplist_simple = []
    toRunDict = {}
    hdl = myfunc.ReadFastaByBlock(infile, method_seqid=0, method_seq=0)
    if hdl.failure:
        isOK = False
    else:
        webcom.WriteDateTimeTagFile(starttagfile, runjob_logfile,
                                    runjob_errfile)
        recordList = hdl.readseq()
        cnt = 0
        origpath = os.getcwd()
        while recordList != None:
            for rd in recordList:
                isSkip = False
                # temp outpath for the sequence is always seq_0, and I feed
                # only one seq a time to the workflow
                tmp_outpath_this_seq = "%s/%s" % (tmp_outpath_result,
                                                  "seq_%d" % 0)
                outpath_this_seq = "%s/%s" % (outpath_result, "seq_%d" % cnt)
                subfoldername_this_seq = "seq_%d" % (cnt)
                if os.path.exists(tmp_outpath_this_seq):
                    try:
                        shutil.rmtree(tmp_outpath_this_seq)
                    except OSError:
                        pass

                maplist.append(
                    "%s\t%d\t%s\t%s" %
                    ("seq_%d" % cnt, len(rd.seq), rd.description, rd.seq))
                maplist_simple.append(
                    "%s\t%d\t%s" %
                    ("seq_%d" % cnt, len(rd.seq), rd.description))
                if not g_params['isForceRun']:
                    md5_key = hashlib.md5(
                        (rd.seq +
                         str(query_para)).encode('utf-8')).hexdigest()
                    subfoldername = md5_key[:2]
                    cachedir = "%s/%s/%s" % (path_cache, subfoldername,
                                             md5_key)
                    zipfile_cache = cachedir + ".zip"

                    if os.path.exists(cachedir) or os.path.exists(
                            zipfile_cache):
                        if os.path.exists(cachedir):
                            try:
                                shutil.copytree(cachedir, outpath_this_seq)
                            except Exception as e:
                                msg = "Failed to copytree  %s -> %s" % (
                                    cachedir, outpath_this_seq)
                                date_str = time.strftime(FORMAT_DATETIME)
                                myfunc.WriteFile(
                                    "[%s] %s with errmsg=%s\n" %
                                    (date_str, msg, str(e)), runjob_errfile,
                                    "a")
                        elif os.path.exists(zipfile_cache):
                            cmd = [
                                "unzip", zipfile_cache, "-d", outpath_result
                            ]
                            webcom.RunCmd(cmd, runjob_logfile, runjob_errfile)
                            shutil.move("%s/%s" % (outpath_result, md5_key),
                                        outpath_this_seq)

                        if os.path.exists(outpath_this_seq):
                            info_finish = webcom.GetInfoFinish_PRODRES(
                                outpath_this_seq,
                                cnt,
                                len(rd.seq),
                                rd.description,
                                source_result="cached",
                                runtime=0.0)
                            myfunc.WriteFile("\t".join(info_finish) + "\n",
                                             finished_seq_file,
                                             "a",
                                             isFlush=True)
                            isSkip = True

                if not isSkip:
                    # first try to delete the outfolder if exists
                    if os.path.exists(outpath_this_seq):
                        try:
                            shutil.rmtree(outpath_this_seq)
                        except OSError:
                            pass
                    origIndex = cnt
                    numTM = 0
                    toRunDict[origIndex] = [rd.seq, numTM, rd.description
                                            ]  #init value for numTM is 0

                cnt += 1
            recordList = hdl.readseq()
        hdl.close()
    myfunc.WriteFile("\n".join(maplist_simple) + "\n", mapfile)

    if not g_params['isOnlyGetCache']:
        torun_all_seqfile = "%s/%s" % (tmp_outpath_result, "query.torun.fa")
        dumplist = []
        for key in toRunDict:
            top = toRunDict[key][0]
            dumplist.append(">%s\n%s" % (str(key), top))
        myfunc.WriteFile("\n".join(dumplist) + "\n", torun_all_seqfile, "w")
        del dumplist

        sortedlist = sorted(list(toRunDict.items()),
                            key=lambda x: x[1][1],
                            reverse=True)
        #format of sortedlist [(origIndex: [seq, numTM, description]), ...]

        # submit sequences one by one to the workflow according to orders in
        # sortedlist

        for item in sortedlist:
            origIndex = item[0]
            seq = item[1][0]
            description = item[1][2]

            subfoldername_this_seq = "seq_%d" % (origIndex)
            outpath_this_seq = "%s/%s" % (outpath_result,
                                          subfoldername_this_seq)
            tmp_outpath_this_seq = "%s/%s" % (tmp_outpath_result, "seq_%d" %
                                              (0))
            if os.path.exists(tmp_outpath_this_seq):
                try:
                    shutil.rmtree(tmp_outpath_this_seq)
                except OSError:
                    pass

            seqfile_this_seq = "%s/%s" % (tmp_outpath_result, "query_%d.fa" %
                                          (origIndex))
            seqcontent = ">query_%d\n%s\n" % (origIndex, seq)
            myfunc.WriteFile(seqcontent, seqfile_this_seq, "w")

            if not os.path.exists(seqfile_this_seq):
                msg = "failed to generate seq index %d" % (origIndex)
                date_str = time.strftime(g_params['FORMAT_DATETIME'])
                myfunc.WriteFile("[%s] %s\n" % (date_str, msg), runjob_errfile,
                                 "a", True)
                continue

            cmd = [
                "python", runscript, "--input", seqfile_this_seq, "--output",
                tmp_outpath_this_seq, "--pfam-dir", path_pfamdatabase,
                "--pfamscan-script", path_pfamscanscript,
                "--fallback-db-fasta", blastdb
            ]

            if 'second_method' in query_para and query_para[
                    'second_method'] != "":
                cmd += ['--second-search', query_para['second_method']]

            if 'pfamscan_evalue' in query_para and query_para[
                    'pfamscan_evalue'] != "":
                cmd += ['--pfamscan_e-val', query_para['pfamscan_evalue']]
            elif 'pfamscan_bitscore' in query_para and query_para[
                    'pfamscan_bitscore'] != "":
                cmd += ['--pfamscan_bitscore', query_para['pfamscan_bitscore']]

            if 'pfamscan_clanoverlap' in query_para:
                if query_para['pfamscan_clanoverlap'] == False:
                    cmd += ['--pfamscan_clan-overlap', 'no']
                else:
                    cmd += ['--pfamscan_clan-overlap', 'yes']

            if 'jackhmmer_iteration' in query_para and query_para[
                    'jackhmmer_iteration'] != "":
                cmd += [
                    '--jackhmmer_max_iter', query_para['jackhmmer_iteration']
                ]

            if 'jackhmmer_threshold_type' in query_para and query_para[
                    'jackhmmer_threshold_type'] != "":
                cmd += [
                    '--jackhmmer-threshold-type',
                    query_para['jackhmmer_threshold_type']
                ]

            if 'jackhmmer_evalue' in query_para and query_para[
                    'jackhmmer_evalue'] != "":
                cmd += ['--jackhmmer_e-val', query_para['jackhmmer_evalue']]
            elif 'jackhmmer_bitscore' in query_para and query_para[
                    'jackhmmer_bitscore'] != "":
                cmd += [
                    '--jackhmmer_bit-score', query_para['jackhmmer_bitscore']
                ]

            if 'psiblast_iteration' in query_para and query_para[
                    'psiblast_iteration'] != "":
                cmd += ['--psiblast_iter', query_para['psiblast_iteration']]
            if 'psiblast_outfmt' in query_para and query_para[
                    'psiblast_outfmt'] != "":
                cmd += ['--psiblast_outfmt', query_para['psiblast_outfmt']]

            (t_success,
             runtime_in_sec) = webcom.RunCmd(cmd, runjob_logfile,
                                             runjob_errfile, True)

            aaseqfile = "%s/seq.fa" % (tmp_outpath_this_seq + os.sep +
                                       "query_0")
            if not os.path.exists(aaseqfile):
                seqcontent = ">%s\n%s\n" % (description, seq)
                myfunc.WriteFile(seqcontent, aaseqfile, "w")

            if os.path.exists(tmp_outpath_this_seq):
                cmd = [
                    "mv", "-f", tmp_outpath_this_seq + os.sep + "query_0",
                    outpath_this_seq
                ]
                isCmdSuccess = False
                (isCmdSuccess,
                 t_runtime) = webcom.RunCmd(cmd, runjob_logfile,
                                            runjob_errfile, True)

                if not 'isKeepTempFile' in query_para or query_para[
                        'isKeepTempFile'] == False:
                    try:
                        temp_result_folder = "%s/temp" % (outpath_this_seq)
                        shutil.rmtree(temp_result_folder)
                    except:
                        msg = "Failed to delete the folder %s" % (
                            temp_result_folder)
                        date_str = time.strftime(g_params['FORMAT_DATETIME'])
                        myfunc.WriteFile("[%s] %s\n" % (date_str, msg),
                                         runjob_errfile, "a", True)

                    flist = [
                        "%s/outputs/%s" % (outpath_this_seq, "Alignment.txt"),
                        "%s/outputs/%s" % (outpath_this_seq, "tableOut.txt"),
                        "%s/outputs/%s" % (outpath_this_seq, "fullOut.txt")
                    ]
                    for f in flist:
                        if os.path.exists(f):
                            try:
                                os.remove(f)
                            except:
                                msg = "Failed to delete the file %s" % (f)
                                date_str = time.strftime(
                                    g_params['FORMAT_DATETIME'])
                                myfunc.WriteFile("[%s] %s\n" % (date_str, msg),
                                                 runjob_errfile, "a", True)

                if isCmdSuccess:
                    timefile = "%s/time.txt" % (outpath_this_seq)
                    runtime = webcom.ReadRuntimeFromFile(timefile,
                                                         default_runtime=0.0)
                    info_finish = webcom.GetInfoFinish_PRODRES(
                        outpath_this_seq,
                        origIndex,
                        len(seq),
                        description,
                        source_result="newrun",
                        runtime=runtime)
                    myfunc.WriteFile("\t".join(info_finish) + "\n",
                                     finished_seq_file,
                                     "a",
                                     isFlush=True)
                    # now write the text output for this seq

                    info_this_seq = "%s\t%d\t%s\t%s" % (
                        "seq_%d" % origIndex, len(seq), description, seq)
                    resultfile_text_this_seq = "%s/%s" % (outpath_this_seq,
                                                          "query.result.txt")
                    #webcom.WriteSubconsTextResultFile(resultfile_text_this_seq,
                    #        outpath_result, [info_this_seq], runtime_in_sec, g_params['base_www_url'])
                    # create or update the md5 cache
                    # create cache only on the front-end
                    if webcom.IsFrontEndNode(g_params['base_www_url']):
                        md5_key = hashlib.md5(
                            (seq +
                             str(query_para)).encode('utf-8')).hexdigest()
                        subfoldername = md5_key[:2]
                        md5_subfolder = "%s/%s" % (path_cache, subfoldername)
                        cachedir = "%s/%s/%s" % (path_cache, subfoldername,
                                                 md5_key)

                        # copy the zipped folder to the cache path
                        origpath = os.getcwd()
                        os.chdir(outpath_result)
                        shutil.copytree("seq_%d" % (origIndex), md5_key)
                        cmd = ["zip", "-rq", "%s.zip" % (md5_key), md5_key]
                        webcom.RunCmd(cmd, runjob_logfile, runjob_logfile)
                        if not os.path.exists(md5_subfolder):
                            os.makedirs(md5_subfolder)
                        shutil.move("%s.zip" % (md5_key),
                                    "%s.zip" % (cachedir))
                        shutil.rmtree(
                            md5_key
                        )  # delete the temp folder named as md5 hash
                        os.chdir(origpath)

                        # Add the finished date to the database
                        date_str = time.strftime(FORMAT_DATETIME)
                        webcom.InsertFinishDateToDB(date_str, md5_key, seq,
                                                    finished_date_db)

    all_end_time = time.time()
    all_runtime_in_sec = all_end_time - all_begin_time

    if not g_params['isOnlyGetCache'] or len(toRunDict) == 0:
        # now write the text output to a single file
        statfile = "%s/%s" % (outpath_result, "stat.txt")
        #webcom.WriteSubconsTextResultFile(resultfile_text, outpath_result, maplist,
        #        all_runtime_in_sec, g_params['base_www_url'], statfile=statfile)

        # now making zip instead (for windows users)
        # note that zip rq will zip the real data for symbolic links
        os.chdir(outpath)
        #             cmd = ["tar", "-czf", tarball, resultpathname]
        cmd = ["zip", "-rq", zipfile, resultpathname]
        webcom.RunCmd(cmd, runjob_logfile, runjob_errfile)

        # write finish tag file
        if os.path.exists(finished_seq_file):
            webcom.WriteDateTimeTagFile(finishtagfile, runjob_logfile,
                                        runjob_errfile)

        isSuccess = False
        if (os.path.exists(finishtagfile)
                and os.path.exists(zipfile_fullpath)):
            isSuccess = True
        else:
            isSuccess = False
            webcom.WriteDateTimeTagFile(failedtagfile, runjob_logfile,
                                        runjob_errfile)

# send the result to email
# do not sendmail at the cloud VM
        if webcom.IsFrontEndNode(g_params['base_www_url']
                                 ) and myfunc.IsValidEmailAddress(email):
            if isSuccess:
                finish_status = "success"
            else:
                finish_status = "failed"
            webcom.SendEmail_on_finish(
                jobid,
                g_params['base_www_url'],
                finish_status,
                name_server="PRODRES",
                from_email="*****@*****.**",
                to_email=email,
                contact_email=contact_email,
                logfile=runjob_logfile,
                errfile=runjob_errfile)

    if os.path.exists(runjob_errfile) and os.path.getsize(runjob_errfile) > 1:
        return 1
    else:
        try:
            shutil.rmtree(tmpdir)
            msg = "rmtree(%s)" % (tmpdir)
            webcom.loginfo("rmtree(%s)" % (tmpdir), runjob_logfile)
        except Exception as e:
            msg = "Failed to rmtree(%s)" % (tmpdir)
            webcom.loginfo(
                "Failed to rmtree(%s) with error message: %s" %
                (tmpdir, str(e)), runjob_errfile)
        return 0