#!/usr/bin/perl
#
# gbAlignRun [-workdir=work/align] [-paraHub=kk] [-verbose]
#
# Run the BLAT alignments with parasol.  
#
# Options:
#   -workdir=work/align - Must be the same as specified for gbAlignSetup.
#   -paraHub=kk - Run parasol on this host. Must be able to ssh
#    to the host without a key prompt.  Overrides configuration value for
#    cluster.paraHub.
#   -paraPriority=n - parasol priority to use for jobs
#   -verbose=n - print details.
#
# Note: rsh does not return the exit code of the remote process, thus
# ssh is used.
#
# $Id: gbAlignRun,v 1.11 2010/04/11 06:48:30 markd Exp $
#
use strict;
use warnings;
use File::Basename;
use FindBin;
use lib "$FindBin::Bin/../lib";
use gbCommon;
setupServerPath();

# Limit the number of jobs pushed by para shove on each pass to this
# amount.  This will cause para shove to exit sooner if the jobs are
# failing.  Don't set it too low, or it takes longer to run.
my $PARA_MAX_PUSH = 200000;

# Entry
setTaskName("gbAlignRun");

# parse into globals used in program
my $cwd = `pwd`;
chomp($cwd);
my $workDir = "work/align";
my $paraHub = undef;
my $paraPriority = undef;

while (($#ARGV >= 0) && ($ARGV[0] =~/^-.*/)) {
    my $opt = $ARGV[0];
    shift @ARGV;
    if ($opt =~ /^-workdir($|=)/) {
        $workDir = parseOptEq($opt);
    } elsif ($opt =~ /^-paraHub($|=)/) {
        $paraHub = parseOptEq($opt);
    } elsif ($opt =~ /^-paraPriority($|=)/) {
        $paraPriority = parseOptEq($opt);
    } elsif ($opt =~ /^-verbose($|=)/) {
        # don't use level
        $gbCommon::verbose = 1;
    } else {
        gbError("invalid option \"$opt\"");
    }
}
if ($#ARGV >= 0) {
    gbError("wrong # args: gbAlignRun [-workdir=work/align] [-paraHub=kk] [-verbose]");
}
if (!defined($paraHub)) {
    $paraHub = getConf("cluster.paraHub");
}

my $alignJobs = "$workDir/align.jobs";

if (! -e "$alignJobs") {
    gbError("parasol jobs file not found: $alignJobs");
}
my $doneFlag = "$workDir/align.done";
if (-e $doneFlag) {
    gbError("alignment appears to have completed, $doneFlag exists");
}

# make absolute path to directory
my $absWorkDir;
if ($workDir =~ /^\//) {
    $absWorkDir = $workDir;
} else {
    $absWorkDir = "$cwd/$workDir";
}
my $sshCmd = "";
if ($paraHub ne "localhost") {
    $sshCmd = "ssh -x $paraHub cd $absWorkDir\\;";
}

# cd to work dir, need for local runs, but alway done to simplify
chdir $workDir || dir("can't chdir to $workDir");

# make an err directory before parasol so that is group writable
makeDir("err");

# this runs to completion
my $paraCmd = "para make -maxPush=$PARA_MAX_PUSH";
if (defined($paraPriority)) {
    $paraCmd .= " -priority=$paraPriority";
}
$paraCmd .= " align.jobs";
runProg("$sshCmd $paraCmd </dev/null");

# Check results
my $paraCheck = callProg("$sshCmd para check </dev/null");
if ($paraCheck =~ /running:/) {
    gbError("alignment parasol jobs appear be running, should have completed in $workDir");
}
if (($paraCheck =~ /crashed:/) || ($paraCheck =~ /failed:/)) {
    gbError("alignment parasol jobs crashed in $workDir");
}

# Get time for logs
runProg("$sshCmd para time </dev/null");

open(DONE, ">", "align.done") || gbError("can't create $doneFlag");
close(DONE) || die("close failed");
