#!/usr/bin/perl

# Autor: Bastian Bolender
# Email: gruenistdiehoffnung@gmx.de
# Projekt: X-on
# Name des Scriptes: vergleich.pl
# Rolle des Scriptes im Gesamtprojekt:  Das Script dient dazu, die Ergebnisse von Jannik, 
#										Sebastian, Temis und den manuellen Annotierern
#										zu vergleichen und daraus Precision&Recall zu berechnen.

# Liest die Ergebnisse in Hashes ein,
# gleicht sie miteinander ab und gibt die Resultate aus.
# Errechnet Precision und Recall

# Eingabe-Agrumente: Jannik, Temis, MA, Sebastian

my $jan  = $ARGV[0];
my $te  = $ARGV[1];
my $ma  = $ARGV[2];
my $se = $ARGV[3];

%hashJa = (); # Daten von Jannik
%hashSe = (); # Daten von Sebastian
%hashTe = (); # Daten von Temis
%hashMa = (); # Daten von manuellen Annotierern
%hashJa_Te = (); # Daten von Jannik und Temis
%hashSe_Te = (); # Daten von Sebastian und Temis
%hashJa_Se_Te = (); # Daten von Jannik, Sebastian und Temis
%contr = (); # 

$MENGE = 10000; # Zahl der zu untersuchenden Abstracts

$placeHolder = "0";

print "Zahl der untersuchten Abstracts: $MENGE\n";

# TE Liste wird einsortiert
open IN2, $te;
$docc = 0; # ZŠhlt die bearbeiteten Zeilen
$docnr1 = 0; 
$docnr2 = 0; # docnrc1 und docnrc2 speichern die Nummern der aktuell Abstracts
$docnrc = 0; # ZŠhlt die gefundenen Dokumente

while ($line = <IN2>)
{
	$docc++;
	print STDERR "\rLese Zeile $docc von TE ein";
	
# Jedes Mal wenn die Abstract-Nummer wechselt wird der counter um 1 erhšht,
# wenn die gewŸnschte Zahl erreicht ist, wird die Schleife unterbrochen.
	$docnr1 = substr ($line, 0, 8);
	if($docnr1 != $docnr2)
	{
	$docnrc++;
# Der Hash %contr dient zu spaeteren Kontrolle, ob eine Abstract-Nummer zu den 10.000 untersuchten gehšrt
	$contr { $docnr2 } = $placeHolder;
	}
	goto LABEL2 if ($docnrc > $MENGE); # ist die gewŸnschte Anzahl erreicht, wird die Schleife unterbrochen
	$docnr2 = $docnr1;	
	
# Das Herkunfts-KŸrzel wird entfernt und die Daten werden in die entsprechenden Hashes geschrieben.
	$p1 = rindex $line, ",";
	$MH1 = substr ($line, 0, $p1);
	$hashTe { $MH1 } = $placeHolder;
	$hashJa_Te { $MH1 } = $placeHolder;
	$hashSe_Te { $MH1 } = $placeHolder;
	$hashJa_Se_Te { $MH1 } = $placeHolder;
}
LABEL2:
$temis_gesamt = $docc; # FŸr die Berechnung von Precision&Recall benštigte Zahlen werden gespeichert.
print "\n";
close IN2;

# JA Liste wird einsortiert
$docc = 0;
$docnr1 = 0;
$count = 0; # ZŠhlt die gefundenen Abstracts

open IN1, $jan;

# Die Input-Datei wird komplett durchsucht. Abstractnummern, die zu den untersuchten gehšren,
# werden in die Hashes geschrieben. 
# Die Datein werden immer komplett durchsucht, da nicht sicher ist ob sie sortiert sind. 
# Ein vorheriger Sortiervorgang wŸrde genau so viel Zeit kosten wie das Durchsuchen beim Verarbeiten.
while ($line = <IN1>)
{
	$docc++;
	print STDERR "\rDurchsuche Zeile $docc von JA";
	$docnr1 = substr ($line, 0, 8);
	$p1 = rindex ($line, ",");
	$MH1 = substr ($line, 0, $p1);
	if (defined ($contr{$docnr1}))
		{
		$count++;
		$hashJa { $MH1 } = $placeHolder;
		$hashJa_Te { $MH1 } = $placeHolder;
		$hashJa_Se_Te { $MH1 } = $placeHolder;
		}
}
print "\n";
print "$count Zeilen eingetragen\n";
close IN1;

# SE Liste wird einsortiert
$docc = 0;
$docnr1 = 0;
$count = 0;

open IN4, $se;

while ($line = <IN4>)
{
	$docc++;
	print STDERR "\rDurchsuche Zeile $docc von SE";
	$docnr1 = substr ($line, 0, 8);
	$p1 = rindex ($line, ",");
	$MH1 = substr ($line, 0, $p1);
	if (defined ($contr{$docnr1}))
		{
		$count++;
		$hashSe { $MH1 } = $placeHolder;
		$hashSe_Te { $MH1 } = $placeHolder;
		$hashJa_Se_Te { $MH1 } = $placeHolder;
		}
}
print "\n";
print "$count Zeilen eingetragen\n";
close IN4;


# MA Liste wird einsortiert
open IN3, $ma;
$docc = 0;
$docnr1 = 0;
$count = 0;

while ($line = <IN3>)
{
	$docc++;
    print STDERR "\rDurchsuche Zeile $docc von MA, gefundene Eintraege: $count";
	$docnr1 = substr ($line, 0, 8);
	$p1 = rindex ($line, ",");
	$MH1 = substr ($line, 0, $p1);
	if (defined ($contr{$docnr1}))
	{
	$count++;
	$hashMa { $MH1 } = $placeHolder;
	}
}
$ma_gesamt = $count;
print "\n";
print "$count Zeilen eingetragen\n";
print "\n";
close IN3;

# Beim Abgleich werden die einzelnen Hashes miteinander verglichen und 
# die Ergebnisse fŸr die Berechnung von Precision & Recall gespeichert.

# Abgleichen Temis
$docc = 0;
$writec = 0;
$ref1 = 0;

foreach $key (keys %hashTe)
{
$docc++;
    print STDERR "\rAbgleich von Zeile $docc von TE";
	
if (defined ($hashMa{$key}))
	{
	$ref1++;
	}
}
	$richtige_temis = $ref1;
	
# Die festgestellten Werte werden direkt ausgegeben. 
	print "\n";
	print "Temis findet $ref1 Treffer die auch MA finden\n";
print "\n";

# Abgleichen Jannik
$docc = 0;
$writec = 0;
$ref1 = 0;
$ref2 = 0;

foreach $key (keys %hashJa)
{
$docc++;
    print STDERR "\rAbgleich von Zeile $docc von JA";
	
if (defined ($hashMa{$key}))
	{
	unless (defined ($hashTe{$key}))
	{
	$ref1++;
	}
	$writec++;
	}

	unless (defined ($hashTe{$key}))
	{
	$ref2++;
	}
}
print "\n";
	print "Jannik findet $writec Treffer die auch MA finden\n";
	print "Jannik findet $ref1 Treffer, die MA auch finden aber Temis nicht\n";
	print "Jannik findet $ref2 Treffer die Temis findet\n";
print "\n";

# Abgleichen Sebastian
$docc = 0;
$writec = 0;
$ref1 = 0;
$ref2 = 0;

foreach $key (keys %hashSe)
{
$docc++;
    print STDERR "\rAbgleich von Zeile $docc von SE";
	
if (defined ($hashMa{$key}))
	{
	unless (defined ($hashTe{$key}))
	{
	$ref1++;
	}
	$writec++;
	}
	
	unless (defined ($hashTe{$key}))
	{
	$ref2++;
	}
}
print "\n";
	print "Sebastian findet $writec Treffer die auch MA finden\n";
	print "Sebastian findet $ref1 Treffer, die MA auch finden aber Temis nicht\n";
	print "Sebastian findet $ref2 Treffer die Temis findet\n";;
print "\n";

# Abgleichen Jannik&Temis
$docc = 0;
$ref1 = 0;

foreach $key (keys %hashJa_Te)
{
$docc++;
    print STDERR "\rAbgleich von Zeile $docc von JA&TE";
	
if (defined ($hashMa{$key}))
	{
	$ref1++;
	}
}
$jate_gesamt = $docc;
$richtige_JATE = $ref1;
print "\n";
	print "Jannik&Temis finden $ref1 Treffer die auch MA finden\n";
print "\n";

# Abgleichen Sebastian&Temis
$docc = 0;
$ref1 = 0;

