#!/Users/runner/bioconda/conda-bld/maker_1616698748543/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_place/bin/perl 

eval 'exec /Users/runner/bioconda/conda-bld/maker_1616698748543/_h_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_place/bin/perl  -S $0 ${1+"$@"}'
    if 0; # not running under some shell

use warnings;
use strict "vars";
use strict "refs";

use FindBin;
use lib "$FindBin::RealBin/../lib";
use lib "$FindBin::RealBin/../perl/lib";
use vars qw($RANK $LOG $CMD_ARGS $VERSION);

BEGIN{
   $VERSION = '3.01.03';

   $main::eva = 1; #tells scripts this is evaluator

   if (not ($ENV{CGL_SO_SOURCE})) {
      $ENV{CGL_SO_SOURCE} = "$FindBin::RealBin/../lib/CGL/so.obo";
   }
   if (not ($ENV{CGL_GO_SOURCE})) {
      $ENV{CGL_GO_SOURCE} = "$FindBin::RealBin/../lib/CGL/gene_ontology.obo"
   }
   
   $CMD_ARGS = join(' ', @ARGV);
   
   #what to do on ^C
   $SIG{'INT'} = sub {
      print STDERR "\n\nProgram aborted by user!!\n\n";
      exit (1);
   };    
   
   #supress warnings from storable module
   $SIG{'__WARN__'} = sub {
      warn $_[0] if ( $_[0] !~ /Not a CODE reference/ &&
		      $_[0] !~ /Can\'t store item CODE/
		    );
   };

   #output to log file of seq that caused rank to die
   $SIG{'__DIE__'} =
   sub {
      if (defined ($LOG) && defined $_[0]) {
	 my $die_count = $LOG->get_die_count();
	 $die_count++;
	 
	 $LOG->add_entry("DIED","RANK",$RANK);
	 $LOG->add_entry("DIED","COUNT",$die_count);
      }

      die "#----------------------\n",
          "FATAL: failed!!\n",
	  "#----------------------\n",
	  $_[0] . "\n";
   };
}

use Cwd;
use FileHandle;
use File::Path;
use Getopt::Long;
use File::Temp qw(tempfile tempdir);
use Bio::DB::Fasta;
use GI;
use Dumper::GFF::GFFV3;
use Iterator::Any;
use Iterator::Fasta;
use Iterator::GFF3;
use Fasta;
use FastaChunker;
use maker::auto_annotator;
use cluster;
use repeat_mask_seq;
use runlog;
use ds_utility;
use GFFDB;
use Error qw(:try);
use Error::Simple;
use Process::MpiChunk;
use Process::MpiTiers;

$| = 1;

my $usage = "
Usage:
     mpi_evaluator [options] <eval_opts> <eval_bopts> <eval_exe>


Options:

     -genome_gff <file>  Specify the maker gff file to evaluate.

     -model_gff  <file>  Specify the external gff file to evaluate.

     -genome     <file>  Specify the genome fasta file.  This if optional if the
                         fasta entries are also found in the gff file.

     -RM_off|R           Turns all repeat masking off.

     -retry   <integer>  Rerun failed contigs up to the specified count.

     -cpus|c  <integer>  Tells how many cpus to use for BLAST analysis.

     -force|f            Forces program to delete old files before running again.
                         This will require all blast analyses to be rerun.
     -again|a            Caculate all output files again even if no settings have
                         changed.

     -quiet|q            Silences most of the status messages.

     -CTL                Generate empty control files in the current directory.

     -help|?             Prints this usage statement.


";

#-------------------------------------------------------------------------------
#------------------------------------ MAIN -------------------------------------
#-------------------------------------------------------------------------------

#---global variables
my %OPT;
my $rank = 0;
my $size = 1;
$RANK = $rank;

#---Process options on the command line 
try{
    GetOptions("RM_off|R" => \$OPT{R},
	       "force|f" => \$OPT{force},
	       "genome|g=s" => \$OPT{genome},
	       "cpus|c=i" => \$OPT{cpus},
	       "predictor=s" =>\$OPT{predictor},
	       "retry=i" =>\$OPT{retry},
	       "evaluate" =>\$OPT{evaluate},
	       "again|a" =>\$OPT{again},
	       "quiet" =>\$main::quiet,
	       "CTL" => sub {GI::generate_control_files(); exit(0);},
	       "version" => sub{print "$VERSION\n"; exit(0)},
	       "help|?" => sub {print $usage; exit(0)}
	       );
}
catch Error::Simple with{
    my $E = shift;
    
    print STDERR $E->{-text};
    die "\n\nFailed parsing command line options!!\n\n";
};

#varibles that are persistent outside of try
my %CTL_OPT;
my $iterator;
my $DS_CTL;
my $GFF_DB;
my $build;
my @failed;

try{
    #get arguments off the command line
    my @ctlfiles = @ARGV;
    
    if (not @ctlfiles) {
	if (-e "eval_opts.ctl" &&
	    -e "eval_bopts.ctl" &&
	    -e "eval_exe.ctl"
	    ) {
	    
	    @ctlfiles = ("eval_opts.ctl",
			 "eval_bopts.ctl",
			 "eval_exe.ctl"
			 );
	}
	else {
	    print STDERR  "ERROR: Control files not found\n";
	    print $usage;
	    exit(0);
	}
    }
    
    #--Control file processing
    
    #set up control options from control files
    %CTL_OPT = GI::load_control_files(\@ctlfiles, \%OPT, $size);
    
    #--open datastructure controller
    $DS_CTL = ds_utility->new(\%CTL_OPT);
    
    #--set up gff database
    $GFF_DB = new GFFDB(\%CTL_OPT);
    $build = $GFF_DB->next_build;
    
    #---load genome multifasta/GFF3 file
    $iterator = new Iterator::Any( -fasta => $CTL_OPT{'genome'},
				   -gff => $CTL_OPT{'genome_gff'},
				   );
}
catch Error::Simple with{
    my $E = shift;
    print STDERR $E->{-text};
    print STDERR "\n\nProgram failed while examining startup data\n",
    "(control files and input fasta files)!!\n\n";
    my $code = 2;
    $code = $E->{-value} if (defined($E->{-value}));
    
    exit($code);
};

my $tier;
while (my $fasta = $iterator->nextFasta() || shift @failed){
    $tier = Process::MpiTiers->new({fasta =>$fasta,
				    CTL_OPT => \%CTL_OPT,
				    DS_CTL  => $DS_CTL,
				    GFF_DB  => $GFF_DB,
				    build   => $build},
				   '0'
				   );

    next if($tier->terminated);
    $tier->run while(! $tier->terminated && ! $tier->failed);
    $DS_CTL->add_entry($tier->DS);
    push(@failed, $tier->fasta) if ($tier->failed);
}

print STDERR "\n\nProgram is now finished!!!\n\n";

#-----------------------------------------------------------------------------
#----------------------------------- SUBS ------------------------------------
#-----------------------------------------------------------------------------
