#!/usr/local/bin/perl
#
# $Id: noptrun,v 1.1 1993/08/31 20:43:13 johans Exp $
#
# noptrun [-v] [-n name] [-p time] [-i count] [-h target_hi] [-l target_low] 
#	     [-c iter] [-t] [-m file] configfile weightbase trainfile testfile
#
#

$Verbose = 0;

$Iteration = 100;
$ContinueFlag = 0;
$TestTrain = 0;
$HighTarget;
$LowTarget;
$ReportName;
$LabelFile;

$NoptestLog;

$ConfigFile;
$WeightBase;
$TrainFile;
$TestFile;

$SleepTime = 60 * 15;

$HostName = `hostname`;

$ChildPid;
$CurrentIter = 0;
$NotFoundCount = 0;

sub PrintUsage {
	print STDERR "usage: noptrun [-v] [-n name] [-i count] [-p time]" .
		     " [-h target_hi] [-l target_low] [-c iter] [-t]" .
		     " [-m file] configfile weightbase trainfile testfile\n";
}

sub InitLogs {

	$NoptestLog = $ReportName . ".summary";

	open( TMP, ">>$NoptestLog" ) || die "noptrun: $NoptestLog: $!\n";

	print TMP "   Iteration          Test Score       Train Score\n";
	print TMP "--------------------------------------------------\n\n";

	close( TMP );


	system( "echo \" \" >> $ReportName.log" );
	system( "echo \'            * * * * *  $ReportName  * * * * *\' >> $ReportName.log" );
	system( "date >> $ReportName.log" );
	system( "echo -n \"Lines in Train file:\" >> $ReportName.log" );
	system( "wc -l $TrainFile >> $ReportName.log" );
	system( "echo -n \"Lines in Test file:\" >> $ReportName.log" );
	system( "wc -l $TestFile >> $ReportName.log" );
	system( "echo \" \" >> $ReportName.log" );

}

sub LogResults {
	local( $iter, $test, $train ) = @_;

	open( NOPTEST_LOG, ">>$NoptestLog" ) || 
					die "noptrun: $NoptestLog: $!\n";

	print NOPTEST_LOG "\t$iter\t\t$test\t\t$train\n";

	close( NOPTEST_LOG );
}

sub AppendFile {
	local( $src, $dst ) = @_;

	open( SRC, $src ) || die "noptrun: $src: $!\n";
	open( DST, ">>$dst" ) || die "noptrun: $dst: $!\n";

	while( $_ = <SRC> ) {
		print DST $_;
	}

	close( SRC );
	close( DST );

}

sub OptTest {
	local( $weights, $vecs ) = @_;
	local( @tmp, $iter, $percent );
	local( $str );

	system( "noptest $weights $vecs /tmp/noptrun.$$" );

	if( -s "/tmp/noptrun.$$" ) {

		open( REPORT, "/tmp/noptrun.$$" ) || die "$!";

		while( $_ = <REPORT> ) {

			if( /^ #/ ) {
				
				chop;
				@tmp = split;

				$iter = $tmp[4];
				chop( $iter );

				$percent = $tmp[7];
			}

			last;
		}

		close( REPORT );

	} else {
		print STDERR "noptrun: noptest of $weights failed.\n";
	}

	system( "echo ----------------------------------- >> $ReportName.log" );
	system( "date >> $ReportName.log" );
	system( "echo \"Host: $HostName\"  >> $ReportName.log" );
	system( "echo \"Weight File: $weights\" >> $ReportName.log" );
	system( "echo \"Test File: $vecs\" >> $ReportName.log" );
	system( "echo \" \" >> $ReportName.log" );

	if( defined( $LabelFile ) ) {
		system( "label_confuse -l $LabelFile -f /tmp/noptrun.$$ >> $ReportName.log" );
	} else {
		system( "cat /tmp/noptrun.$$ >> $ReportName.log" );
	}

	system( "echo \" \" >> $ReportName.log" );

	unlink( "/tmp/noptrun.$$" );

	( $iter, $percent );
}