foreach $key (keys %hashSe_Te)
{
$docc++;
    print STDERR "\rAbgleich von Zeile $docc von SE&TE";
	
if (defined ($hashMa{$key}))
	{
	$ref1++;
	}
}
$sete_gesamt = $docc;
$richtige_SETE = $ref1;
print "\n";
	print "Sebastian&Temis finden $ref1 Treffer die auch MA finden\n";
print "\n";


# Abgleichen Jannik, Sebastian&Temis
$docc = 0;
$ref1 = 0;

foreach $key (keys %hashJa_Se_Te)
{
$docc++;
    print STDERR "\rAbgleich von Zeile $docc von SE&TE";
	
if (defined ($hashMa{$key}))
	{
	$ref1++;
	}
}
$jasete_gesamt = $docc;
$richtige_JASETE = $ref1;
print "\n";
	print "Jannik, Sebastian&Temis finden $ref1 Treffer die auch MA finden\n";
print "\n";


# Abgleichen MA
$docc = 0;
$ref1 = 0;
$ref2 = 0;

foreach $key (keys %hashMa)
{
$docc++;
    print STDERR "\rAbgleich von Zeile $docc von MA";
	
unless (defined ($hashJa_Te{$key}))
	{
	$ref1++;
	}

unless (defined ($hashSe_Te{$key}))
	{
	$ref2++;
	}
}

print "\n";
	print "MA finden $ref1 Treffer die Jannik&Temis nicht finden\n";
	print "MA finden $ref2 Treffer die Sebastian&Temis nicht finden\n";
print "\n";


# Berechnung von Precision&Recall

# Temis
$pr_te = $richtige_temis / ($richtige_temis + ($temis_gesamt - $richtige_temis));
$re_te = $richtige_temis / ($richtige_temis + ($ma_gesamt - $richtige_temis));

# Jannik&Temis
$pr_jate = $richtige_JATE / ($richtige_JATE + ($jate_gesamt - $richtige_JATE));
$re_jate = $richtige_JATE / ($richtige_JATE + ($ma_gesamt - $richtige_JATE));

# Sebastian&Temis
$pr_sete = $richtige_SETE / ($richtige_SETE + ($sete_gesamt - $richtige_SETE));
$re_sete = $richtige_SETE / ($richtige_SETE + ($ma_gesamt - $richtige_SETE));

# Jannik, Sebastian&Temis
$pr_jasete = $richtige_JASETE / ($richtige_JASETE + ($jasete_gesamt - $richtige_JASETE));
$re_jasete = $richtige_JASETE / ($richtige_JASETE + ($ma_gesamt - $richtige_JASETE));

#$jasete_gesamt = $docc;
#$richtige_JASETE = $ref1;

print "Precision Temis: $pr_te\n";
print "Recall Temis: $re_te\n";
print "\n";

print "Precision Jannik&Temis: $pr_jate\n";
print "Recall Jannik&Temis: $re_jate\n";
print "\n";

print "Precision Sebastian&Temis: $pr_sete\n";
print "Recall Sebastian&Temis: $re_sete\n";
print "\n";

print "Precision Jannik, Sebastian&Temis: $pr_jasete\n";
print "Recall Jannik, Sebastian&Temis: $re_jasete\n";
print "\n";

__END__


=head1 Das Tool Vergleich 

Autor: Bastian Bolender
Email: gruenistdiehoffnung@gmx.de
Projekt: X-on
Name des Scriptes: vergleich.pl

Rolle des Scriptes im Gesamtprojekt:    
Das Script dient dazu, die Ergebnisse von Jannik, Sebastian, Temis und den manuellen Annotierern zu vergleichen und daraus Precision&Recall zu berechnen.

Liest die Ergebnisse in Hashes ein, gleicht sie miteinander ab und gibt die Resultate aus. Errechnet Precision und Recall

Die Argumente werden in dieser Reihenfolge eigegeben: Jannik, Temis, MA, Sebastian

Mit der Variable $MENGE kann die Anzal der untersuchten Abstracts eingestellt werden.

Die Daten werden in verschiedene Hashes einsortiert, um sie spŠter miteinander abzugleichen.

Beim Abgleich werden die einzelnen Hashes miteinander verglichen und 
die Ergebnisse fuer die Berechnung von Precision & Recall gespeichert.

Die Ergebnisse werden ausgegeben.

Danach werden Precision&Recall errechnet und ebenfalls ausgegeben.



















