#!/usr/local/bin/perl -w

############################################# 
#  ROC v0.3
#
#  added -uiuc
# 
#############################################
#
# generates ROC curves from output of 
# SvmFu, SNoW, or UIUC scripts
#
# Mariano Alvira
# malvira@mit.edu
#
#############################################

use strict;

my($act0, $act1, $o, $tc, $label, @points,$tc_state,$i,@truepos,@falsepos,$totpos,$totneg);

sub usage {
    print "\nUsage: roc -snow|-svmfu|-uiuc filename\n";
    print "           prints to STOUT roc values as:\n";
    print "           fallout recall\n\n";
    print "           -snow :  input comes from `snow -test -o allboth`\n";
    print "           -svmfu:  input comes from `svmfutest -p`\n";
    print "           -uiuc :  input comes uiuc Roth scripts (*.res.roc)\n\n";
    exit 1;
}

sub read_snow {
    open(IN, "<$ARGV[1]");
    while (<IN>) {
	next unless /Label: (\d+)/;
	$tc=$1;
	$_=<IN>;
	next unless /\d+:\s+\d+\s+(\S+)\s+([^\s\*]+)/;
	$act0=$2;
	$_=<IN>;
	next unless /\d+:\s+\d+\s+(\S+)\s+([^\s\*]+)/;
	$act1=$2;
      	$o=$act1-$act0;
	push @points, [$o, $tc];
    }
    close(IN);
}

sub read_svmfu {
    open(IN, "<$ARGV[1]");
    while (<IN>) {
        next unless /\(TC: ([^\)]+)\) \(O:([^\)]+)/;
        $tc=$1; $o=$2 * 1;
        push @points, [$o, $tc];
    }
}

sub read_uiuc {
    open(IN, "<$ARGV[1]");
    while (<IN>) {
        next unless /([\-\.0-9]+)\s+([0-9]+)/;
        $label=$2; $o=$1 * 1;
	if($label == 500000) { $tc = 0 };
	if($label == 500001) { $tc = 1 };
        push @points, [$o, $tc];
    }
}

if(not defined $ARGV[0]) {usage;}

if($ARGV[0] eq '-snow') {read_snow;}
elsif($ARGV[0] eq '-svmfu') {read_svmfu;}
elsif($ARGV[0] eq '-uiuc') {read_uiuc;}
else {usage;}

@points = sort { $b->[0] <=> $a->[0] } @points;

$tc_state = $points[0][1];
$totpos = 0, $totneg = 0;
foreach $i (0 .. $#points) {
    if ($points[$i][1] == $tc_state) {
	if ($points[$i][1]==1) { $totpos++; }
	else { $totneg++; }
    }
    else {
	$tc_state = $points[$i][1];
	if ($points[$i][1]==1) { 
	    $totpos++; }
	else {
	    push @truepos, $totpos;
	    push @falsepos, $totneg;
	    $totneg++; }
    }
}

foreach $i (0 .. $#truepos) {
    printf("%05f %05f\n",$falsepos[$i]/$totneg, $truepos[$i]/$totpos);
}