sub StartNopt {
	local( @noptcmd );

	push( @noptcmd, "nopt" );
	push( @noptcmd, "-t" );
	push( @noptcmd, "-i" );
	push( @noptcmd, $Iteration );

	if( defined( $LowTarget ) ) {
		push( @noptcmd, "-l" );
		push( @noptcmd, $LowTarget );
	}

	if( defined( $HighTarget ) ) {
		push( @noptcmd, "-h" );
		push( @noptcmd, $HighTarget );
	}

	if( $ContinueFlag == 1 ) {
		push( @noptcmd, "-c" );
		push( @noptcmd, $CurrentIter );
	}

	push( @noptcmd, $ConfigFile );
	push( @noptcmd, $TrainFile );

	push( @noptcmd, $WeightBase );

	if( $Verbose ) {
		print STDERR "starting nopt: @noptcmd\n";
	}

	if( $ChildPid = fork ) {

		;	# parent does nothing

	} elsif( $ChildPid == 0 ) {

		open( NOPT, ">>$ReportName.run" ) || 
					die "noptrun: $ReportName.run: $!\n";

		select( NOPT ); $| = 1;
		select( STDOUT ); $| = 1;

		open( STDOUT, ">&NOPT" );
		open( STDERR, ">&STDOUT" );

		exec( @noptcmd );
		print STDERR "noptrun: could not start nopt: $!\n";
		exit( 1 );

	} else {

		print STDERR "noptrun: could not exec nopt: $!\n";
		exit( 1 );

	}
}

#
# Main Loop starts
#

chop( $HostName );

while( @ARGV ) {

	if( $ARGV[0] !~ /^-/ ) {
		last;
	}

	$arg = shift( @ARGV );

	if( $arg eq "-i" ) {

		$Iteration = shift( @ARGV );

	} elsif( $arg eq "-n" ) {

		$ReportName = shift( @ARGV );

	} elsif( $arg eq "-v" ) {

		$Verbose = 1;

	} elsif( $arg eq "-h" ) {

		$HighTarget = shift( @ARGV );

	} elsif( $arg eq "-l" ) {

		$LowTarget = shift( @ARGV );

	} elsif( $arg eq "-c" ) {

		$CurrentIter = shift( @ARGV );
		$ContinueFlag = 1;

	} elsif( $arg eq "-p" ) {

		$SleepTime = shift( @ARGV );
		$SleepTime *= 60;

	} elsif( $arg eq "-t" ) {

		$TestTrain = 1;

	} elsif( $arg eq "-m" ) {

		$LabelFile = shift( @ARGV );

	} else {
		print STDERR "noptrun: bad arugment \'$arg\'\n";
		do PrintUsage();
		exit( 1 );
	}
}

if( $#ARGV != 3 ) {
	do PrintUsage();
	exit( 1 );
}

$ConfigFile = $ARGV[0];
$WeightBase = $ARGV[1];
$TrainFile = $ARGV[2];
$TestFile = $ARGV[3];

if( !defined( $ReportName ) ) {
	$ReportName = $WeightBase;
}

do StartNopt();
do InitLogs();

$CurrentIter += $Iteration;

while( 1 ) {


	$NextWeightFile = $WeightBase . "." . $CurrentIter;
	
	if( $Verbose ) {
		print STDERR "checking for file $NextWeightFile ... ";
	}

	if( -s $NextWeightFile ) {

		$NotFoundCount = 0;

		if( $Verbose ) {
			print STDERR "found, doing test.\n";
		}

		( $Iter, $TestScore ) = &OptTest( $NextWeightFile, $TestFile );

		if( $TestTrain ) {
			( $Iter, $TrainScore ) = &OptTest( $NextWeightFile, 
								$TrainFile );
		}

		do LogResults( $Iter, $TestScore, $TrainScore );

		$CurrentIter += $Iteration;

		next;

	} else {
	
		$NotFoundCount++;

		if( $Verbose ) {
			print STDERR "not found, sleeping.\n";
		}

	}

	#
	# Try and not run forever
	#
	if( $NotFoundCount >= 10 ) {

		print STDERR "noptrun: could not find $NextWeightFile in last 10 polling times ($SleepTime secs), quiting\n";
		exit;
	}

	sleep( $SleepTime );
}

