#!/usr/bin/perl -w
use strict;
use warnings;
my $srcdir = $ENV{srcdir} || '.';
my $num_threads = 0;

# Calculate root(mean(square(error))) of results WRT example result files.

# PSICOV
{
	open(TF, '<', "$srcdir/demo_1000.psicov.50") || die("failed to open '$srcdir/demo_1000.psicov.50': $!");
	my @tf = <TF>;
	close(TF);

	# Run it:
	my @cmd = ('./freecontact', '--parprof=psicov', '--density=0', '-f', "$srcdir/demo_1000.aln", '--threads', $num_threads, '--debug');
	open(FP, '-|', @cmd) || die("failed in command '@cmd': $!, ".($?>>8));
	my $ltc = 50; # lines to compare

	my $psicov_req_prec = 9e-05;
	my $i = 0;
	my $rmse = 0;
	while(($i++ < $ltc) && (my $line = <FP>))
	{
		chomp($line); chomp(@tf);
		# Compare it to $srcdir/demo_1000.psicov.50, mind precision:
		# * TF (psicov110 -i 62 -d 0 demo_1000.aln): demo_1000.psicov
		# 55 67 0 8 10.840280
		my @pv = split(/ /o, $tf[$i-1]);
		my @fv = split(/ /o, $line);
		if($pv[0] != $fv[0]){ die("v0 mismatch '$tf[$i-1]' '$line'"); }
		if($pv[1] != $fv[1]){ die("v1 mismatch '$tf[$i-1]' '$line'"); }
		$rmse += ($pv[4] - $fv[4])**2;
	}
	close(FP) || ( (($?&127)!=13) && die("failed in command '@cmd': $!, ".($?>>8)) ); # @cmd will fail with SIGPIPE because we do not read out all the lines
	close(TF);
	$rmse = ($rmse/$ltc)**0.5;
	if($rmse > $psicov_req_prec){ die("PSICOV precision error: $rmse > $psicov_req_prec"); } # lkajan: precision should be defined in terms of say stddev of scores
	else{ warn("PSICOV RMSE: $rmse\n"); }
}

# EVfold-mfDCA
{
	open(TF, '<', "$srcdir/PF00071_v25_999.evfold.50") || die("failed to open '$srcdir/PF00071_v25_999.evfold.50': $!");
	my @tf = <TF>;
	close(TF);

	# Run it:
	my @cmd = (qq($srcdir/a2m2aln --query '^RASH_HUMAN/(\\d+)' < '$srcdir/PF00071_v25_999.fa' | ./freecontact --parprof=evfold --threads $num_threads --debug));
	open(FP, '-|', @cmd) || die("failed in command '@cmd': $!, ".($?>>8));
	my $ltc = 50; # lines to compare

	my $dca_req_prec = 9e-5;
	my $i = 0;
	my $rmse = 0;
	while(($i++ < $ltc) && (my $line = <FP>))
	{
		chomp($line); chomp(@tf);
		# Compare it to $srcdir/demo_1000.psicov.50, mind precision:
		# * TF (calculate_evolutionary_constraints_cnscore('PF00071_v25_999.fa', 'RASH_HUMAN', '../src/PF00071_v25_999.evfold')): PF00071_v25_999.evfold
		# 5 K 6 L 0.332129 3.59798
		my @pv = split(/ /o, $tf[$i-1]);
		my @fv = split(/ /o, $line);
		if($pv[0] != $fv[0]){ die("v0 mismatch '$tf[$i-1]' '$line'"); }
		if($pv[1] ne $fv[1]){ die("v1 mismatch '$tf[$i-1]' '$line'"); }
		if($pv[2] != $fv[2]){ die("v2 mismatch '$tf[$i-1]' '$line'"); }
		if($pv[3] ne $fv[3]){ die("v3 mismatch '$tf[$i-1]' '$line'"); }
		$rmse += ($pv[5] - $fv[5])**2;
	}
	close(FP) || ( (($?>>8)!=141) && die("failed in command '@cmd': $!, ".($?>>8)) ); # @cmd will fail with 141 (SIGPIPE+128) because we do not read out all the lines
	close(TF);
	$rmse = ($rmse/$ltc)**0.5;
	if($rmse > $dca_req_prec){ die("EVfold-mfDCA precision error: $rmse > $dca_req_prec"); }
	else{ warn("EVfold-mfDCA RMSE: $rmse\n"); }
}

exit(0);
# vim:et:ts=4:ai:
