Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- SCTK/src/acomp/acomp.pl +328 -0
- SCTK/src/acomp/makefile +27 -0
- SCTK/src/acomp/makefile.in +27 -0
- SCTK/src/align2html/Segment.pm +325 -0
- SCTK/src/align2html/SegmentGroup.pm +407 -0
- SCTK/src/align2html/Token.pm +166 -0
- SCTK/src/align2html/align2html-main.pl +1436 -0
- SCTK/src/align2html/align2html.pl +0 -0
- SCTK/src/align2html/buildInstallVersion.pl +69 -0
- SCTK/src/align2html/buildPack.pl +29 -0
- SCTK/src/align2html/makefile +25 -0
- SCTK/src/align2html/makefile.in +25 -0
- SCTK/src/align2html/packImageTarFile +229 -0
- SCTK/src/chfilt/chfilt.pl +1042 -0
- SCTK/src/chfilt/makefile +40 -0
- SCTK/src/chfilt/makefile.in +40 -0
- SCTK/src/ctmValidator/makefile +19 -0
- SCTK/src/hamzaNorm/hamzaNorm.pl +95 -0
- SCTK/src/hamzaNorm/makefile +33 -0
- SCTK/src/hamzaNorm/makefile.in +33 -0
- SCTK/src/rttmValidator/makefile +19 -0
- SCTK/src/rttmValidator/makefile.in +19 -0
- SCTK/src/rttmValidator/rttmValidator.pl +917 -0
- SCTK/src/sclite/addarc1.o +0 -0
- SCTK/src/sclite/alex.h +23 -0
- SCTK/src/sclite/align.c +1443 -0
- SCTK/src/sclite/align.o +0 -0
- SCTK/src/sclite/anovar.c +485 -0
- SCTK/src/sclite/arcseq1.c +13 -0
- SCTK/src/sclite/arcseq1.o +0 -0
- SCTK/src/sclite/config.in +151 -0
- SCTK/src/sclite/ctm2ctm.c +518 -0
- SCTK/src/sclite/killarc1.o +0 -0
- SCTK/src/sclite/llist.c +159 -0
- SCTK/src/sclite/llist.h +32 -0
- SCTK/src/sclite/makefile.in +246 -0
- SCTK/src/sclite/marc1.c +25 -0
- SCTK/src/sclite/mcnemar.c +18 -0
- SCTK/src/sclite/mfa.c +299 -0
- SCTK/src/sclite/mnode1.c +55 -0
- SCTK/src/sclite/mtchprs.c +833 -0
- SCTK/src/sclite/net_adt.o +0 -0
- SCTK/src/sclite/order.c +277 -0
- SCTK/src/sclite/order.o +0 -0
- SCTK/src/sclite/pad.h +7 -0
- SCTK/src/sclite/sclite.c +764 -0
- SCTK/src/sclite/signtest.c +304 -0
- SCTK/src/sclite/slm_intf.c +195 -0
- SCTK/src/sclite/statdist.o +0 -0
- SCTK/src/sclite/stm.h +31 -0
SCTK/src/acomp/acomp.pl
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/perl -w
|
| 2 |
+
|
| 3 |
+
my $Version="1.1";
|
| 4 |
+
|
| 5 |
+
#####
|
| 6 |
+
# Version 1.0 Released September 9, 1997
|
| 7 |
+
# - Initial Release
|
| 8 |
+
# Version 1.1 Released October 24, 1997
|
| 9 |
+
# - added the -f flag to interpret fragments
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
my $Usage="Usage: acompl.pl [ -t -s -f ] [ -i fmt ] -m min -l lex Infile|- OutFile|-\n".
|
| 13 |
+
"Version: $Version\n".
|
| 14 |
+
"Desc: The 'acomp' program expands compound words in German orthography into\n".
|
| 15 |
+
" the constituent parts of those compound words. The program uses the\n".
|
| 16 |
+
" LDC German Lexicon as a basis for the expansions. Input is read from\n".
|
| 17 |
+
" InFile or STDIN if infile is '-' and output is written to Outfile or\n".
|
| 18 |
+
" STDOUT if OutFile is '-'\n".
|
| 19 |
+
"Options:\n".
|
| 20 |
+
" -m min Set the minimum length on a compound costituent part to 'min'.\n".
|
| 21 |
+
" Default is 2.\n".
|
| 22 |
+
" -l lex File name of the LDC German Dictionary\n".
|
| 23 |
+
" -t Disable the processing of triplet consonants\n".
|
| 24 |
+
" -s Disable the processing of -s and -en insertions\n".
|
| 25 |
+
" -f Divide word fragments as best as you can\n".
|
| 26 |
+
" -i fmt Set the input file formant to 'fmt'. The possible choices are:\n".
|
| 27 |
+
" txt -> plain text, the default\n".
|
| 28 |
+
" ctm -> CTM format, ignores all but the 5th column, and if\n".
|
| 29 |
+
" a division occurs and a confidence score is present,\n".
|
| 30 |
+
" the confidence score is copied to all parts.\n".
|
| 31 |
+
" stm -> STM format, change only the text field of the stm record\n".
|
| 32 |
+
"\n";
|
| 33 |
+
$Lex = "";
|
| 34 |
+
$MaxLen = 0;
|
| 35 |
+
%LexHash = ();
|
| 36 |
+
%CompHash = ();
|
| 37 |
+
$MinCompLen = 2;
|
| 38 |
+
$DoTriplet = 1;
|
| 39 |
+
$DoInserts = 1;
|
| 40 |
+
$InFmt = "txt";
|
| 41 |
+
$InFile = "";
|
| 42 |
+
$OutFile = "";
|
| 43 |
+
$Frag = 0;
|
| 44 |
+
|
| 45 |
+
$| = 1; # This will cause stdout to be flushed whenever we print to it.
|
| 46 |
+
|
| 47 |
+
use Getopt::Long;
|
| 48 |
+
my $ret = GetOptions ("l=s",
|
| 49 |
+
"m=s",
|
| 50 |
+
"t",
|
| 51 |
+
"s",
|
| 52 |
+
"i:s",
|
| 53 |
+
"f");
|
| 54 |
+
die "\n$Usage\nError: Failed to parse arguments" if (! $ret);
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
if (defined($opt_l)) { $Lex = $opt_l; } else { die("$Usage\n\nError: Lexicon required via -l.\n"); }
|
| 58 |
+
if (defined($opt_m)) { $MinCompLen = $opt_m; }
|
| 59 |
+
if (defined($opt_t)) { $DoTriplet = 0; $opt_t = 0;}
|
| 60 |
+
if (defined($opt_s)) { $DoInserts = 0; $opt_s = 0;}
|
| 61 |
+
if (defined($opt_f)) { $Frag = 1; $opt_f = 0;}
|
| 62 |
+
if (defined($opt_i)) {
|
| 63 |
+
die("$Usage\n\nError: Undefined input format '$opt_i'")
|
| 64 |
+
if ($opt_i !~ /^(txt|ctm|stm)$/);
|
| 65 |
+
$InFmt = $opt_i;
|
| 66 |
+
}
|
| 67 |
+
#### The main functions arguments:
|
| 68 |
+
if ($#ARGV > 1) { print "\n$Usage\nToo many arguments\n\n"; exit 1; }
|
| 69 |
+
if ($#ARGV == 0) { print "\n$Usage\nOutput Not Specified\n\n"; exit 1; }
|
| 70 |
+
if ($#ARGV == -1) { print "\n$Usage\nInput and Output Not Specified\n\n";
|
| 71 |
+
exit 1; }
|
| 72 |
+
|
| 73 |
+
$InFile=$ARGV[0];
|
| 74 |
+
$OutFile=$ARGV[1];
|
| 75 |
+
die("$Usage\nError: Input file $InFile does not exist\n")
|
| 76 |
+
if ($InFile ne "-" && ! -r $InFile);
|
| 77 |
+
|
| 78 |
+
########################## MAIN #####################D
|
| 79 |
+
|
| 80 |
+
&LoadLex();
|
| 81 |
+
|
| 82 |
+
open(IN,"$InFile") || die("Error: Unable to open input file '$InFile'");
|
| 83 |
+
open(OUT,">$OutFile") || die("Error: Unable to open output file '$OutFile'");
|
| 84 |
+
|
| 85 |
+
while (<IN>){
|
| 86 |
+
chop;
|
| 87 |
+
if ($_ =~ /^;;/){
|
| 88 |
+
print OUT "$_\n";
|
| 89 |
+
} elsif ($InFmt eq "txt"){
|
| 90 |
+
print OUT &String_LU($_)."\n";
|
| 91 |
+
} elsif ($InFmt eq "ctm"){
|
| 92 |
+
s/^\s+//;
|
| 93 |
+
local(@ctm);
|
| 94 |
+
local(@new_words);
|
| 95 |
+
local($i);
|
| 96 |
+
local($newt);
|
| 97 |
+
local($conf);
|
| 98 |
+
|
| 99 |
+
@ctm = split(/\s+/,$_);
|
| 100 |
+
if ($#ctm <= 4) { $conf = "" ; } else { $conf = $ctm[5]; }
|
| 101 |
+
|
| 102 |
+
$newt = &String_LU($ctm[4]);
|
| 103 |
+
@new_words = split(/\s+/,$newt);
|
| 104 |
+
for ($i=0; $i<=$#new_words; $i++){
|
| 105 |
+
printf OUT ("%s %s %.2f %.2f %s %s\n",$ctm[0],$ctm[1],
|
| 106 |
+
$ctm[2] + ($i * ($ctm[3] / ($#new_words+1))),
|
| 107 |
+
$ctm[3] / ($#new_words + 1), $new_words[$i], $conf);
|
| 108 |
+
}
|
| 109 |
+
} elsif ($InFmt eq "stm"){
|
| 110 |
+
s/^\s+//;
|
| 111 |
+
local(@sl) = split(/\s+/,$_,7);
|
| 112 |
+
local($txt);
|
| 113 |
+
die "Error: Not enough fields in stm line '$_'\n" if ($#sl < 4);
|
| 114 |
+
|
| 115 |
+
if ($#sl == 4){
|
| 116 |
+
print OUT "$sl[0] $sl[1] $sl[2] $sl[3] $sl[4]\n";
|
| 117 |
+
} else {
|
| 118 |
+
print OUT "$sl[0] $sl[1] $sl[2] $sl[3] $sl[4]";
|
| 119 |
+
if ($sl[5] =~ /^<.*>$/){
|
| 120 |
+
print OUT " $sl[5]";
|
| 121 |
+
$txt = "";
|
| 122 |
+
if ($#sl == 6){ $txt = $sl[6]; }
|
| 123 |
+
} else {
|
| 124 |
+
$txt = $sl[5];
|
| 125 |
+
if ($#sl == 6){ $txt .= " ".$sl[6]; }
|
| 126 |
+
}
|
| 127 |
+
if ($txt ne ""){
|
| 128 |
+
print OUT " ".&String_LU($txt);
|
| 129 |
+
}
|
| 130 |
+
print OUT "\n";
|
| 131 |
+
}
|
| 132 |
+
}
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
close (IN); close(OUT);
|
| 136 |
+
|
| 137 |
+
################# END OF MAIN #########################
|
| 138 |
+
###########################################################
|
| 139 |
+
|
| 140 |
+
sub String_LU{
|
| 141 |
+
local($s) = @_;
|
| 142 |
+
local($new) = "";
|
| 143 |
+
local($ne);
|
| 144 |
+
$s =~ tr/a-z/A-Z/;
|
| 145 |
+
$s =~ tr/\340-\377/\300-\337/;
|
| 146 |
+
foreach $word(split(/\s+/,$s)){
|
| 147 |
+
if ($word =~ /^\(.*\)$/){
|
| 148 |
+
$word =~ s/^\((.*)\)$/$1/;
|
| 149 |
+
local($lookup) = &Comp_LU($word);
|
| 150 |
+
if ($word !~ /-$/ || (! $Frag)){
|
| 151 |
+
foreach $ne(split(/\s+/,$lookup)){
|
| 152 |
+
$new .= "(".$ne.") ";
|
| 153 |
+
}
|
| 154 |
+
} else {
|
| 155 |
+
$lookup =~ s/(\S+-)$/aq($1)/;
|
| 156 |
+
$new .= "$lookup ";
|
| 157 |
+
}
|
| 158 |
+
} else {
|
| 159 |
+
$new .= &Comp_LU($word)." ";
|
| 160 |
+
}
|
| 161 |
+
}
|
| 162 |
+
$new =~ s/ $//;
|
| 163 |
+
$new;
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
sub Comp_LU{
|
| 167 |
+
local($text) = @_;
|
| 168 |
+
local(@Comps) = ();
|
| 169 |
+
local($comp);
|
| 170 |
+
local($db) = 0;
|
| 171 |
+
|
| 172 |
+
if ($CompHash{$text} !~ /^$/){
|
| 173 |
+
print "hashed $text = $CompHash{$text}\n" if ($db);
|
| 174 |
+
$CompHash{$text};
|
| 175 |
+
} else {
|
| 176 |
+
if ($Frag && $text =~ /-$/) {
|
| 177 |
+
print "Fragment Lookup '$text'\n" if ($db);
|
| 178 |
+
|
| 179 |
+
local($len) = length($text);
|
| 180 |
+
local($htext) = "";
|
| 181 |
+
local($nocomp) = 1;
|
| 182 |
+
local($i, $j);
|
| 183 |
+
for ($i=$len-2; $i>=$MinCompLen && $nocomp; $i--){
|
| 184 |
+
$htext = substr($text,0,$i);
|
| 185 |
+
&is_Compound("",$htext,"",*Comps);
|
| 186 |
+
if ($#Comps != -1){
|
| 187 |
+
print "Fragment match @Comps\n" if ($db);
|
| 188 |
+
foreach ($j=0; $j <= $#Comps; $j++){
|
| 189 |
+
$Comps[$j] .= " ".substr($text,$i);
|
| 190 |
+
}
|
| 191 |
+
$nocomp = 0;
|
| 192 |
+
}
|
| 193 |
+
}
|
| 194 |
+
} else {
|
| 195 |
+
print "compute $text " if ($db);
|
| 196 |
+
&is_Compound("",$text,"",*Comps);
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
if ($#Comps == -1) {
|
| 200 |
+
$comp = $text;
|
| 201 |
+
} elsif ($#Comps > 0) {
|
| 202 |
+
$comp = "{";
|
| 203 |
+
foreach $c (@Comps){
|
| 204 |
+
$comp .= " $c /";
|
| 205 |
+
}
|
| 206 |
+
$comp =~ s:/$:}:;
|
| 207 |
+
} else {
|
| 208 |
+
$comp = $Comps[0];
|
| 209 |
+
}
|
| 210 |
+
$CompHash{$text} = $comp;
|
| 211 |
+
print "compute $text = $comp\n" if ($db);
|
| 212 |
+
$comp;
|
| 213 |
+
}
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
sub is_Compound{
|
| 217 |
+
local($hist,$val,$ind,*comps) = @_;
|
| 218 |
+
local($sval);
|
| 219 |
+
local($resid);
|
| 220 |
+
local($vallen) = length($val);
|
| 221 |
+
local($srchlen) = $MaxLen;
|
| 222 |
+
local($db) = 0;
|
| 223 |
+
local($stop_recur) = 0;
|
| 224 |
+
local($i);
|
| 225 |
+
|
| 226 |
+
$srchlen = $vallen if ($vallen < $MaxLen);
|
| 227 |
+
|
| 228 |
+
printf $ind."is_Compound hist: '$hist' val: '$val' slen: $srchlen\n" if ($db);
|
| 229 |
+
if ($LexHash{$val} eq "1"){
|
| 230 |
+
### The word is already in the hashed list, return it.
|
| 231 |
+
local($co);
|
| 232 |
+
($co = "$hist $val") =~ s/^ //;
|
| 233 |
+
print "$ind******* SUCCESS Search value pre-defined '$co'\n" if ($db);
|
| 234 |
+
push(@comps,$co);
|
| 235 |
+
1;
|
| 236 |
+
} else {
|
| 237 |
+
### loop through all of the characters in a
|
| 238 |
+
for ($i=$srchlen; $i>=$MinCompLen && ! $stop_recur; $i--){
|
| 239 |
+
$sval = substr($val,0,$i);
|
| 240 |
+
print $ind." $sval\n" if ($db);
|
| 241 |
+
if ($LexHash{$sval} eq "1"){
|
| 242 |
+
$resid = substr($val,$i);
|
| 243 |
+
print $ind." Possible subword '$sval' residual '$resid'\n" if ($db);
|
| 244 |
+
if (length($resid) >= $MinCompLen){
|
| 245 |
+
if (&is_Compound($hist." $sval",$resid, $ind." |",*comps) == 1){
|
| 246 |
+
$stop_recur = 1;
|
| 247 |
+
print "$ind**** Curtailing search for normal lookup\n" if ($db);
|
| 248 |
+
} else {
|
| 249 |
+
print "$ind**** Failed to Curtail search\n" if ($db);
|
| 250 |
+
}
|
| 251 |
+
} else {
|
| 252 |
+
print "$ind**** Residual length < MinCompLen $MinCompLen\n" if ($db);
|
| 253 |
+
}
|
| 254 |
+
#### handle the geminate constant conditional
|
| 255 |
+
if (! $stop_recur && $DoTriplet && $sval =~ /([bcdfghjklmnpqrstvwxyz])\1$/){
|
| 256 |
+
$resid = substr($val,$i-1);
|
| 257 |
+
print $ind." Possible geminate consonate subword residual $resid\n" if ($db);
|
| 258 |
+
if (length($resid) >= $MinCompLen){
|
| 259 |
+
if (&is_Compound($hist." $sval",$resid, $ind." |",*comps) == 1){
|
| 260 |
+
$stop_recur = 1;
|
| 261 |
+
print "$ind**** Curtailing search for triplet consonants\n" if ($db);
|
| 262 |
+
} else {
|
| 263 |
+
print "$ind**** Failed to Curtail search\n" if ($db);
|
| 264 |
+
}
|
| 265 |
+
}
|
| 266 |
+
}
|
| 267 |
+
#### handle the insertion of syllables
|
| 268 |
+
if (! $stop_recur && $DoInserts && ( $resid =~ /^([sS]|[eE][nN])/ ) ){
|
| 269 |
+
local($gen);
|
| 270 |
+
if ($resid =~ /^[sS]/){ $resid = substr($val,$i+1); $gen = "s" }
|
| 271 |
+
if ($resid =~ /^[eE][nN]/){ $resid = substr($val,$i+2); $gen = "en" }
|
| 272 |
+
print $ind." Possible additional '$gen' on residual '$gen'$resid\n" if ($db);
|
| 273 |
+
if (length($resid) >= $MinCompLen){
|
| 274 |
+
if (&is_Compound($hist." $sval",$resid, $ind." |",*comps) == 1){
|
| 275 |
+
$stop_recur = 1;
|
| 276 |
+
print "$ind**** Curtailing search for insertion of syllables\n" if ($db);
|
| 277 |
+
} else {
|
| 278 |
+
print "$ind**** Failed to Curtail search\n" if ($db);
|
| 279 |
+
}
|
| 280 |
+
}
|
| 281 |
+
}
|
| 282 |
+
}
|
| 283 |
+
}
|
| 284 |
+
$stop_recur;
|
| 285 |
+
}
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
sub LoadLex{
|
| 289 |
+
local($len);
|
| 290 |
+
local($db) = 0;
|
| 291 |
+
open(LEX,$Lex) || die("Unable to open Lexicon '$Lex'");
|
| 292 |
+
|
| 293 |
+
print "Reading Lexicon: '$Lex'\n Each . is 10000 entries: " if ($db);
|
| 294 |
+
while (<LEX>){
|
| 295 |
+
chop;
|
| 296 |
+
($word) = split;
|
| 297 |
+
$word =~ tr/a-z/A-Z/;
|
| 298 |
+
$word =~ tr/\340-\377/\300-\337/;
|
| 299 |
+
|
| 300 |
+
if ($word =~ /[-_]/){
|
| 301 |
+
($sep = $word) =~ s/[-_]+/ /g;
|
| 302 |
+
($cmp = $word) =~ s/_//g;
|
| 303 |
+
foreach $sw(split(/\s+/,$sep)){
|
| 304 |
+
$LexHash{$sw} = "1";
|
| 305 |
+
$len = length($sw);
|
| 306 |
+
$MaxLen = $len if ($MaxLen < $len);
|
| 307 |
+
}
|
| 308 |
+
$CompHash{$cmp} = $sep;
|
| 309 |
+
if ($cmp =~ /-/){
|
| 310 |
+
$cmp =~ s/-//g;
|
| 311 |
+
$CompHash{$cmp} = $sep;
|
| 312 |
+
}
|
| 313 |
+
} else {
|
| 314 |
+
$LexHash{$word} = "1";
|
| 315 |
+
$CompHash{$word} = $word;
|
| 316 |
+
}
|
| 317 |
+
if (($. + 1) % 10000 == 0){
|
| 318 |
+
print "." if ($db);
|
| 319 |
+
}
|
| 320 |
+
}
|
| 321 |
+
print "\n $. entries loaded, Largest word is $MaxLen\n" if ($db);
|
| 322 |
+
|
| 323 |
+
close(LEX);
|
| 324 |
+
|
| 325 |
+
# print "LexHash:\n"; foreach $key(sort(keys %LexHash)) { print " $key -> $LexHash{$key}\n"; }
|
| 326 |
+
# print "CompHash:\n"; foreach $key(sort(keys %CompHash)) { print " $key -> $CompHash{$key}\n"; }
|
| 327 |
+
}
|
| 328 |
+
|
SCTK/src/acomp/makefile
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# **********************************************************
|
| 2 |
+
# Makefile for rfilter1 Directory
|
| 3 |
+
# **********************************************************
|
| 4 |
+
SHELL = /bin/sh
|
| 5 |
+
PREFIX=/home/userube/mozilla/zz__temp_5_rover/SCTK
|
| 6 |
+
bindir = $(PREFIX)/bin
|
| 7 |
+
T=../test_suite
|
| 8 |
+
PERL=/slp/sware/Linux/bin/perl
|
| 9 |
+
|
| 10 |
+
all: acomp.pl
|
| 11 |
+
|
| 12 |
+
acomp.pl:
|
| 13 |
+
chmod +x acomp.pl
|
| 14 |
+
|
| 15 |
+
setTests:
|
| 16 |
+
|
| 17 |
+
check: all
|
| 18 |
+
@echo "Testing acomp.pl"
|
| 19 |
+
@echo " No tests defined for acomp.pl"
|
| 20 |
+
|
| 21 |
+
install: all
|
| 22 |
+
cp acomp.pl $(DESTDIR)$(bindir)
|
| 23 |
+
|
| 24 |
+
clean:
|
| 25 |
+
|
| 26 |
+
distclean: clean
|
| 27 |
+
$(RM) -r *~ makefile
|
SCTK/src/acomp/makefile.in
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# **********************************************************
|
| 2 |
+
# Makefile for rfilter1 Directory
|
| 3 |
+
# **********************************************************
|
| 4 |
+
SHELL = /bin/sh
|
| 5 |
+
PREFIX=
|
| 6 |
+
bindir = $(PREFIX)/bin
|
| 7 |
+
T=../test_suite
|
| 8 |
+
PERL=/slp/sware/Linux/bin/perl
|
| 9 |
+
|
| 10 |
+
all: acomp.pl
|
| 11 |
+
|
| 12 |
+
acomp.pl:
|
| 13 |
+
chmod +x acomp.pl
|
| 14 |
+
|
| 15 |
+
setTests:
|
| 16 |
+
|
| 17 |
+
check: all
|
| 18 |
+
@echo "Testing acomp.pl"
|
| 19 |
+
@echo " No tests defined for acomp.pl"
|
| 20 |
+
|
| 21 |
+
install: all
|
| 22 |
+
cp acomp.pl $(DESTDIR)$(bindir)
|
| 23 |
+
|
| 24 |
+
clean:
|
| 25 |
+
|
| 26 |
+
distclean: clean
|
| 27 |
+
$(RM) -r *~ makefile
|
SCTK/src/align2html/Segment.pm
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ALIGN2HTML
|
| 2 |
+
# Author: Jerome Ajot
|
| 3 |
+
#
|
| 4 |
+
# This software was developed at the National Institute of Standards and Technology by
|
| 5 |
+
# employees of the Federal Government in the course of their official duties. Pursuant
|
| 6 |
+
# to title 17 Section 105 of the United States Code this software is not subject to
|
| 7 |
+
# copyright protection and is in the public domain. ALIGN2HTML is an experimental system.
|
| 8 |
+
# NIST assumes no responsibility whatsoever for its use by other parties, and makes no
|
| 9 |
+
# guarantees, expressed or implied, about its quality, reliability, or any other
|
| 10 |
+
# characteristic. We would appreciate acknowledgement if the software is used.
|
| 11 |
+
#
|
| 12 |
+
# THIS SOFTWARE IS PROVIDED "AS IS." With regard to this software, NIST MAKES NO EXPRESS
|
| 13 |
+
# OR IMPLIED WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING MERCHANTABILITY,
|
| 14 |
+
# OR FITNESS FOR A PARTICULAR PURPOSE.
|
| 15 |
+
|
| 16 |
+
package Segment;
|
| 17 |
+
use strict;
|
| 18 |
+
use Data::Dumper;
|
| 19 |
+
|
| 20 |
+
use Token;
|
| 21 |
+
|
| 22 |
+
sub new
|
| 23 |
+
{
|
| 24 |
+
my $class = shift;
|
| 25 |
+
my $self = {};
|
| 26 |
+
|
| 27 |
+
$self->{ID} = shift;
|
| 28 |
+
$self->{SPKRID} = shift;
|
| 29 |
+
$self->{TOKENS} = {};
|
| 30 |
+
$self->{MINX} = 10000000;
|
| 31 |
+
$self->{MAXX} = 0;
|
| 32 |
+
$self->{HEIGHT} = 0;
|
| 33 |
+
$self->{HASFAKETIME} = 0;
|
| 34 |
+
|
| 35 |
+
bless $self;
|
| 36 |
+
return $self;
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
sub AddToken
|
| 40 |
+
{
|
| 41 |
+
my ($self, $tkn) = @_;
|
| 42 |
+
$self->{TOKENS}{$tkn->{ID}} = $tkn;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
sub SetY
|
| 46 |
+
{
|
| 47 |
+
my ($self, $ypos) = @_;
|
| 48 |
+
|
| 49 |
+
foreach my $tknid(sort keys %{ $self->{TOKENS} })
|
| 50 |
+
{
|
| 51 |
+
$self->{TOKENS}{$tknid}->SetYPos($ypos);
|
| 52 |
+
}
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
sub isTokenInSegment
|
| 56 |
+
{
|
| 57 |
+
my ($self, $tokenid) = @_;
|
| 58 |
+
|
| 59 |
+
foreach my $tknid(sort keys %{ $self->{TOKENS} })
|
| 60 |
+
{
|
| 61 |
+
return 1 if($tknid == $tokenid);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
return 0;
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
sub CalculateMinMaxX
|
| 68 |
+
{
|
| 69 |
+
my ($self) = @_;
|
| 70 |
+
|
| 71 |
+
foreach my $tknid(sort keys %{ $self->{TOKENS} })
|
| 72 |
+
{
|
| 73 |
+
next if( ($self->{TOKENS}{$tknid}->{XSTARTPOS} == 0) && ($self->{TOKENS}{$tknid}->{XENDPOS} == 0) && ($self->{TOKENS}{$tknid}->{TEXT} eq "") );
|
| 74 |
+
$self->{MINX} = $self->{TOKENS}{$tknid}->{XSTARTPOS} if($self->{MINX} > $self->{TOKENS}{$tknid}->{XSTARTPOS});
|
| 75 |
+
$self->{MAXX} = $self->{TOKENS}{$tknid}->{XENDPOS} if($self->{MAXX} < $self->{TOKENS}{$tknid}->{XENDPOS});
|
| 76 |
+
}
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
sub HasOnlyOneFakeToken
|
| 80 |
+
{
|
| 81 |
+
my ($self) = @_;
|
| 82 |
+
|
| 83 |
+
foreach my $tknid(sort keys %{ $self->{TOKENS} })
|
| 84 |
+
{
|
| 85 |
+
return 0 if( !( ($self->{TOKENS}{$tknid}->{XSTARTPOS} == 0) && ($self->{TOKENS}{$tknid}->{XENDPOS} == 0) && ($self->{TOKENS}{$tknid}->{TEXT} eq "") ) );
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
return 1;
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
sub CleanSegmentPrevNext
|
| 92 |
+
{
|
| 93 |
+
my ($self) = @_;
|
| 94 |
+
|
| 95 |
+
foreach my $tknid(sort keys %{ $self->{TOKENS} })
|
| 96 |
+
{
|
| 97 |
+
my $myToken = $self->{TOKENS}{$tknid};
|
| 98 |
+
|
| 99 |
+
for(my $i=0; $i< @{ $myToken->{PREVTKNID} }; $i++)
|
| 100 |
+
{
|
| 101 |
+
delete $myToken->{PREVTKNID}[$i] if(!$self->isTokenInSegment($myToken->{PREVTKNID}[$i]));
|
| 102 |
+
}
|
| 103 |
+
|
| 104 |
+
for(my $i=0; $i< @{ $myToken->{NEXTTKNID} }; $i++)
|
| 105 |
+
{
|
| 106 |
+
delete $myToken->{NEXTTKNID}[$i] if(!$self->isTokenInSegment($myToken->{NEXTTKNID}[$i]));
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
$myToken->{NUMPREV} = scalar( @{ $myToken->{PREVTKNID} } );
|
| 110 |
+
$myToken->{NUMNEXT} = scalar( @{ $myToken->{NEXTTKNID} } );
|
| 111 |
+
}
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
sub MultiGraphXY
|
| 115 |
+
{
|
| 116 |
+
my ($self) = @_;
|
| 117 |
+
|
| 118 |
+
my $maxheigh = 0;
|
| 119 |
+
|
| 120 |
+
if(scalar(keys %{ $self->{TOKENS} }) != 0)
|
| 121 |
+
{
|
| 122 |
+
my %tokenPositions;
|
| 123 |
+
my @listTokenID;
|
| 124 |
+
my $currentlevel = 0;
|
| 125 |
+
my $maxlengh = 0;
|
| 126 |
+
|
| 127 |
+
foreach my $tknid(sort {$a <=> $b} keys %{ $self->{TOKENS} })
|
| 128 |
+
{
|
| 129 |
+
$tokenPositions{$tknid}{XB} = 0;
|
| 130 |
+
$tokenPositions{$tknid}{XE} = 1;
|
| 131 |
+
$tokenPositions{$tknid}{Y} = 0;
|
| 132 |
+
$tokenPositions{$tknid}{TEXT} = $self->{TOKENS}{$tknid}->{TEXT};
|
| 133 |
+
|
| 134 |
+
push(@listTokenID, $tknid);
|
| 135 |
+
|
| 136 |
+
if( scalar(@{ $self->{TOKENS}{$tknid}->{PREVTKNID} }) == 0 )
|
| 137 |
+
{
|
| 138 |
+
$tokenPositions{$tknid}{Y} = $currentlevel;
|
| 139 |
+
$currentlevel++;
|
| 140 |
+
}
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
for(my $i=0; $i<@listTokenID; $i++)
|
| 144 |
+
{
|
| 145 |
+
my $tokenid = $listTokenID[$i];
|
| 146 |
+
my $token = $self->{TOKENS}{$tokenid};
|
| 147 |
+
my @prevtkn = @{ $token->{PREVTKNID} };
|
| 148 |
+
my @nexttkn = @{ $token->{NEXTTKNID} };
|
| 149 |
+
|
| 150 |
+
my $tokenBegin = $tokenPositions{$tokenid}{XB};
|
| 151 |
+
my $tokenEnd = $tokenPositions{$tokenid}{XE};
|
| 152 |
+
my $tokenY = $tokenPositions{$tokenid}{Y};
|
| 153 |
+
|
| 154 |
+
for(my $j=0; $j<@nexttkn; $j++)
|
| 155 |
+
{
|
| 156 |
+
my $nexttokenid = $nexttkn[$j];
|
| 157 |
+
|
| 158 |
+
my $nexttokenBegin = $tokenPositions{$nexttokenid}{XB};
|
| 159 |
+
my $nexttokenEnd = $tokenPositions{$nexttokenid}{XE};
|
| 160 |
+
my $nextTokenY = $tokenPositions{$nexttokenid}{Y};
|
| 161 |
+
|
| 162 |
+
if( $nexttokenBegin < $tokenEnd)
|
| 163 |
+
{
|
| 164 |
+
$tokenPositions{$nexttokenid}{XB} = $tokenEnd;
|
| 165 |
+
$tokenPositions{$nexttokenid}{XE} = $tokenPositions{$nexttokenid}{XB} + 1;
|
| 166 |
+
$i = -1;
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
my $nbrprev = scalar( @{ $self->{TOKENS}{$nexttokenid}->{PREVTKNID} } ) - 1;
|
| 170 |
+
|
| 171 |
+
if($nextTokenY < ($tokenY + $j - $nbrprev))
|
| 172 |
+
{
|
| 173 |
+
$tokenPositions{$nexttokenid}{Y} = $tokenY + $j - $nbrprev;
|
| 174 |
+
$i = -1;
|
| 175 |
+
}
|
| 176 |
+
}
|
| 177 |
+
|
| 178 |
+
for(my $j=0; $j<@prevtkn; $j++)
|
| 179 |
+
{
|
| 180 |
+
my $prevtokenid = $prevtkn[$j];
|
| 181 |
+
|
| 182 |
+
my $prevtokenBegin = $tokenPositions{$prevtokenid}{XB};
|
| 183 |
+
my $prevtokenEnd = $tokenPositions{$prevtokenid}{XE};
|
| 184 |
+
|
| 185 |
+
if( $prevtokenEnd != $tokenBegin)
|
| 186 |
+
{
|
| 187 |
+
$tokenPositions{$prevtokenid}{XE} = $tokenBegin;
|
| 188 |
+
$i = -1;
|
| 189 |
+
}
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
foreach my $tken (sort {$a <=> $b} keys %tokenPositions)
|
| 194 |
+
{
|
| 195 |
+
$maxheigh = $tokenPositions{$tken}{Y} if($tokenPositions{$tken}{Y} > $maxheigh);
|
| 196 |
+
$maxlengh = $tokenPositions{$tken}{XE} if($tokenPositions{$tken}{XE} > $maxlengh);
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
foreach my $tknid(sort keys %{ $self->{TOKENS} })
|
| 200 |
+
{
|
| 201 |
+
my $updown = 1;
|
| 202 |
+
my $base = 0;
|
| 203 |
+
|
| 204 |
+
if($self->{TOKENS}{$tknid}->{REFORSYS} eq "REF")
|
| 205 |
+
{
|
| 206 |
+
$updown = -1;
|
| 207 |
+
$base = $maxheigh;
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
if($self->{TOKENS}{$tknid}->{REALTIME} == 0)
|
| 211 |
+
{
|
| 212 |
+
$self->{TOKENS}{$tknid}->MakeFakeTime($tokenPositions{$tknid}{XB}, $tokenPositions{$tknid}{XE}, $maxlengh);
|
| 213 |
+
$self->{HASFAKETIME} = 1;
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
$self->{TOKENS}{$tknid}->{YPOS} += $base*30 + $updown*30*$tokenPositions{$tknid}{Y};
|
| 217 |
+
}
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
$self->{HEIGHT} = ($maxheigh+1)*30;
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
sub Compute
|
| 224 |
+
{
|
| 225 |
+
my ($self) = @_;
|
| 226 |
+
|
| 227 |
+
# Calculate Min and Max X
|
| 228 |
+
$self->CalculateMinMaxX();
|
| 229 |
+
|
| 230 |
+
# Clean up the previous and Next of Tokens
|
| 231 |
+
$self->CleanSegmentPrevNext();
|
| 232 |
+
|
| 233 |
+
# Assign X and Y for graph
|
| 234 |
+
$self->MultiGraphXY();
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
sub GetDraw
|
| 238 |
+
{
|
| 239 |
+
my ($self, $minx) = @_;
|
| 240 |
+
my $output2 = "";
|
| 241 |
+
|
| 242 |
+
my @listfirsts;
|
| 243 |
+
my @listlasts;
|
| 244 |
+
|
| 245 |
+
foreach my $tknid(sort keys %{ $self->{TOKENS} })
|
| 246 |
+
{
|
| 247 |
+
my @prevtkn = @{ $self->{TOKENS}{$tknid}->{PREVTKNID} };
|
| 248 |
+
my @nexttkn = @{ $self->{TOKENS}{$tknid}->{NEXTTKNID} };
|
| 249 |
+
|
| 250 |
+
if(scalar(@prevtkn) > 1)
|
| 251 |
+
{
|
| 252 |
+
for(my $i=1; $i<@prevtkn; $i++)
|
| 253 |
+
{
|
| 254 |
+
my $end1x = $self->{TOKENS}{$prevtkn[$i-1]}->{XENDPOS} - $minx;
|
| 255 |
+
my $end1y = $self->{TOKENS}{$prevtkn[$i-1]}->{YPOS};
|
| 256 |
+
my $end2x = $self->{TOKENS}{$prevtkn[$i]}->{XENDPOS} - $minx;
|
| 257 |
+
my $end2y = $self->{TOKENS}{$prevtkn[$i]}->{YPOS};
|
| 258 |
+
|
| 259 |
+
$output2 .= sprintf("jg.drawLine(scale*%.0f, %.0f, scale*%.0f, %.0f);\n", $end1x, $end1y, $end2x, $end2y);
|
| 260 |
+
}
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
push(@listfirsts, $tknid) if(scalar(@prevtkn) == 0);
|
| 264 |
+
|
| 265 |
+
if(scalar(@nexttkn) > 1)
|
| 266 |
+
{
|
| 267 |
+
for(my $i=1; $i<@nexttkn; $i++)
|
| 268 |
+
{
|
| 269 |
+
my $begin1x = $self->{TOKENS}{$nexttkn[$i-1]}->{XSTARTPOS} - $minx;
|
| 270 |
+
my $begin1y = $self->{TOKENS}{$nexttkn[$i-1]}->{YPOS};
|
| 271 |
+
my $begin2x = $self->{TOKENS}{$nexttkn[$i]}->{XSTARTPOS} - $minx;
|
| 272 |
+
my $begin2y = $self->{TOKENS}{$nexttkn[$i]}->{YPOS};
|
| 273 |
+
|
| 274 |
+
$output2 .= sprintf("jg.drawLine(scale*%.0f, %.0f, scale*%.0f, %.0f);\n", $begin1x, $begin1y, $begin2x, $begin2y);
|
| 275 |
+
}
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
push(@listlasts, $tknid) if(scalar(@nexttkn) == 0);
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
if(scalar(@listfirsts) > 1)
|
| 282 |
+
{
|
| 283 |
+
for(my $i=1; $i<@listfirsts; $i++)
|
| 284 |
+
{
|
| 285 |
+
my $begin1x = $self->{TOKENS}{$listfirsts[$i-1]}->{XSTARTPOS} - $minx;
|
| 286 |
+
my $begin1y = $self->{TOKENS}{$listfirsts[$i-1]}->{YPOS};
|
| 287 |
+
my $begin2x = $self->{TOKENS}{$listfirsts[$i]}->{XSTARTPOS} - $minx;
|
| 288 |
+
my $begin2y = $self->{TOKENS}{$listfirsts[$i]}->{YPOS};
|
| 289 |
+
|
| 290 |
+
$output2 .= sprintf("jg.drawLine(scale*%.0f, %.0f, scale*%.0f, %.0f);\n", $begin1x, $begin1y, $begin2x, $begin2y);
|
| 291 |
+
}
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
+
if(scalar(@listlasts) > 1)
|
| 295 |
+
{
|
| 296 |
+
for(my $i=1; $i<@listlasts; $i++)
|
| 297 |
+
{
|
| 298 |
+
my $end1x = $self->{TOKENS}{$listlasts[$i-1]}->{XENDPOS} - $minx;
|
| 299 |
+
my $end1y = $self->{TOKENS}{$listlasts[$i-1]}->{YPOS};
|
| 300 |
+
my $end2x = $self->{TOKENS}{$listlasts[$i]}->{XENDPOS} - $minx;
|
| 301 |
+
my $end2y = $self->{TOKENS}{$listlasts[$i]}->{YPOS};
|
| 302 |
+
|
| 303 |
+
$output2 .= sprintf("jg.drawLine(scale*%.0f, %.0f, scale*%.0f, %.0f);\n", $end1x, $end1y, $end2x, $end2y);
|
| 304 |
+
}
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
my $output = "";
|
| 308 |
+
|
| 309 |
+
if($output2 ne "")
|
| 310 |
+
{
|
| 311 |
+
$output .= sprintf("jg.setColor(\"grey\");\n");
|
| 312 |
+
$output .= sprintf("jg.setStroke(Stroke.DOTTED);\n");
|
| 313 |
+
$output .= $output2;
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
foreach my $tknid(sort keys %{ $self->{TOKENS} })
|
| 317 |
+
{
|
| 318 |
+
$output .= $self->{TOKENS}{$tknid}->GetDraw($minx);
|
| 319 |
+
}
|
| 320 |
+
|
| 321 |
+
return $output;
|
| 322 |
+
}
|
| 323 |
+
|
| 324 |
+
1;
|
| 325 |
+
|
SCTK/src/align2html/SegmentGroup.pm
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ALIGN2HTML
|
| 2 |
+
# Author: Jerome Ajot
|
| 3 |
+
#
|
| 4 |
+
# This software was developed at the National Institute of Standards and Technology by
|
| 5 |
+
# employees of the Federal Government in the course of their official duties. Pursuant
|
| 6 |
+
# to title 17 Section 105 of the United States Code this software is not subject to
|
| 7 |
+
# copyright protection and is in the public domain. ALIGN2HTML is an experimental system.
|
| 8 |
+
# NIST assumes no responsibility whatsoever for its use by other parties, and makes no
|
| 9 |
+
# guarantees, expressed or implied, about its quality, reliability, or any other
|
| 10 |
+
# characteristic. We would appreciate acknowledgement if the software is used.
|
| 11 |
+
#
|
| 12 |
+
# THIS SOFTWARE IS PROVIDED "AS IS." With regard to this software, NIST MAKES NO EXPRESS
|
| 13 |
+
# OR IMPLIED WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING MERCHANTABILITY,
|
| 14 |
+
# OR FITNESS FOR A PARTICULAR PURPOSE.
|
| 15 |
+
|
| 16 |
+
package SegmentGroup;
|
| 17 |
+
use strict;
|
| 18 |
+
use Data::Dumper;
|
| 19 |
+
|
| 20 |
+
sub new
|
| 21 |
+
{
|
| 22 |
+
my $class = shift;
|
| 23 |
+
my $self = {};
|
| 24 |
+
|
| 25 |
+
$self->{ID} = shift;
|
| 26 |
+
$self->{REF} = {};
|
| 27 |
+
$self->{SYS} = {};
|
| 28 |
+
$self->{STARTYPOS} = 25;
|
| 29 |
+
$self->{YPOSSTEP} = 20;
|
| 30 |
+
$self->{MINX} = 10000000;
|
| 31 |
+
$self->{MAXX} = 0;
|
| 32 |
+
$self->{HEIGHT} = 0;
|
| 33 |
+
$self->{SPKRHEIGHT} = {};
|
| 34 |
+
$self->{HASFAKETIME} = 0;
|
| 35 |
+
$self->{SPKRYS} = {};
|
| 36 |
+
$self->{FILE} = shift;
|
| 37 |
+
$self->{CHANNEL} = shift;
|
| 38 |
+
$self->{NCORR} = 0;
|
| 39 |
+
$self->{NINS} = 0;
|
| 40 |
+
$self->{NSUB} = 0;
|
| 41 |
+
$self->{NDEL} = 0;
|
| 42 |
+
$self->{NREF} = 0;
|
| 43 |
+
$self->{NSPKRERR} = 0;
|
| 44 |
+
$self->{ET} = 0;
|
| 45 |
+
$self->{BT} = 0;
|
| 46 |
+
$self->{ALIGNED} = 0;
|
| 47 |
+
|
| 48 |
+
bless $self;
|
| 49 |
+
return $self;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
sub unique
|
| 53 |
+
{
|
| 54 |
+
my %saw;
|
| 55 |
+
return grep(!$saw{$_}++, sort @_);
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
sub addRefSegment
|
| 59 |
+
{
|
| 60 |
+
my ($self, $seg) = @_;
|
| 61 |
+
$self->{REF}{$seg->{ID}} = $seg;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
sub addSysSegment
|
| 65 |
+
{
|
| 66 |
+
my ($self, $seg) = @_;
|
| 67 |
+
$self->{SYS}{$seg->{ID}} = $seg;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
sub ContainsFakeTimes
|
| 71 |
+
{
|
| 72 |
+
my ($self) = @_;
|
| 73 |
+
|
| 74 |
+
foreach my $segrefid(sort keys %{ $self->{REF} })
|
| 75 |
+
{
|
| 76 |
+
$self->{HASFAKETIME} = 1 if($self->{REF}{$segrefid}->{HASFAKETIME} == 1);
|
| 77 |
+
return;
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
foreach my $segsysid(sort keys %{ $self->{SYS} })
|
| 81 |
+
{
|
| 82 |
+
$self->{HASFAKETIME} = 1 if($self->{SYS}{$segsysid}->{HASFAKETIME} == 1);
|
| 83 |
+
return;
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
sub GetNumHypWords
|
| 88 |
+
{
|
| 89 |
+
my ($self) = @_;
|
| 90 |
+
|
| 91 |
+
my $number = 0;
|
| 92 |
+
foreach my $segsysid(keys %{ $self->{SYS} }) { $number += scalar keys %{ $self->{SYS}{$segsysid}->{TOKENS} } if(!($self->{SYS}{$segsysid}->HasOnlyOneFakeToken())); }
|
| 93 |
+
return $number;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
sub GetToken
|
| 97 |
+
{
|
| 98 |
+
my ($self, $tokenID) = @_;
|
| 99 |
+
|
| 100 |
+
foreach my $segrefid(keys %{ $self->{REF} })
|
| 101 |
+
{
|
| 102 |
+
return $self->{REF}{$segrefid}->{TOKENS}{$tokenID} if(exists($self->{REF}{$segrefid}->{TOKENS}{$tokenID}));
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
foreach my $segsysid(keys %{ $self->{SYS} })
|
| 106 |
+
{
|
| 107 |
+
return $self->{SYS}{$segsysid}->{TOKENS}{$tokenID} if(exists($self->{SYS}{$segsysid}->{TOKENS}{$tokenID}));
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
return undef;
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
sub CalculateBeginEndTime
|
| 114 |
+
{
|
| 115 |
+
my ($self) = @_;
|
| 116 |
+
|
| 117 |
+
$self->{ET} = 0;
|
| 118 |
+
$self->{BT} = 1000000;
|
| 119 |
+
|
| 120 |
+
foreach my $segrefid(sort keys %{ $self->{REF} })
|
| 121 |
+
{
|
| 122 |
+
foreach my $tknid(sort keys %{ $self->{REF}{$segrefid}->{TOKENS} })
|
| 123 |
+
{
|
| 124 |
+
next if( ($self->{REF}{$segrefid}->{TOKENS}{$tknid}->{SEGBT} == 0) && ($self->{REF}{$segrefid}->{TOKENS}{$tknid}->{SEGET} == 0) && ($self->{REF}{$segrefid}->{TOKENS}{$tknid}->{TEXT} eq "") );
|
| 125 |
+
$self->{BT} = $self->{REF}{$segrefid}->{TOKENS}{$tknid}->{SEGBT} if($self->{REF}{$segrefid}->{TOKENS}{$tknid}->{SEGBT} < $self->{BT});
|
| 126 |
+
$self->{ET} = $self->{REF}{$segrefid}->{TOKENS}{$tknid}->{SEGET} if($self->{REF}{$segrefid}->{TOKENS}{$tknid}->{SEGET} > $self->{ET});
|
| 127 |
+
}
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
foreach my $segsysid(sort keys %{ $self->{SYS} })
|
| 131 |
+
{
|
| 132 |
+
foreach my $tknid(sort keys %{ $self->{SYS}{$segsysid}->{TOKENS} })
|
| 133 |
+
{
|
| 134 |
+
next if( ($self->{SYS}{$segsysid}->{TOKENS}{$tknid}->{BT} == 0) && ($self->{SYS}{$segsysid}->{TOKENS}{$tknid}->{BT} + $self->{SYS}{$segsysid}->{TOKENS}{$tknid}->{DUR} == 0) && ($self->{SYS}{$segsysid}->{TOKENS}{$tknid}->{TEXT} eq "") );
|
| 135 |
+
$self->{BT} = $self->{SYS}{$segsysid}->{TOKENS}{$tknid}->{BT} if($self->{SYS}{$segsysid}->{TOKENS}{$tknid}->{BT} < $self->{BT});
|
| 136 |
+
$self->{ET} = sprintf("%.3f", $self->{SYS}{$segsysid}->{TOKENS}{$tknid}->{BT} + $self->{SYS}{$segsysid}->{TOKENS}{$tknid}->{DUR}) if(sprintf("%.3f", $self->{SYS}{$segsysid}->{TOKENS}{$tknid}->{BT} + $self->{SYS}{$segsysid}->{TOKENS}{$tknid}->{DUR}) > $self->{ET});
|
| 137 |
+
}
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
sub CalculateMinMaxX
|
| 142 |
+
{
|
| 143 |
+
my ($self) = @_;
|
| 144 |
+
|
| 145 |
+
foreach my $segrefid(sort keys %{ $self->{REF} })
|
| 146 |
+
{
|
| 147 |
+
$self->{MINX} = $self->{REF}{$segrefid}->{MINX} if($self->{MINX} > $self->{REF}{$segrefid}->{MINX});
|
| 148 |
+
$self->{MAXX} = $self->{REF}{$segrefid}->{MAXX} if($self->{MAXX} < $self->{REF}{$segrefid}->{MAXX});
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
foreach my $segsysid(sort keys %{ $self->{SYS} })
|
| 152 |
+
{
|
| 153 |
+
$self->{MINX} = $self->{SYS}{$segsysid}->{MINX} if($self->{MINX} > $self->{SYS}{$segsysid}->{MINX});
|
| 154 |
+
$self->{MAXX} = $self->{SYS}{$segsysid}->{MAXX} if($self->{MAXX} < $self->{SYS}{$segsysid}->{MAXX});
|
| 155 |
+
}
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
sub CalculateHeigh
|
| 159 |
+
{
|
| 160 |
+
my ($self) = @_;
|
| 161 |
+
|
| 162 |
+
my %spkrYpos;
|
| 163 |
+
|
| 164 |
+
$self->{HEIGHT} = 2 * $self->{STARTYPOS} + $self->{YPOSSTEP};
|
| 165 |
+
|
| 166 |
+
foreach my $segrefid(sort keys %{ $self->{REF} })
|
| 167 |
+
{
|
| 168 |
+
my $spkrID = $self->{REF}{$segrefid}->{SPKRID};
|
| 169 |
+
|
| 170 |
+
if(!exists($spkrYpos{REF}{$spkrID}))
|
| 171 |
+
{
|
| 172 |
+
$spkrYpos{REF}{$spkrID} = 1;
|
| 173 |
+
$self->{SPKRHEIGHT}{$spkrID} = $self->{REF}{$segrefid}->{HEIGHT};
|
| 174 |
+
}
|
| 175 |
+
else
|
| 176 |
+
{
|
| 177 |
+
$self->{SPKRHEIGHT}{$spkrID} = $self->{REF}{$segrefid}->{HEIGHT} if($self->{REF}{$segrefid}->{HEIGHT} > $self->{SPKRHEIGHT}{$spkrID});
|
| 178 |
+
}
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
foreach my $segsysid(sort keys %{ $self->{SYS} })
|
| 182 |
+
{
|
| 183 |
+
my $spkrID = $self->{SYS}{$segsysid}->{SPKRID};
|
| 184 |
+
|
| 185 |
+
if(!exists($spkrYpos{SYS}{$spkrID}))
|
| 186 |
+
{
|
| 187 |
+
$spkrYpos{SYS}{$spkrID} = 1;
|
| 188 |
+
$self->{SPKRHEIGHT}{$spkrID} = $self->{SYS}{$segsysid}->{HEIGHT};
|
| 189 |
+
}
|
| 190 |
+
else
|
| 191 |
+
{
|
| 192 |
+
$self->{SPKRHEIGHT}{$spkrID} = $self->{SYS}{$segsysid}->{HEIGHT} if($self->{SYS}{$segsysid}->{HEIGHT} > $self->{SPKRHEIGHT}{$spkrID});
|
| 193 |
+
}
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
foreach my $idd (keys %{ $self->{SPKRHEIGHT} } )
|
| 197 |
+
{
|
| 198 |
+
$self->{HEIGHT} += $self->{SPKRHEIGHT}{$idd} + $self->{YPOSSTEP};
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
return $self->{HEIGHT};
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
sub SetYs
|
| 205 |
+
{
|
| 206 |
+
my ($self) = @_;
|
| 207 |
+
|
| 208 |
+
my $output = "";
|
| 209 |
+
my $currYpos = $self->{STARTYPOS};
|
| 210 |
+
my $YposStep = $self->{YPOSSTEP};
|
| 211 |
+
|
| 212 |
+
my %spkrYpos;
|
| 213 |
+
|
| 214 |
+
foreach my $segrefid(sort keys %{ $self->{REF} })
|
| 215 |
+
{
|
| 216 |
+
my $spkrID = $self->{REF}{$segrefid}->{SPKRID};
|
| 217 |
+
my $Ypos;
|
| 218 |
+
|
| 219 |
+
if(!exists($spkrYpos{REF}{$spkrID}))
|
| 220 |
+
{
|
| 221 |
+
$Ypos = $currYpos;
|
| 222 |
+
$spkrYpos{REF}{$spkrID} = $Ypos;
|
| 223 |
+
$currYpos += $self->{SPKRHEIGHT}{$spkrID} + $YposStep;
|
| 224 |
+
}
|
| 225 |
+
else
|
| 226 |
+
{
|
| 227 |
+
$Ypos = $spkrYpos{REF}{$spkrID};
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
$self->{REF}{$segrefid}->SetY($Ypos);
|
| 231 |
+
$self->{SPKRYS}{$spkrID} = $Ypos;
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
$currYpos += 2*$self->{YPOSSTEP};
|
| 235 |
+
|
| 236 |
+
foreach my $segsysid(sort keys %{ $self->{SYS} })
|
| 237 |
+
{
|
| 238 |
+
my $spkrID = $self->{SYS}{$segsysid}->{SPKRID};
|
| 239 |
+
my $Ypos;
|
| 240 |
+
|
| 241 |
+
if(!exists($spkrYpos{SYS}{$spkrID}))
|
| 242 |
+
{
|
| 243 |
+
$Ypos = $currYpos;
|
| 244 |
+
$spkrYpos{SYS}{$spkrID} = $Ypos;
|
| 245 |
+
$currYpos += $self->{SPKRHEIGHT}{$spkrID} + $YposStep;
|
| 246 |
+
}
|
| 247 |
+
else
|
| 248 |
+
{
|
| 249 |
+
$Ypos = $spkrYpos{SYS}{$spkrID};
|
| 250 |
+
}
|
| 251 |
+
|
| 252 |
+
$self->{SYS}{$segsysid}->SetY($Ypos);
|
| 253 |
+
$self->{SPKRYS}{$spkrID} = $Ypos;
|
| 254 |
+
}
|
| 255 |
+
}
|
| 256 |
+
|
| 257 |
+
sub GetFillREFHYP
|
| 258 |
+
{
|
| 259 |
+
my ($self, $maxscalewidth) = @_;
|
| 260 |
+
my $output = "";
|
| 261 |
+
my @valuessep1;
|
| 262 |
+
|
| 263 |
+
foreach my $spkrID(sort keys %{ $self->{SPKRYS} })
|
| 264 |
+
{
|
| 265 |
+
push(@valuessep1, $self->{SPKRYS}{$spkrID} - 25);
|
| 266 |
+
push(@valuessep1, $self->{SPKRYS}{$spkrID} + $self->{SPKRHEIGHT}{$spkrID});
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
my @valuessep = sort {$a <=> $b} @valuessep1;
|
| 270 |
+
|
| 271 |
+
my @refspkrs;
|
| 272 |
+
foreach my $segref (keys %{ $self->{REF} }) { push(@refspkrs, $self->{REF}{$segref}->{SPKRID}); }
|
| 273 |
+
my $nrefspkr = scalar unique @refspkrs;
|
| 274 |
+
|
| 275 |
+
my @sysspkrs;
|
| 276 |
+
foreach my $segsys (keys %{ $self->{SYS} }) { push(@sysspkrs, $self->{SYS}{$segsys}->{SPKRID}); }
|
| 277 |
+
my $nsysspkr = scalar unique @sysspkrs;
|
| 278 |
+
|
| 279 |
+
if($nrefspkr == 0)
|
| 280 |
+
{
|
| 281 |
+
my $y1 = $valuessep[0];
|
| 282 |
+
my $y2 = $valuessep[scalar(@valuessep) - 1];
|
| 283 |
+
$output .= sprintf("jg.setColor(\"#ffeeee\");\n");
|
| 284 |
+
$output .= sprintf("jg.fillRect(0, %.0f, scale*%.0f - 1, %.0f);\n", $y1 + 1, $maxscalewidth, $y2 - $y1 - 1);
|
| 285 |
+
}
|
| 286 |
+
elsif($nsysspkr == 0)
|
| 287 |
+
{
|
| 288 |
+
my $y1 = $valuessep[0];
|
| 289 |
+
my $y2 = $valuessep[scalar(@valuessep) - 1];
|
| 290 |
+
$output .= sprintf("jg.setColor(\"#eeffee\");\n");
|
| 291 |
+
$output .= sprintf("jg.fillRect(0, %.0f, scale*%.0f - 1, %.0f);\n", $y1 + 1, $maxscalewidth, $y2 - $y1 - 1);
|
| 292 |
+
}
|
| 293 |
+
else
|
| 294 |
+
{
|
| 295 |
+
my $y1 = $valuessep[0];
|
| 296 |
+
my $ym = ($valuessep[2*$nrefspkr - 1] + $valuessep[2*$nrefspkr])/2;
|
| 297 |
+
my $y2 = $valuessep[scalar(@valuessep) - 1];
|
| 298 |
+
$output .= sprintf("jg.setColor(\"#eeffee\");\n");
|
| 299 |
+
$output .= sprintf("jg.fillRect(0, %.0f, scale*%.0f - 1, %.0f);\n", $y1 + 1, $maxscalewidth, $ym - $y1 - 1);
|
| 300 |
+
$output .= sprintf("jg.setColor(\"#ffeeee\");\n");
|
| 301 |
+
$output .= sprintf("jg.fillRect(0, %.0f, scale*%.0f - 1, %.0f);\n", $ym - $y1 + 1, $maxscalewidth, $y2 - $ym -1);
|
| 302 |
+
}
|
| 303 |
+
|
| 304 |
+
return $output;
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
sub GetSeparationLines
|
| 308 |
+
{
|
| 309 |
+
my ($self, $maxscalewidth) = @_;
|
| 310 |
+
my $output = "";
|
| 311 |
+
|
| 312 |
+
$output .= sprintf("jg.setColor(\"black\");\n");
|
| 313 |
+
$output .= sprintf("jg.setFont(\"verdana\",\"12px\",Font.PLAIN);\n");
|
| 314 |
+
|
| 315 |
+
foreach my $spkrID(sort keys %{ $self->{SPKRYS} })
|
| 316 |
+
{
|
| 317 |
+
my $spkName = $spkrID;
|
| 318 |
+
$spkName =~ s/^ref://;
|
| 319 |
+
$spkName =~ s/^hyp://;
|
| 320 |
+
$output .= sprintf("jg.drawStringRect(\"%s\",%.0f, %.0f, scale*%.0f, \"left\");\n", $spkName, 0, $self->{SPKRYS}{$spkrID} - 8 + ($self->{SPKRHEIGHT}{$spkrID}-30)/2, $maxscalewidth);
|
| 321 |
+
}
|
| 322 |
+
|
| 323 |
+
$output .= sprintf("jg.setColor(\"yellow\");\n");
|
| 324 |
+
$output .= sprintf("jg.setStroke(1);\n");
|
| 325 |
+
|
| 326 |
+
my @valuessep1;
|
| 327 |
+
|
| 328 |
+
foreach my $spkrID(sort keys %{ $self->{SPKRYS} })
|
| 329 |
+
{
|
| 330 |
+
push(@valuessep1, $self->{SPKRYS}{$spkrID} - 25);
|
| 331 |
+
push(@valuessep1, $self->{SPKRYS}{$spkrID} + $self->{SPKRHEIGHT}{$spkrID});
|
| 332 |
+
}
|
| 333 |
+
|
| 334 |
+
my @valuessep = sort {$a <=> $b} @valuessep1;
|
| 335 |
+
|
| 336 |
+
$output .= sprintf("jg.drawLine(0, %.0f, scale*%.0f - 1, %.0f);\n", $valuessep[0], $maxscalewidth, $valuessep[0]);
|
| 337 |
+
|
| 338 |
+
for(my $i=1; $i<scalar(@valuessep)-1; $i += 2)
|
| 339 |
+
{
|
| 340 |
+
my $ypostmp = ($valuessep[$i] + $valuessep[$i + 1])/2;
|
| 341 |
+
|
| 342 |
+
$output .= sprintf("jg.drawLine(0, %.0f, scale*%.0f - 1, %.0f);\n", $ypostmp, $maxscalewidth, $ypostmp);
|
| 343 |
+
}
|
| 344 |
+
|
| 345 |
+
$output .= sprintf("jg.drawLine(0, %.0f, scale*%.0f - 1, %.0f);\n", $valuessep[scalar(@valuessep) - 1], $maxscalewidth, $valuessep[scalar(@valuessep) - 1]);
|
| 346 |
+
|
| 347 |
+
return $output;
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
+
sub Compute
|
| 351 |
+
{
|
| 352 |
+
my ($self) = @_;
|
| 353 |
+
|
| 354 |
+
foreach my $segrefid(sort keys %{ $self->{REF} })
|
| 355 |
+
{
|
| 356 |
+
$self->{REF}{$segrefid}->Compute();
|
| 357 |
+
}
|
| 358 |
+
|
| 359 |
+
foreach my $segsysid(sort keys %{ $self->{SYS} })
|
| 360 |
+
{
|
| 361 |
+
$self->{SYS}{$segsysid}->Compute();
|
| 362 |
+
}
|
| 363 |
+
|
| 364 |
+
$self->CalculateMinMaxX();
|
| 365 |
+
$self->CalculateHeigh();
|
| 366 |
+
$self->ContainsFakeTimes();
|
| 367 |
+
$self->SetYs();
|
| 368 |
+
$self->CalculateBeginEndTime();
|
| 369 |
+
}
|
| 370 |
+
|
| 371 |
+
sub isInSpeakers
|
| 372 |
+
{
|
| 373 |
+
my ($self, $spkr) = @_;
|
| 374 |
+
|
| 375 |
+
foreach my $segrefid(sort keys %{ $self->{REF} })
|
| 376 |
+
{
|
| 377 |
+
return 1 if($self->{REF}{$segrefid}->{SPKRID} =~ /^$spkr$/i);
|
| 378 |
+
}
|
| 379 |
+
|
| 380 |
+
foreach my $segsysid(sort keys %{ $self->{SYS} })
|
| 381 |
+
{
|
| 382 |
+
return 1 if($self->{SYS}{$segsysid}->{SPKRID} =~ /^$spkr$/i);
|
| 383 |
+
}
|
| 384 |
+
|
| 385 |
+
return 0;
|
| 386 |
+
}
|
| 387 |
+
|
| 388 |
+
sub GetDraw
|
| 389 |
+
{
|
| 390 |
+
my ($self, $decalx) = @_;
|
| 391 |
+
my $output = "";
|
| 392 |
+
|
| 393 |
+
foreach my $segrefid(sort keys %{ $self->{REF} })
|
| 394 |
+
{
|
| 395 |
+
$output .= $self->{REF}{$segrefid}->GetDraw($self->{MINX} - $decalx);
|
| 396 |
+
}
|
| 397 |
+
|
| 398 |
+
foreach my $segsysid(sort keys %{ $self->{SYS} })
|
| 399 |
+
{
|
| 400 |
+
$output .= $self->{SYS}{$segsysid}->GetDraw($self->{MINX} - $decalx);
|
| 401 |
+
}
|
| 402 |
+
|
| 403 |
+
return $output;
|
| 404 |
+
}
|
| 405 |
+
|
| 406 |
+
1;
|
| 407 |
+
|
SCTK/src/align2html/Token.pm
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ALIGN2HTML
|
| 2 |
+
# Author: Jerome Ajot
|
| 3 |
+
#
|
| 4 |
+
# This software was developed at the National Institute of Standards and Technology by
|
| 5 |
+
# employees of the Federal Government in the course of their official duties. Pursuant
|
| 6 |
+
# to title 17 Section 105 of the United States Code this software is not subject to
|
| 7 |
+
# copyright protection and is in the public domain. ALIGN2HTML is an experimental system.
|
| 8 |
+
# NIST assumes no responsibility whatsoever for its use by other parties, and makes no
|
| 9 |
+
# guarantees, expressed or implied, about its quality, reliability, or any other
|
| 10 |
+
# characteristic. We would appreciate acknowledgement if the software is used.
|
| 11 |
+
#
|
| 12 |
+
# THIS SOFTWARE IS PROVIDED "AS IS." With regard to this software, NIST MAKES NO EXPRESS
|
| 13 |
+
# OR IMPLIED WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING MERCHANTABILITY,
|
| 14 |
+
# OR FITNESS FOR A PARTICULAR PURPOSE.
|
| 15 |
+
|
| 16 |
+
package Token;
|
| 17 |
+
use strict;
|
| 18 |
+
use Data::Dumper;
|
| 19 |
+
|
| 20 |
+
sub new
|
| 21 |
+
{
|
| 22 |
+
my $class = shift;
|
| 23 |
+
my $self = {};
|
| 24 |
+
|
| 25 |
+
$self->{ID} = shift;
|
| 26 |
+
$self->{BT} = shift;
|
| 27 |
+
$self->{DUR} = shift;
|
| 28 |
+
$self->{MID} = 0;
|
| 29 |
+
$self->{TEXT} = shift;
|
| 30 |
+
$self->{LENGTH} = 0;
|
| 31 |
+
$self->{XSTARTPOS} = 0;
|
| 32 |
+
$self->{XENDPOS} = 0;
|
| 33 |
+
$self->{YPOS} = 0;
|
| 34 |
+
$self->{XMIDPOS} = 0;
|
| 35 |
+
$self->{TEXTPOS} = "top";
|
| 36 |
+
$self->{WIDTHLINE} = 1;
|
| 37 |
+
$self->{PIXPERSEC} = 100;
|
| 38 |
+
$self->{REFORSYS} = shift;
|
| 39 |
+
$self->{PREVTKNID} = [()];
|
| 40 |
+
$self->{NEXTTKNID} = [()];
|
| 41 |
+
$self->{DISPLAY} = 0;
|
| 42 |
+
$self->{NUMPREV} = 0;
|
| 43 |
+
$self->{NUMNEXT} = 0;
|
| 44 |
+
$self->{SEGGRPID} = shift;
|
| 45 |
+
$self->{SEGID} = shift;
|
| 46 |
+
$self->{SPKRID} = shift;
|
| 47 |
+
$self->{CONF} = shift;
|
| 48 |
+
$self->{REALTIME} = 1;
|
| 49 |
+
|
| 50 |
+
my $tmpprev = shift;
|
| 51 |
+
my $tmpnext = shift;
|
| 52 |
+
|
| 53 |
+
$self->{SEGBT} = shift;
|
| 54 |
+
$self->{SEGET} = shift;
|
| 55 |
+
|
| 56 |
+
bless $self;
|
| 57 |
+
|
| 58 |
+
$self->{REALTIME} = 0 if( ($self->{BT} eq "") || ($self->{DUR} eq "") );
|
| 59 |
+
|
| 60 |
+
if($self->{REALTIME} == 0)
|
| 61 |
+
{
|
| 62 |
+
$self->{BT} = $self->{SEGBT};
|
| 63 |
+
$self->{DUR} = sprintf("%.3f", $self->{SEGET}-$self->{SEGBT});
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
$self->{MID} = sprintf("%.0f", $self->{BT} + $self->{DUR}/2);
|
| 67 |
+
$self->{XSTARTPOS} = sprintf("%.0f", $self->{PIXPERSEC}*$self->{BT});
|
| 68 |
+
$self->{XMIDPOS} = sprintf("%.0f", $self->{PIXPERSEC}*($self->{BT}+$self->{DUR}/2));
|
| 69 |
+
$self->{XENDPOS} = sprintf("%.0f", $self->{PIXPERSEC}*($self->{BT}+$self->{DUR}));
|
| 70 |
+
$self->{LENGTH} = sprintf("%.0f", $self->{PIXPERSEC}*$self->{DUR});
|
| 71 |
+
$self->{TEXTPOS} = "bottom" if($self->{REFORSYS} eq "SYS");
|
| 72 |
+
|
| 73 |
+
push(@{ $self->{PREVTKNID} }, sort {$a <=> $b} split(/\|/, $tmpprev) );
|
| 74 |
+
push(@{ $self->{NEXTTKNID} }, sort {$a <=> $b} split(/\|/, $tmpnext) );
|
| 75 |
+
|
| 76 |
+
$self->{NUMPREV} = scalar( @{ $self->{PREVTKNID} } );
|
| 77 |
+
$self->{NUMNEXT} = scalar( @{ $self->{NEXTTKNID} } );
|
| 78 |
+
|
| 79 |
+
return $self;
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
sub MakeFakeTime
|
| 83 |
+
{
|
| 84 |
+
my ($self, $beginindex, $endindex, $maxind) = @_;
|
| 85 |
+
|
| 86 |
+
$self->{DUR} = sprintf("%.3f", ($self->{SEGET} - $self->{SEGBT})*( ($endindex - $beginindex)/$maxind ) );
|
| 87 |
+
$self->{BT} = sprintf("%.3f", $self->{SEGBT} + ($self->{SEGET} - $self->{SEGBT})*$beginindex/$maxind);
|
| 88 |
+
$self->{MID} = sprintf("%.0f", $self->{BT} + $self->{DUR}/2);
|
| 89 |
+
$self->{XSTARTPOS} = sprintf("%.0f", $self->{PIXPERSEC}*$self->{BT});
|
| 90 |
+
$self->{XMIDPOS} = sprintf("%.0f", $self->{PIXPERSEC}*($self->{BT}+$self->{DUR}/2));
|
| 91 |
+
$self->{XENDPOS} = sprintf("%.0f", $self->{PIXPERSEC}*($self->{BT}+$self->{DUR}));
|
| 92 |
+
$self->{LENGTH} = sprintf("%.0f", $self->{PIXPERSEC}*$self->{DUR});
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
sub DoDisplay
|
| 96 |
+
{
|
| 97 |
+
my ($self) = @_;
|
| 98 |
+
$self->{DISPLAY} = 1;
|
| 99 |
+
}
|
| 100 |
+
|
| 101 |
+
sub AddPrevToken
|
| 102 |
+
{
|
| 103 |
+
my ($self, $prevtknid) = @_;
|
| 104 |
+
push(@{ $self->{PREVTKNID} }, $prevtknid);
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
sub AddNextToken
|
| 108 |
+
{
|
| 109 |
+
my ($self, $nexttknid) = @_;
|
| 110 |
+
push(@{ $self->{NEXTTKNID} }, $nexttknid);
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
sub SetYPos
|
| 114 |
+
{
|
| 115 |
+
my ($self, $ypos) = @_;
|
| 116 |
+
$self->{YPOS} += $ypos;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
sub SetWidthLine
|
| 121 |
+
{
|
| 122 |
+
my ($self, $lwidth) = @_;
|
| 123 |
+
$self->{WIDTHLINE} = $lwidth;
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
sub IsFakeToken
|
| 127 |
+
{
|
| 128 |
+
my ($self) = @_;
|
| 129 |
+
return( ($self->{SEGBT} == 0) && ($self->{SEGET} == 0) && ($self->{TEXT} eq "") );
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
sub GetDraw
|
| 133 |
+
{
|
| 134 |
+
my ($self, $minx) = @_;
|
| 135 |
+
my $output = "";
|
| 136 |
+
|
| 137 |
+
return $output if(! $self->{DISPLAY});
|
| 138 |
+
|
| 139 |
+
if($self->{TEXT} ne "")
|
| 140 |
+
{
|
| 141 |
+
my $modiftexty = ($self->{TEXTPOS} eq "top" ? -17 : 6);
|
| 142 |
+
my $bullet = "images/white_dk.gif";
|
| 143 |
+
$bullet = "images/white_lt.gif" if($self->{REALTIME} == 0);
|
| 144 |
+
|
| 145 |
+
$output .= sprintf("jg.setColor(\"DimGray\");\n");
|
| 146 |
+
$output .= sprintf("jg.setStroke(%.0f);\n", $self->{WIDTHLINE});
|
| 147 |
+
$output .= sprintf("jg.drawLine(%.0f*scale, %.0f, %.0f*scale, %.0f);\n", $self->{XSTARTPOS} - $minx, $self->{YPOS}, $self->{XENDPOS} - $minx, $self->{YPOS});
|
| 148 |
+
$output .= sprintf("jg.setFont(\"arial\",\"11px\",Font.PLAIN);\n");
|
| 149 |
+
$output .= sprintf("jg.drawStringRect(\"%s\", %.0f*scale + 1, %.0f, %.0f*scale - 1, \"center\");\n", $self->{TEXT}, $self->{XSTARTPOS} - $minx, $self->{YPOS}+$modiftexty, $self->{LENGTH});
|
| 150 |
+
$output .= sprintf("jg.drawImage(\"%s\", %.0f*scale - 7, %.0f - 7, 14, 14);\n", $bullet, $self->{XSTARTPOS} - $minx, $self->{YPOS});
|
| 151 |
+
$output .= sprintf("jg.drawImage(\"%s\", %.0f*scale - 7, %.0f - 7, 14, 14);\n", $bullet, $self->{XENDPOS} - $minx, $self->{YPOS});
|
| 152 |
+
}
|
| 153 |
+
elsif(!( ($self->{SEGBT} == 0) && ($self->{SEGET} == 0) && ($self->{TEXT} eq "") ) )
|
| 154 |
+
{
|
| 155 |
+
$output .= sprintf("jg.setColor(\"brown\");\n");
|
| 156 |
+
$output .= sprintf("jg.setStroke(%.0f);\n", $self->{WIDTHLINE});
|
| 157 |
+
$output .= sprintf("jg.drawLine(%.0f*scale, %.0f, %.0f*scale, %.0f);\n", $self->{XSTARTPOS} - $minx, $self->{YPOS}, $self->{XENDPOS} - $minx, $self->{YPOS});
|
| 158 |
+
$output .= sprintf("jg.drawLine(%.0f*scale, %.0f, %.0f*scale, %.0f);\n", $self->{XSTARTPOS} - $minx, $self->{YPOS} - 4, $self->{XSTARTPOS} - $minx, $self->{YPOS} + 4);
|
| 159 |
+
$output .= sprintf("jg.drawLine(%.0f*scale, %.0f, %.0f*scale, %.0f);\n", $self->{XENDPOS} - $minx, $self->{YPOS} - 4, $self->{XENDPOS} - $minx, $self->{YPOS} + 4);
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
return $output;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
1;
|
| 166 |
+
|
SCTK/src/align2html/align2html-main.pl
ADDED
|
@@ -0,0 +1,1436 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/perl -w
|
| 2 |
+
|
| 3 |
+
# ALIGN2HTML
|
| 4 |
+
# Author: Jerome Ajot
|
| 5 |
+
#
|
| 6 |
+
# This software was developed at the National Institute of Standards and Technology by
|
| 7 |
+
# employees of the Federal Government in the course of their official duties. Pursuant
|
| 8 |
+
# to title 17 Section 105 of the United States Code this software is not subject to
|
| 9 |
+
# copyright protection and is in the public domain. ALIGN2HTML is an experimental system.
|
| 10 |
+
# NIST assumes no responsibility whatsoever for its use by other parties, and makes no
|
| 11 |
+
# guarantees, expressed or implied, about its quality, reliability, or any other
|
| 12 |
+
# characteristic. We would appreciate acknowledgement if the software is used.
|
| 13 |
+
#
|
| 14 |
+
# THIS SOFTWARE IS PROVIDED "AS IS." With regard to this software, NIST MAKES NO EXPRESS
|
| 15 |
+
# OR IMPLIED WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING MERCHANTABILITY,
|
| 16 |
+
# OR FITNESS FOR A PARTICULAR PURPOSE.
|
| 17 |
+
|
| 18 |
+
use strict;
|
| 19 |
+
use Getopt::Long;
|
| 20 |
+
use Data::Dumper;
|
| 21 |
+
use File::Path;
|
| 22 |
+
|
| 23 |
+
### Begin Local Modules
|
| 24 |
+
use SegmentGroup;
|
| 25 |
+
use Segment;
|
| 26 |
+
use Token;
|
| 27 |
+
### End Local Modules
|
| 28 |
+
|
| 29 |
+
Getopt::Long::Configure(qw( auto_abbrev no_ignore_case ));
|
| 30 |
+
|
| 31 |
+
my $VERSION = "0.6";
|
| 32 |
+
my $AlignFile = "";
|
| 33 |
+
my $MapFile = "";
|
| 34 |
+
my $Outputdir = "";
|
| 35 |
+
my $NonLinearSegments = 0;
|
| 36 |
+
my $pixelpersec = 100;
|
| 37 |
+
my $maxscalewidth = 0;
|
| 38 |
+
|
| 39 |
+
## This variable says if the program is installed as a standalone executable
|
| 40 |
+
my $Installed = 0;
|
| 41 |
+
|
| 42 |
+
sub usage
|
| 43 |
+
{
|
| 44 |
+
print "perl align2html.pl [OPTIONS] -i alignfile -o outputdir\n";
|
| 45 |
+
print "Version: $VERSION\n";
|
| 46 |
+
print "\n";
|
| 47 |
+
print "Required file arguments:\n";
|
| 48 |
+
print " -a, --alignfile Path to the Alignment file.\n";
|
| 49 |
+
print " -o, --outputdir Path to the output directory.\n";
|
| 50 |
+
print "\n";
|
| 51 |
+
print "Options\n";
|
| 52 |
+
print " -m, --mapfile Path to the Mapping file.\n";
|
| 53 |
+
print "\n";
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
sub extractJavaImages
|
| 57 |
+
{
|
| 58 |
+
my ($outDir) = @_;
|
| 59 |
+
die "HERE DOCUMENT NOT BUILT";
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
sub unique
|
| 63 |
+
{
|
| 64 |
+
my %saw;
|
| 65 |
+
return grep(!$saw{$_}++, sort @_);
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
my %SegGroups;
|
| 69 |
+
my %Alignments;
|
| 70 |
+
my %FileChannelSG;
|
| 71 |
+
my %Overlap;
|
| 72 |
+
my %CumulOverlap;
|
| 73 |
+
|
| 74 |
+
sub addSGLine
|
| 75 |
+
{
|
| 76 |
+
my ($inputline) = @_;
|
| 77 |
+
|
| 78 |
+
my $SG;
|
| 79 |
+
my $Segmnt;
|
| 80 |
+
my $SYSREF = "";
|
| 81 |
+
my $SegID;
|
| 82 |
+
my $Tokn;
|
| 83 |
+
my $SpkrID;
|
| 84 |
+
|
| 85 |
+
my $SG_SegGrpID = $inputline->[1];
|
| 86 |
+
my $SG_SegGrpFile = $inputline->[2];
|
| 87 |
+
my $SG_SegGrpChan = $inputline->[3];
|
| 88 |
+
my $SG_RefSegID = $inputline->[5];
|
| 89 |
+
my $SG_HypSegID = $inputline->[16];
|
| 90 |
+
|
| 91 |
+
my $ok = 0;
|
| 92 |
+
|
| 93 |
+
if($SG_RefSegID ne "" && $inputline->[9] ne "")
|
| 94 |
+
{
|
| 95 |
+
$SYSREF = "REF";
|
| 96 |
+
$SegID = $SG_RefSegID;
|
| 97 |
+
$SpkrID = "ref:" . $inputline->[8];
|
| 98 |
+
|
| 99 |
+
my $dur = 0;
|
| 100 |
+
$dur = sprintf("%.3f", $inputline->[11]-$inputline->[10]) if( ($inputline->[10] ne "") || ($inputline->[11] ne "") );
|
| 101 |
+
|
| 102 |
+
$Tokn = new Token($inputline->[9], $inputline->[10], $dur, $inputline->[12], $SYSREF, $inputline->[1], $inputline->[5], $SpkrID, $inputline->[13], $inputline->[14], $inputline->[15], $inputline->[6], $inputline->[7]);
|
| 103 |
+
$ok = 1;
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
if($SG_HypSegID ne "" && $inputline->[20] ne "")
|
| 107 |
+
{
|
| 108 |
+
$SYSREF = "SYS";
|
| 109 |
+
$SegID = $SG_HypSegID;
|
| 110 |
+
$SpkrID = "hyp:" . $inputline->[19];
|
| 111 |
+
|
| 112 |
+
my $dur = 0;
|
| 113 |
+
$dur = sprintf("%.3f", $inputline->[22]-$inputline->[21]) if( ($inputline->[21] ne "") || ($inputline->[22] ne "") );
|
| 114 |
+
|
| 115 |
+
$Tokn = new Token($inputline->[20], $inputline->[21], $dur, $inputline->[23], $SYSREF, $inputline->[1], $inputline->[16], $SpkrID, $inputline->[24], $inputline->[25], $inputline->[26], $inputline->[17], $inputline->[18]);
|
| 116 |
+
$ok = 1;
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
if($ok)
|
| 120 |
+
{
|
| 121 |
+
$SegGroups{$SG_SegGrpID} = new SegmentGroup($SG_SegGrpID, $SG_SegGrpFile, $SG_SegGrpChan) if(!exists($SegGroups{$SG_SegGrpID}));
|
| 122 |
+
$SG = $SegGroups{$SG_SegGrpID};
|
| 123 |
+
|
| 124 |
+
if(!exists( $SG->{$SYSREF}{$SegID} ))
|
| 125 |
+
{
|
| 126 |
+
$Segmnt = new Segment($SegID, $SpkrID);
|
| 127 |
+
|
| 128 |
+
$SG->addSysSegment($Segmnt) if($SYSREF eq "SYS");
|
| 129 |
+
$SG->addRefSegment($Segmnt) if($SYSREF eq "REF");
|
| 130 |
+
}
|
| 131 |
+
else
|
| 132 |
+
{
|
| 133 |
+
$Segmnt = $SG->{$SYSREF}{$SegID};
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
$Tokn->DoDisplay();
|
| 137 |
+
$Segmnt->AddToken($Tokn);
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
sub addAlignments
|
| 142 |
+
{
|
| 143 |
+
my ($inputline) = @_;
|
| 144 |
+
|
| 145 |
+
my $SG_SegGrpID = $inputline->[1];
|
| 146 |
+
my $SG_Eval = $inputline->[4];
|
| 147 |
+
my $SG_RefTknID = $inputline->[9];
|
| 148 |
+
my $SG_HypTknID = $inputline->[20];
|
| 149 |
+
|
| 150 |
+
push( @{ $Alignments{$SG_SegGrpID} }, [($SG_Eval, $SG_RefTknID, $SG_HypTknID)]);
|
| 151 |
+
$SegGroups{$SG_SegGrpID}->{ALIGNED} = 1;
|
| 152 |
+
|
| 153 |
+
if($SG_RefTknID ne "")
|
| 154 |
+
{
|
| 155 |
+
$SegGroups{$SG_SegGrpID}->GetToken($SG_RefTknID)->SetWidthLine(2);
|
| 156 |
+
$SegGroups{$SG_SegGrpID}->GetToken($SG_RefTknID)->DoDisplay();
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
if($SG_HypTknID ne "")
|
| 160 |
+
{
|
| 161 |
+
$SegGroups{$SG_SegGrpID}->GetToken($SG_HypTknID)->SetWidthLine(2);
|
| 162 |
+
$SegGroups{$SG_SegGrpID}->GetToken($SG_HypTknID)->DoDisplay();
|
| 163 |
+
}
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
sub loadAlignFile
|
| 167 |
+
{
|
| 168 |
+
my ($alignfile) = @_;
|
| 169 |
+
my $linenum = 0;
|
| 170 |
+
|
| 171 |
+
open(ALIGNFILE, $alignfile) or die "Unable to open for read alignfile file '$alignfile'";
|
| 172 |
+
|
| 173 |
+
while (<ALIGNFILE>)
|
| 174 |
+
{
|
| 175 |
+
chomp;
|
| 176 |
+
my $fileline = $_;
|
| 177 |
+
$linenum++;
|
| 178 |
+
|
| 179 |
+
next if($fileline !~ /^\[ALIGNMENT\]/);
|
| 180 |
+
next if($fileline =~ /^\[ALIGNMENT\]\s*Aligned/);
|
| 181 |
+
|
| 182 |
+
$fileline =~ s/^\[ALIGNMENT\]//g;
|
| 183 |
+
$fileline =~ s/\s+//g;
|
| 184 |
+
$fileline =~ s/,/, /g;
|
| 185 |
+
|
| 186 |
+
my @spliteedline = split(",", $fileline);
|
| 187 |
+
|
| 188 |
+
foreach (@spliteedline) { $_ =~ s/\s+//g; }
|
| 189 |
+
|
| 190 |
+
addSGLine(\@spliteedline) if($spliteedline[0] eq "SG" );
|
| 191 |
+
addAlignments(\@spliteedline) if($spliteedline[0] eq "YES");
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
close(ALIGNFILE);
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
sub GetHTMLHeader
|
| 198 |
+
{
|
| 199 |
+
my ($ID) = @_;
|
| 200 |
+
|
| 201 |
+
my $out = "";
|
| 202 |
+
|
| 203 |
+
$out .= "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
|
| 204 |
+
$out .= "\n";
|
| 205 |
+
$out .= "<html>\n";
|
| 206 |
+
$out .= "<head>\n";
|
| 207 |
+
$out .= "<meta content=\"text/html; charset=utf-8\" http-equiv=\"content-type\">\n";
|
| 208 |
+
$out .= "<title>Segment Group ID $ID</title>\n";
|
| 209 |
+
$out .= "<script type=\"text/javascript\" src=\"js/wz_jsgraphics.js\"></script>\n";
|
| 210 |
+
$out .= "<script type=\"text/javascript\">\n";
|
| 211 |
+
$out .= "<!--\n";
|
| 212 |
+
$out .= "var jg;\n";
|
| 213 |
+
$out .= "var scale = 1;\n";
|
| 214 |
+
$out .= "\n";
|
| 215 |
+
$out .= "function Init()\n";
|
| 216 |
+
$out .= "{\n";
|
| 217 |
+
$out .= "jg = new jsGraphics(\"Graph\");\n";
|
| 218 |
+
$out .= "scale = 1;\n";
|
| 219 |
+
$out .= "}\n";
|
| 220 |
+
$out .= "\n";
|
| 221 |
+
$out .= "function myDraw()\n";
|
| 222 |
+
$out .= "{\n";
|
| 223 |
+
$out .= "jg.clear();\n";
|
| 224 |
+
|
| 225 |
+
return $out;
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
sub GetHTMLFooter
|
| 229 |
+
{
|
| 230 |
+
my ($end, $heigh, $warning, $SG) = @_;
|
| 231 |
+
|
| 232 |
+
my $out = "";
|
| 233 |
+
|
| 234 |
+
$out .= "jg.paint();\n";
|
| 235 |
+
$out .= "}\n";
|
| 236 |
+
$out .= "\n";
|
| 237 |
+
$out .= "//-->\n";
|
| 238 |
+
$out .= "</script>\n";
|
| 239 |
+
$out .= "</head>\n";
|
| 240 |
+
$out .= "\n";
|
| 241 |
+
$out .= "<body bgcolor=\"white\" onload=\"Init(); myDraw()\">\n";
|
| 242 |
+
$out .= "\n";
|
| 243 |
+
$out .= sprintf("<div id=\"Graph\" style=\"background-color:white;height:%dpx;width:%dpx;border-style:solid;border-width:0;position:relative;top:0;left:0;\"></div>\n", $heigh, $end);
|
| 244 |
+
$out .= "\n";
|
| 245 |
+
$out .= "<font face=\"courier\">\n";
|
| 246 |
+
$out .= "<a href=\"#\" onclick=\"scale -= 0.5; myDraw(); return false\">[-5]</a>\n";
|
| 247 |
+
$out .= "<a href=\"#\" onclick=\"scale -= 0.1; myDraw(); return false\">[-]</a>\n";
|
| 248 |
+
$out .= "<a href=\"#\" onclick=\"scale = 1; myDraw(); return false\">[Reset]</a>\n";
|
| 249 |
+
$out .= "<a href=\"#\" onclick=\"scale += 0.1; myDraw(); return false\">[+]</a>\n";
|
| 250 |
+
$out .= "<a href=\"#\" onclick=\"scale += 0.5; myDraw(); return false\">[+5]</a>\n";
|
| 251 |
+
|
| 252 |
+
|
| 253 |
+
|
| 254 |
+
$out .= "</font>\n";
|
| 255 |
+
$out .= PrintMapping($SG);
|
| 256 |
+
$out .= PrintWarning() if($warning == 1);
|
| 257 |
+
$out .= "</body>\n";
|
| 258 |
+
$out .= "</html>\n";
|
| 259 |
+
|
| 260 |
+
return $out;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
sub CalculateMaxScale
|
| 264 |
+
{
|
| 265 |
+
my ($start, $end, $stepsec, $heigh) = @_;
|
| 266 |
+
my $beginxline = $pixelpersec*sprintf("%.0f", $start/$pixelpersec);
|
| 267 |
+
my $endxline = $pixelpersec*sprintf("%.0f", $end/$pixelpersec);
|
| 268 |
+
|
| 269 |
+
$beginxline -= $pixelpersec if( ($beginxline > $start) && ($beginxline > $pixelpersec) );
|
| 270 |
+
$endxline += $pixelpersec if($endxline < $end);
|
| 271 |
+
$maxscalewidth = $endxline - $start + $pixelpersec;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
sub GetDrawScale
|
| 275 |
+
{
|
| 276 |
+
my ($start, $end, $stepsec, $heigh) = @_;
|
| 277 |
+
|
| 278 |
+
my $output = "";
|
| 279 |
+
$output .= sprintf("jg.setColor(\"orange\");\n");
|
| 280 |
+
$output .= sprintf("jg.setStroke(Stroke.DOTTED);\n");
|
| 281 |
+
$output .= sprintf("jg.setFont(\"arial\",\"8px\",Font.BOLD);\n");
|
| 282 |
+
|
| 283 |
+
my $beginxline = $pixelpersec*sprintf("%.0f", $start/$pixelpersec);
|
| 284 |
+
my $endxline = $pixelpersec*sprintf("%.0f", $end/$pixelpersec);
|
| 285 |
+
|
| 286 |
+
$beginxline -= $pixelpersec if( ($beginxline > $start) && ($beginxline > $pixelpersec) );
|
| 287 |
+
$endxline += $pixelpersec if($endxline < $end);
|
| 288 |
+
|
| 289 |
+
for(my $i=$beginxline; $i<=$endxline; $ i += $stepsec*$pixelpersec)
|
| 290 |
+
{
|
| 291 |
+
$output .= sprintf("jg.drawLine(scale*%.0f, 0, scale*%.0f, %.0f);\n", $i - $start + $pixelpersec, $i - $start + $pixelpersec, $heigh);
|
| 292 |
+
$output .= sprintf("jg.drawStringRect(\"%s\", scale*%.1f - 9, %.0f + 2, 20, \"center\");\n", $i/$pixelpersec, $i - $start + $pixelpersec, $heigh);
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
return $output;
|
| 296 |
+
}
|
| 297 |
+
|
| 298 |
+
sub LinkToken
|
| 299 |
+
{
|
| 300 |
+
my ($tkn1x, $tkn1y, $tkn2x, $tkn2y, $decalx, $type) = @_;
|
| 301 |
+
|
| 302 |
+
my $color = "black";
|
| 303 |
+
$color = "blue" if($type eq "spkrerr");
|
| 304 |
+
$color = "red" if($type eq "sub");
|
| 305 |
+
$color = "green"if($type eq "corr");
|
| 306 |
+
|
| 307 |
+
my $out = "";
|
| 308 |
+
$out .= sprintf("jg.setColor(\"%s\");\n", $color);
|
| 309 |
+
$out .= sprintf("jg.setStroke(2);\n");
|
| 310 |
+
$out .= sprintf("jg.drawLine(%.0f*scale, %.0f, %.0f*scale, %.0f);\n", $tkn1x - $decalx, $tkn1y, $tkn2x - $decalx, $tkn2y);
|
| 311 |
+
|
| 312 |
+
return $out;
|
| 313 |
+
}
|
| 314 |
+
|
| 315 |
+
sub InsSubToken
|
| 316 |
+
{
|
| 317 |
+
my ($tknx, $tkny, $decalx, $type) = @_;
|
| 318 |
+
|
| 319 |
+
my $multi = 1;
|
| 320 |
+
$multi = -1 if($type eq "SYS");
|
| 321 |
+
|
| 322 |
+
my $color = "black";
|
| 323 |
+
|
| 324 |
+
my $out = "";
|
| 325 |
+
$out .= sprintf("jg.setColor(\"%s\");\n", $color);
|
| 326 |
+
$out .= sprintf("jg.setStroke(1);\n");
|
| 327 |
+
$out .= sprintf("jg.drawLine(%.0f*scale, %.0f, %.0f*scale, %.0f);\n", $tknx - $decalx, $tkny, $tknx - $decalx, $tkny + $multi*13);
|
| 328 |
+
$out .= sprintf("jg.drawLine(%.0f*scale - 8, %.0f, %.0f*scale + 8, %.0f);\n", $tknx - $decalx, $tkny + $multi*13 , $tknx - $decalx, $tkny + $multi*13);
|
| 329 |
+
$out .= sprintf("jg.drawLine(%.0f*scale - 5, %.0f, %.0f*scale + 5, %.0f);\n", $tknx - $decalx, $tkny + $multi*15 , $tknx - $decalx, $tkny + $multi*15);
|
| 330 |
+
$out .= sprintf("jg.drawLine(%.0f*scale - 2, %.0f, %.0f*scale + 2, %.0f);\n", $tknx - $decalx, $tkny + $multi*17 , $tknx - $decalx, $tkny + $multi*17);
|
| 331 |
+
|
| 332 |
+
return $out;
|
| 333 |
+
}
|
| 334 |
+
|
| 335 |
+
sub InsOptSubToken
|
| 336 |
+
{
|
| 337 |
+
my ($tknx, $tkny, $decalx, $type) = @_;
|
| 338 |
+
|
| 339 |
+
my $multi = 1;
|
| 340 |
+
$multi = -1 if($type eq "SYS");
|
| 341 |
+
|
| 342 |
+
my $color = "green";
|
| 343 |
+
|
| 344 |
+
my $out = "";
|
| 345 |
+
$out .= sprintf("jg.setColor(\"%s\");\n", $color);
|
| 346 |
+
$out .= sprintf("jg.setStroke(1);\n");
|
| 347 |
+
$out .= sprintf("jg.drawLine(%.0f*scale, %.0f, %.0f*scale, %.0f);\n", $tknx - $decalx, $tkny, $tknx - $decalx, $tkny + $multi*13);
|
| 348 |
+
$out .= sprintf("jg.drawLine(%.0f*scale - 8, %.0f, %.0f*scale + 8, %.0f);\n", $tknx - $decalx, $tkny + $multi*13 , $tknx - $decalx, $tkny + $multi*13);
|
| 349 |
+
$out .= sprintf("jg.drawLine(%.0f*scale - 5, %.0f, %.0f*scale + 5, %.0f);\n", $tknx - $decalx, $tkny + $multi*15 , $tknx - $decalx, $tkny + $multi*15);
|
| 350 |
+
$out .= sprintf("jg.drawLine(%.0f*scale - 2, %.0f, %.0f*scale + 2, %.0f);\n", $tknx - $decalx, $tkny + $multi*17 , $tknx - $decalx, $tkny + $multi*17);
|
| 351 |
+
|
| 352 |
+
return $out;
|
| 353 |
+
}
|
| 354 |
+
|
| 355 |
+
sub DrawLinkToken
|
| 356 |
+
{
|
| 357 |
+
my ($sg, $tknrefid, $tknhypid, $decalx, $type) = @_;
|
| 358 |
+
|
| 359 |
+
my $tknref;
|
| 360 |
+
my $tknhyp;
|
| 361 |
+
|
| 362 |
+
if($type eq "I")
|
| 363 |
+
{
|
| 364 |
+
$sg->{NINS}++;
|
| 365 |
+
$tknhyp = $sg->GetToken($tknhypid);
|
| 366 |
+
return InsSubToken($tknhyp->{XMIDPOS}, $tknhyp->{YPOS}, $sg->{MINX} - $pixelpersec, $tknhyp->{REFORSYS});
|
| 367 |
+
}
|
| 368 |
+
|
| 369 |
+
if($type eq "D")
|
| 370 |
+
{
|
| 371 |
+
$sg->{NDEL}++;
|
| 372 |
+
$sg->{NREF}++;
|
| 373 |
+
$tknref = $sg->GetToken($tknrefid);
|
| 374 |
+
return InsSubToken($tknref->{XMIDPOS}, $tknref->{YPOS}, $sg->{MINX} - $pixelpersec, $tknref->{REFORSYS});
|
| 375 |
+
}
|
| 376 |
+
|
| 377 |
+
if($type eq "C")
|
| 378 |
+
{
|
| 379 |
+
$sg->{NCORR}++;
|
| 380 |
+
$tknref = $sg->GetToken($tknrefid);
|
| 381 |
+
$tknhyp = $sg->GetToken($tknhypid);
|
| 382 |
+
|
| 383 |
+
my $refdef = 0;
|
| 384 |
+
$refdef = 1 if($tknrefid ne "");
|
| 385 |
+
|
| 386 |
+
my $hypdef = 0;
|
| 387 |
+
$hypdef = 1 if($tknhypid ne "");
|
| 388 |
+
|
| 389 |
+
$sg->{NREF}++ if($refdef);
|
| 390 |
+
|
| 391 |
+
return LinkToken($tknref->{XMIDPOS}, $tknref->{YPOS}, $tknhyp->{XMIDPOS}, $tknhyp->{YPOS}, $sg->{MINX} - $pixelpersec, "corr") if($refdef && $hypdef);
|
| 392 |
+
return InsOptSubToken($tknref->{XMIDPOS}, $tknref->{YPOS}, $sg->{MINX} - $pixelpersec, $tknref->{REFORSYS}) if($refdef && !$hypdef);
|
| 393 |
+
return InsOptSubToken($tknhyp->{XMIDPOS}, $tknhyp->{YPOS}, $sg->{MINX} - $pixelpersec, $tknhyp->{REFORSYS}) if(!$refdef && $hypdef);
|
| 394 |
+
}
|
| 395 |
+
|
| 396 |
+
if($type eq "S")
|
| 397 |
+
{
|
| 398 |
+
$sg->{NSUB}++;
|
| 399 |
+
$sg->{NREF}++;
|
| 400 |
+
$tknref = $sg->GetToken($tknrefid);
|
| 401 |
+
$tknhyp = $sg->GetToken($tknhypid);
|
| 402 |
+
return LinkToken($tknref->{XMIDPOS}, $tknref->{YPOS}, $tknhyp->{XMIDPOS}, $tknhyp->{YPOS}, $sg->{MINX} - $pixelpersec, "sub");
|
| 403 |
+
}
|
| 404 |
+
|
| 405 |
+
if($type eq "P")
|
| 406 |
+
{
|
| 407 |
+
$sg->{NSPKRERR}++;
|
| 408 |
+
$sg->{NREF}++;
|
| 409 |
+
$tknref = $sg->GetToken($tknrefid);
|
| 410 |
+
$tknhyp = $sg->GetToken($tknhypid);
|
| 411 |
+
return LinkToken($tknref->{XMIDPOS}, $tknref->{YPOS}, $tknhyp->{XMIDPOS}, $tknhyp->{YPOS}, $sg->{MINX} - $pixelpersec, "spkrerr");
|
| 412 |
+
}
|
| 413 |
+
|
| 414 |
+
die "Unknown type $type";
|
| 415 |
+
}
|
| 416 |
+
|
| 417 |
+
sub PrintWarning
|
| 418 |
+
{
|
| 419 |
+
return "<p>WARNING: Some words do not have times specified for them. For these cases, word times <img src='images/white_lt.gif' border='0' /> are estimated from the segment times.</p>\n";
|
| 420 |
+
}
|
| 421 |
+
|
| 422 |
+
sub PrintMapping
|
| 423 |
+
{
|
| 424 |
+
my($SG) = @_;
|
| 425 |
+
my $out = "";
|
| 426 |
+
my @listmapping;
|
| 427 |
+
|
| 428 |
+
if($MapFile ne "")
|
| 429 |
+
{
|
| 430 |
+
$out .= "<br><br>MAPPING:<br>\n";
|
| 431 |
+
|
| 432 |
+
open(MAPFILE, $MapFile) or die "$?";
|
| 433 |
+
|
| 434 |
+
while (<MAPFILE>)
|
| 435 |
+
{
|
| 436 |
+
chomp;
|
| 437 |
+
next if($_ =~ /^File,Channel,RefSpeaker,SysSpeaker,isMapped,timeOverlap$/);
|
| 438 |
+
|
| 439 |
+
my @info = split(/,/, $_);
|
| 440 |
+
|
| 441 |
+
if($info[4] eq "mapped")
|
| 442 |
+
{
|
| 443 |
+
my $tmp1 = "ref:" . uc($info[2]);
|
| 444 |
+
my $tmp2 = "hyp:" . uc($info[3]);
|
| 445 |
+
|
| 446 |
+
if($SG->isInSpeakers($tmp1) == 1 && $SG->isInSpeakers($tmp2) == 1)
|
| 447 |
+
{
|
| 448 |
+
$tmp1 =~ s/^ref://;
|
| 449 |
+
$tmp1 =~ s/^hyp://;
|
| 450 |
+
$tmp2 =~ s/^ref://;
|
| 451 |
+
$tmp2 =~ s/^hyp://;
|
| 452 |
+
push(@listmapping, "$tmp1 <=> $tmp2<br>\n");
|
| 453 |
+
}
|
| 454 |
+
}
|
| 455 |
+
}
|
| 456 |
+
|
| 457 |
+
close MAPFILE;
|
| 458 |
+
|
| 459 |
+
my @listsorted = sort(@listmapping);
|
| 460 |
+
|
| 461 |
+
foreach my $mapp (@listsorted)
|
| 462 |
+
{
|
| 463 |
+
$out .= "$mapp\n";
|
| 464 |
+
}
|
| 465 |
+
}
|
| 466 |
+
|
| 467 |
+
return $out;
|
| 468 |
+
}
|
| 469 |
+
|
| 470 |
+
sub DrawKey
|
| 471 |
+
{
|
| 472 |
+
my ($ystart) = @_;
|
| 473 |
+
|
| 474 |
+
my $ystartpos = $ystart;
|
| 475 |
+
|
| 476 |
+
my $out = "";
|
| 477 |
+
$out .= sprintf("jg.setFont(\"verdana\",\"12px\",Font.PLAIN);\n");
|
| 478 |
+
$out .= sprintf("jg.setStroke(1);\n");
|
| 479 |
+
|
| 480 |
+
$out .= sprintf("jg.setColor(\"black\");\n");
|
| 481 |
+
$out .= sprintf("jg.drawLine(%.0f, %.0f, %.0f, %.0f);\n" , 15, $ystartpos , 15, $ystartpos + 13);
|
| 482 |
+
$out .= sprintf("jg.drawLine(%.0f - 8, %.0f, %.0f + 8, %.0f);\n", 15, $ystartpos + 13 , 15, $ystartpos + 13);
|
| 483 |
+
$out .= sprintf("jg.drawLine(%.0f - 5, %.0f, %.0f + 5, %.0f);\n", 15, $ystartpos + 15 , 15, $ystartpos + 15);
|
| 484 |
+
$out .= sprintf("jg.drawLine(%.0f - 2, %.0f, %.0f + 2, %.0f);\n", 15, $ystartpos + 17 , 15, $ystartpos + 17);
|
| 485 |
+
$out .= sprintf("jg.drawStringRect(\"%s\", %.0f, %.0f, 100, \"left\");\n", "Deletion", 50, $ystartpos + 4);
|
| 486 |
+
|
| 487 |
+
$out .= sprintf("jg.setColor(\"green\");\n");
|
| 488 |
+
$out .= sprintf("jg.drawLine(%.0f, %.0f, %.0f, %.0f);\n" , 215, $ystartpos , 215, $ystartpos + 13);
|
| 489 |
+
$out .= sprintf("jg.drawLine(%.0f - 8, %.0f, %.0f + 8, %.0f);\n", 215, $ystartpos + 13 , 215, $ystartpos + 13);
|
| 490 |
+
$out .= sprintf("jg.drawLine(%.0f - 5, %.0f, %.0f + 5, %.0f);\n", 215, $ystartpos + 15 , 215, $ystartpos + 15);
|
| 491 |
+
$out .= sprintf("jg.drawLine(%.0f - 2, %.0f, %.0f + 2, %.0f);\n", 215, $ystartpos + 17 , 215, $ystartpos + 17);
|
| 492 |
+
$out .= sprintf("jg.drawStringRect(\"%s\", %.0f, %.0f, 200, \"left\");\n", "Optionally Deletable", 250, $ystartpos + 4);
|
| 493 |
+
|
| 494 |
+
$ystartpos += 50;
|
| 495 |
+
|
| 496 |
+
$out .= sprintf("jg.setColor(\"black\");\n");
|
| 497 |
+
$out .= sprintf("jg.drawLine(%.0f, %.0f, %.0f, %.0f);\n" , 15, $ystartpos , 15, $ystartpos - 13);
|
| 498 |
+
$out .= sprintf("jg.drawLine(%.0f - 8, %.0f, %.0f + 8, %.0f);\n", 15, $ystartpos - 13 , 15, $ystartpos - 13);
|
| 499 |
+
$out .= sprintf("jg.drawLine(%.0f - 5, %.0f, %.0f + 5, %.0f);\n", 15, $ystartpos - 15 , 15, $ystartpos - 15);
|
| 500 |
+
$out .= sprintf("jg.drawLine(%.0f - 2, %.0f, %.0f + 2, %.0f);\n", 15, $ystartpos - 17 , 15, $ystartpos - 17);
|
| 501 |
+
$out .= sprintf("jg.drawStringRect(\"%s\", %.0f, %.0f, 100, \"left\");\n", "Insertion", 50, $ystartpos - 17);
|
| 502 |
+
|
| 503 |
+
$out .= sprintf("jg.setColor(\"green\");\n");
|
| 504 |
+
$out .= sprintf("jg.drawLine(%.0f, %.0f, %.0f, %.0f);\n" , 215, $ystartpos , 215, $ystartpos - 13);
|
| 505 |
+
$out .= sprintf("jg.drawLine(%.0f - 8, %.0f, %.0f + 8, %.0f);\n", 215, $ystartpos - 13 , 215, $ystartpos - 13);
|
| 506 |
+
$out .= sprintf("jg.drawLine(%.0f - 5, %.0f, %.0f + 5, %.0f);\n", 215, $ystartpos - 15 , 215, $ystartpos - 15);
|
| 507 |
+
$out .= sprintf("jg.drawLine(%.0f - 2, %.0f, %.0f + 2, %.0f);\n", 215, $ystartpos - 17 , 215, $ystartpos - 17);
|
| 508 |
+
$out .= sprintf("jg.drawStringRect(\"%s\", %.0f, %.0f, 200, \"left\");\n", "Optionally Insertable", 250, $ystartpos - 17);
|
| 509 |
+
|
| 510 |
+
$ystartpos += 15;
|
| 511 |
+
|
| 512 |
+
$out .= sprintf("jg.setStroke(2);\n");
|
| 513 |
+
|
| 514 |
+
$out .= sprintf("jg.setColor(\"green\");\n");
|
| 515 |
+
$out .= sprintf("jg.drawLine(%.0f, %.0f, %.0f, %.0f);\n" , 205, $ystartpos , 225, $ystartpos);
|
| 516 |
+
$out .= sprintf("jg.drawStringRect(\"%s\", %.0f, %.0f, 100, \"left\");\n", "Correct", 250, $ystartpos - 7);
|
| 517 |
+
|
| 518 |
+
$out .= sprintf("jg.setColor(\"red\");\n");
|
| 519 |
+
$out .= sprintf("jg.drawLine(%.0f, %.0f, %.0f, %.0f);\n" , 5, $ystartpos , 25, $ystartpos);
|
| 520 |
+
$out .= sprintf("jg.drawStringRect(\"%s\", %.0f, %.0f, 100, \"left\");\n", "Substitution", 50, $ystartpos - 7);
|
| 521 |
+
|
| 522 |
+
$ystartpos += 25;
|
| 523 |
+
|
| 524 |
+
$out .= sprintf("jg.setColor(\"blue\");\n");
|
| 525 |
+
$out .= sprintf("jg.drawLine(%.0f, %.0f, %.0f, %.0f);\n" , 5, $ystartpos , 25, $ystartpos);
|
| 526 |
+
$out .= sprintf("jg.drawStringRect(\"%s\", %.0f, %.0f, 100, \"left\");\n", "Speaker error", 50, $ystartpos - 7);
|
| 527 |
+
|
| 528 |
+
$out .= sprintf("jg.setStroke(1);\n");
|
| 529 |
+
$out .= sprintf("jg.setColor(\"brown\");\n");
|
| 530 |
+
$out .= sprintf("jg.drawLine(%.0f, %.0f, %.0f, %.0f);\n" , 205, $ystartpos , 225, $ystartpos);
|
| 531 |
+
$out .= sprintf("jg.drawLine(%.0f, %.0f, %.0f, %.0f);\n" , 205, $ystartpos -4 , 205, $ystartpos + 4);
|
| 532 |
+
$out .= sprintf("jg.drawLine(%.0f, %.0f, %.0f, %.0f);\n" , 225, $ystartpos -4 , 225, $ystartpos + 4);
|
| 533 |
+
$out .= sprintf("jg.drawStringRect(\"%s\", %.0f, %.0f, 100, \"left\");\n", "Empty Segment", 250, $ystartpos - 7);
|
| 534 |
+
|
| 535 |
+
$ystartpos += 25;
|
| 536 |
+
|
| 537 |
+
$out .= sprintf("jg.setColor(\"#eeffee\");\n");
|
| 538 |
+
$out .= sprintf("jg.fillRect(%.0f, %.0f, %.0f, %.0f);\n", 5, $ystartpos - 3 , 25, 8);
|
| 539 |
+
$out .= sprintf("jg.setColor(\"green\");\n");
|
| 540 |
+
$out .= sprintf("jg.drawStringRect(\"%s\", %.0f, %.0f, 100, \"left\");\n", "References", 50, $ystartpos - 7);
|
| 541 |
+
|
| 542 |
+
$ystartpos += 25;
|
| 543 |
+
|
| 544 |
+
$out .= sprintf("jg.setColor(\"#ffeeee\");\n");
|
| 545 |
+
$out .= sprintf("jg.fillRect(%.0f, %.0f, %.0f, %.0f);\n", 5, $ystartpos - 3 , 25, 8);
|
| 546 |
+
$out .= sprintf("jg.setColor(\"red\");\n");
|
| 547 |
+
$out .= sprintf("jg.drawStringRect(\"%s\", %.0f, %.0f, 100, \"left\");\n", "Systems", 50, $ystartpos - 7);
|
| 548 |
+
|
| 549 |
+
return $out;
|
| 550 |
+
}
|
| 551 |
+
|
| 552 |
+
GetOptions
|
| 553 |
+
(
|
| 554 |
+
'alignfile=s' => \$AlignFile,
|
| 555 |
+
'mapfile=s' => \$MapFile,
|
| 556 |
+
'outputdir=s' => \$Outputdir,
|
| 557 |
+
'version' => sub { print "align2html version: $VERSION\n"; exit },
|
| 558 |
+
'help' => sub { usage (); exit },
|
| 559 |
+
);
|
| 560 |
+
|
| 561 |
+
die "ERROR: An Align file must be set." if($AlignFile eq "");
|
| 562 |
+
die "ERROR: An Output directory must be set." if($Outputdir eq "");
|
| 563 |
+
|
| 564 |
+
system("mkdir -p $Outputdir");
|
| 565 |
+
|
| 566 |
+
loadAlignFile($AlignFile);
|
| 567 |
+
|
| 568 |
+
foreach my $SegGrpID ( sort keys %SegGroups )
|
| 569 |
+
{
|
| 570 |
+
my $out = "";
|
| 571 |
+
my $outputfilename = "segmentgroup-$SegGrpID.html";
|
| 572 |
+
my $mySG = $SegGroups{$SegGrpID};
|
| 573 |
+
|
| 574 |
+
$mySG->Compute();
|
| 575 |
+
|
| 576 |
+
$out .= GetHTMLHeader($SegGrpID);
|
| 577 |
+
CalculateMaxScale($mySG->{MINX}, $mySG->{MAXX}, 1, $mySG->{HEIGHT});
|
| 578 |
+
$out .= $mySG->GetFillREFHYP($maxscalewidth);
|
| 579 |
+
$out .= GetDrawScale($mySG->{MINX}, $mySG->{MAXX}, 1, $mySG->{HEIGHT});
|
| 580 |
+
$out .= $mySG->GetSeparationLines($maxscalewidth);
|
| 581 |
+
$out .= $mySG->GetDraw($pixelpersec);
|
| 582 |
+
|
| 583 |
+
foreach (@{ $Alignments{$SegGrpID} })
|
| 584 |
+
{
|
| 585 |
+
my $typ = $_->[0];
|
| 586 |
+
my $tknrefid = $_->[1];
|
| 587 |
+
my $tknhypid = $_->[2];
|
| 588 |
+
|
| 589 |
+
$out .= DrawLinkToken($mySG, $tknrefid, $tknhypid, $mySG->{MINX} - $pixelpersec, $typ);
|
| 590 |
+
}
|
| 591 |
+
|
| 592 |
+
$out .= DrawKey($mySG->{HEIGHT} + 25);
|
| 593 |
+
|
| 594 |
+
$out .= GetHTMLFooter($mySG->{MAXX} - $mySG->{MINX} + $pixelpersec, $mySG->{HEIGHT} + 185, $mySG->{HASFAKETIME}, $mySG);
|
| 595 |
+
|
| 596 |
+
open(FILESG, ">$Outputdir/$outputfilename") or die "Can't open file $Outputdir/$outputfilename for write";
|
| 597 |
+
print FILESG "$out\n";
|
| 598 |
+
close FILESG;
|
| 599 |
+
|
| 600 |
+
my @refspkrs;
|
| 601 |
+
foreach my $segref (sort keys %{ $mySG->{REF} }){ push(@refspkrs, $mySG->{REF}{$segref}->{SPKRID}) if($mySG->{REF}{$segref}->{SPKRID} ne "ref:INTER_SEGMENT_GAP"); }
|
| 602 |
+
my $countSpeakers = scalar unique @refspkrs;
|
| 603 |
+
|
| 604 |
+
my @sysspkrs;
|
| 605 |
+
foreach my $segsys (sort keys %{ $mySG->{SYS} }){ push(@refspkrs, $mySG->{SYS}{$segsys}->{SPKRID}) if(!($mySG->{SYS}{$segsys}->HasOnlyOneFakeToken())); }
|
| 606 |
+
my $counthypSpeakers = scalar unique @sysspkrs;
|
| 607 |
+
|
| 608 |
+
$mySG->{ALIGNED} = 1 if( ($countSpeakers == 0) && ($counthypSpeakers == 0) );
|
| 609 |
+
$mySG->{ALIGNED} = 1 if( ($mySG->{ALIGNED} == 0) && ($countSpeakers == 1) && ($counthypSpeakers == 0) && ($mySG->{HASFAKETIME} == 1) );
|
| 610 |
+
|
| 611 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NCORR} = 0 if(!exists($FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NCORR}));
|
| 612 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NINS} = 0 if(!exists($FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NINS}));
|
| 613 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NSUB} = 0 if(!exists($FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NSUB}));
|
| 614 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NDEL} = 0 if(!exists($FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NDEL}));
|
| 615 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NREF} = 0 if(!exists($FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NREF}));
|
| 616 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NSPKRERR} = 0 if(!exists($FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NSPKRERR}));
|
| 617 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{TOTTIME} = 0 if(!exists($FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{TOTTIME}));
|
| 618 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{TOTTIMEALIGNED} = 0 if(!exists($FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{TOTTIMEALIGNED}));
|
| 619 |
+
|
| 620 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NCORR} += $mySG->{NCORR};
|
| 621 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NINS} += $mySG->{NINS};
|
| 622 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NSUB} += $mySG->{NSUB};
|
| 623 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NDEL} += $mySG->{NDEL};
|
| 624 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NREF} += $mySG->{NREF};
|
| 625 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{NSPKRERR} += $mySG->{NSPKRERR};
|
| 626 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{TOTTIME} += $mySG->{ET} - $mySG->{BT};
|
| 627 |
+
push( @{ $FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{LISTSG} }, $SegGrpID);
|
| 628 |
+
push( @{ $FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{LISTSGALIGNED} }, $SegGrpID) if($mySG->{ALIGNED} == 1);
|
| 629 |
+
$FileChannelSG{$mySG->{FILE}}{$mySG->{CHANNEL}}{TOTTIMEALIGNED} += $mySG->{ET} - $mySG->{BT} if($mySG->{ALIGNED} == 1);
|
| 630 |
+
|
| 631 |
+
$Overlap{$countSpeakers}{NREF} = 0 if(!exists($Overlap{$countSpeakers}{NREF}));
|
| 632 |
+
$Overlap{$countSpeakers}{NREF} += $mySG->{NREF};
|
| 633 |
+
|
| 634 |
+
$Overlap{$countSpeakers}{NCORR} = 0 if(!exists($Overlap{$countSpeakers}{NCORR}));
|
| 635 |
+
$Overlap{$countSpeakers}{NCORR} += $mySG->{NCORR};
|
| 636 |
+
$Overlap{$countSpeakers}{PCORR} = "NA";
|
| 637 |
+
$Overlap{$countSpeakers}{PCORR} = sprintf("%.1f", 100*$Overlap{$countSpeakers}{NCORR}/$Overlap{$countSpeakers}{NREF}) if($Overlap{$countSpeakers}{NREF} != 0);
|
| 638 |
+
|
| 639 |
+
$Overlap{$countSpeakers}{NSUB} = 0 if(!exists($Overlap{$countSpeakers}{NSUB}));
|
| 640 |
+
$Overlap{$countSpeakers}{NSUB} += $mySG->{NSUB};
|
| 641 |
+
$Overlap{$countSpeakers}{PSUB} = "NA";
|
| 642 |
+
$Overlap{$countSpeakers}{PSUB} = sprintf("%.1f", 100*$Overlap{$countSpeakers}{NSUB}/$Overlap{$countSpeakers}{NREF}) if($Overlap{$countSpeakers}{NREF} != 0);
|
| 643 |
+
|
| 644 |
+
$Overlap{$countSpeakers}{NINS} = 0 if(!exists($Overlap{$countSpeakers}{NINS}));
|
| 645 |
+
$Overlap{$countSpeakers}{NINS} += $mySG->{NINS};
|
| 646 |
+
$Overlap{$countSpeakers}{PINS} = "NA";
|
| 647 |
+
$Overlap{$countSpeakers}{PINS} = sprintf("%.1f", 100*$Overlap{$countSpeakers}{NINS}/$Overlap{$countSpeakers}{NREF}) if($Overlap{$countSpeakers}{NREF} != 0);
|
| 648 |
+
|
| 649 |
+
$Overlap{$countSpeakers}{NDEL} = 0 if(!exists($Overlap{$countSpeakers}{NDEL}));
|
| 650 |
+
$Overlap{$countSpeakers}{NDEL} += $mySG->{NDEL};
|
| 651 |
+
$Overlap{$countSpeakers}{PDEL} = "NA";
|
| 652 |
+
$Overlap{$countSpeakers}{PDEL} = sprintf("%.1f", 100*$Overlap{$countSpeakers}{NDEL}/$Overlap{$countSpeakers}{NREF}) if($Overlap{$countSpeakers}{NREF} != 0);
|
| 653 |
+
|
| 654 |
+
$Overlap{$countSpeakers}{NSPKRERR} = 0 if(!exists($Overlap{$countSpeakers}{NSPKRERR}));
|
| 655 |
+
$Overlap{$countSpeakers}{NSPKRERR} += $mySG->{NSPKRERR};
|
| 656 |
+
$Overlap{$countSpeakers}{PSPKRERR} = "NA";
|
| 657 |
+
$Overlap{$countSpeakers}{PSPKRERR} = sprintf("%.1f", 100*$Overlap{$countSpeakers}{NSPKRERR}/$Overlap{$countSpeakers}{NREF}) if($Overlap{$countSpeakers}{NREF} != 0);
|
| 658 |
+
|
| 659 |
+
$Overlap{$countSpeakers}{NERR} = $Overlap{$countSpeakers}{NSUB} + $Overlap{$countSpeakers}{NINS} + $Overlap{$countSpeakers}{NDEL} + $Overlap{$countSpeakers}{NSPKRERR};
|
| 660 |
+
$Overlap{$countSpeakers}{PERR} = "NA";
|
| 661 |
+
$Overlap{$countSpeakers}{PERR} = sprintf("%.1f", 100*$Overlap{$countSpeakers}{NERR}/$Overlap{$countSpeakers}{NREF}) if($Overlap{$countSpeakers}{NREF} != 0);
|
| 662 |
+
|
| 663 |
+
$Overlap{$countSpeakers}{TOTTIME} = 0 if(!exists($Overlap{$countSpeakers}{TOTTIME}));
|
| 664 |
+
$Overlap{$countSpeakers}{TOTTIME} += $mySG->{ET} - $mySG->{BT};
|
| 665 |
+
|
| 666 |
+
push( @{ $Overlap{$countSpeakers}{LISTSG} }, $SegGrpID);
|
| 667 |
+
$Overlap{$countSpeakers}{NLISTSG} = scalar @{ $Overlap{$countSpeakers}{LISTSG} };
|
| 668 |
+
|
| 669 |
+
$Overlap{$countSpeakers}{TOTTIMEALIGNED} = 0 if(!exists($Overlap{$countSpeakers}{TOTTIMEALIGNED}));
|
| 670 |
+
$Overlap{$countSpeakers}{TOTTIMEALIGNED} += $mySG->{ET} - $mySG->{BT} if($mySG->{ALIGNED} == 1);
|
| 671 |
+
|
| 672 |
+
push( @{ $Overlap{$countSpeakers}{LISTSGALIGNED} }, $SegGrpID) if($mySG->{ALIGNED} == 1);
|
| 673 |
+
$Overlap{$countSpeakers}{NLISTSGALIGNED} = 0;
|
| 674 |
+
$Overlap{$countSpeakers}{NLISTSGALIGNED} = scalar(@{ $Overlap{$countSpeakers}{LISTSGALIGNED} }) if(exists($Overlap{$countSpeakers}{LISTSGALIGNED}));
|
| 675 |
+
|
| 676 |
+
$Overlap{$countSpeakers}{NUMHYPTOKENS} = 0 if(!exists($Overlap{$countSpeakers}{NUMHYPTOKENS}));
|
| 677 |
+
$Overlap{$countSpeakers}{NUMHYPTOKENS} += $SegGroups{$SegGrpID}->GetNumHypWords();
|
| 678 |
+
}
|
| 679 |
+
|
| 680 |
+
open(FILEINDEX, ">$Outputdir/index.html") or die "$?";
|
| 681 |
+
|
| 682 |
+
print FILEINDEX "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
|
| 683 |
+
print FILEINDEX "<html>\n";
|
| 684 |
+
print FILEINDEX "<head>\n";
|
| 685 |
+
print FILEINDEX "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=ISO-8859-1\">\n";
|
| 686 |
+
print FILEINDEX "<title>Overall Performance Summary by Meeting</title>\n";
|
| 687 |
+
print FILEINDEX "</head>\n";
|
| 688 |
+
print FILEINDEX "<body>\n";
|
| 689 |
+
print FILEINDEX "<center>\n";
|
| 690 |
+
print FILEINDEX "<h2>Overall Performance Summary by Meeting</h2>\n";
|
| 691 |
+
print FILEINDEX "<table style=\"text-align: left;\" border=\"1\" cellpadding=\"1\" cellspacing=\"0\">\n";
|
| 692 |
+
print FILEINDEX "<tbody>\n";
|
| 693 |
+
print FILEINDEX "<tr>\n";
|
| 694 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: left;\"><b>File\/Channel</b></td>\n";
|
| 695 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Regions</b></td>\n";
|
| 696 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Total<br>Time</b></td>\n";
|
| 697 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Regions<br>Aligned</b></td>\n";
|
| 698 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Total Time<br>Aligned</b></td>\n";
|
| 699 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Ref Aligned<br>Words</b></td>\n";
|
| 700 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Corr</b></td>\n";
|
| 701 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Sub</b></td>\n";
|
| 702 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Ins</b></td>\n";
|
| 703 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Del</b></td>\n";
|
| 704 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>SpErr</b></td>\n";
|
| 705 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Err</b></td>\n";
|
| 706 |
+
print FILEINDEX "</tr>\n";
|
| 707 |
+
|
| 708 |
+
my $TnbrSG = 0;
|
| 709 |
+
my $Ttottime = 0;
|
| 710 |
+
my $TnbrSGAligned = 0;
|
| 711 |
+
my $Ttottimealigned = 0;
|
| 712 |
+
my $Tnumref = 0;
|
| 713 |
+
my $TpercCorr = 0;
|
| 714 |
+
my $TpercSub = 0;
|
| 715 |
+
my $TpercIns = 0;
|
| 716 |
+
my $TpercDel = 0;
|
| 717 |
+
my $TpercSpErr = 0;
|
| 718 |
+
my $TpercErr = 0;
|
| 719 |
+
my $TnumCorr = 0;
|
| 720 |
+
my $TnumSub = 0;
|
| 721 |
+
my $TnumIns = 0;
|
| 722 |
+
my $TnumDel = 0;
|
| 723 |
+
my $TnumSpErr = 0;
|
| 724 |
+
my $TnumErr = 0;
|
| 725 |
+
|
| 726 |
+
my $ccount = 0;
|
| 727 |
+
|
| 728 |
+
foreach my $file(sort keys %FileChannelSG)
|
| 729 |
+
{
|
| 730 |
+
foreach my $channel(sort keys %{ $FileChannelSG{$file} })
|
| 731 |
+
{
|
| 732 |
+
my $cleanfile = $file;
|
| 733 |
+
$cleanfile =~ s/\//\_/g;
|
| 734 |
+
my $filename = "$cleanfile" . "_" . "$channel" . ".html";
|
| 735 |
+
|
| 736 |
+
my $percCorr = "NA";
|
| 737 |
+
my $percSub = "NA";
|
| 738 |
+
my $percIns = "NA";
|
| 739 |
+
my $percDel = "NA";
|
| 740 |
+
my $percErr = "NA";
|
| 741 |
+
my $percSpErr = "NA";
|
| 742 |
+
|
| 743 |
+
my $numref = $FileChannelSG{$file}{$channel}{NREF};
|
| 744 |
+
$Tnumref += $numref;
|
| 745 |
+
|
| 746 |
+
my $nbrSG = scalar(@{ $FileChannelSG{$file}{$channel}{LISTSG} });
|
| 747 |
+
$TnbrSG += $nbrSG;
|
| 748 |
+
|
| 749 |
+
my $tottime = sprintf("%.3f", $FileChannelSG{$file}{$channel}{TOTTIME});
|
| 750 |
+
$Ttottime += $tottime;
|
| 751 |
+
|
| 752 |
+
my $nbrSGAligned = scalar(@{ $FileChannelSG{$file}{$channel}{LISTSGALIGNED} });
|
| 753 |
+
$TnbrSGAligned += $nbrSGAligned;
|
| 754 |
+
|
| 755 |
+
my $tottimealigned = sprintf("%.3f", $FileChannelSG{$file}{$channel}{TOTTIMEALIGNED});
|
| 756 |
+
$Ttottimealigned += $tottimealigned;
|
| 757 |
+
|
| 758 |
+
if($FileChannelSG{$file}{$channel}{NREF} != 0)
|
| 759 |
+
{
|
| 760 |
+
$percCorr = sprintf("%.1f%% (%d)", 100*$FileChannelSG{$file}{$channel}{NCORR}/$FileChannelSG{$file}{$channel}{NREF}, $FileChannelSG{$file}{$channel}{NCORR});
|
| 761 |
+
$percSub = sprintf("%.1f%% (%d)", 100*$FileChannelSG{$file}{$channel}{NSUB}/$FileChannelSG{$file}{$channel}{NREF}, $FileChannelSG{$file}{$channel}{NSUB});
|
| 762 |
+
$percIns = sprintf("%.1f%% (%d)", 100*$FileChannelSG{$file}{$channel}{NINS}/$FileChannelSG{$file}{$channel}{NREF}, $FileChannelSG{$file}{$channel}{NINS});
|
| 763 |
+
$percDel = sprintf("%.1f%% (%d)", 100*$FileChannelSG{$file}{$channel}{NDEL}/$FileChannelSG{$file}{$channel}{NREF}, $FileChannelSG{$file}{$channel}{NDEL});
|
| 764 |
+
$percErr = sprintf("%.1f%% (%d)", 100*($FileChannelSG{$file}{$channel}{NDEL}+$FileChannelSG{$file}{$channel}{NINS}+$FileChannelSG{$file}{$channel}{NSUB}+$FileChannelSG{$file}{$channel}{NSPKRERR})/$FileChannelSG{$file}{$channel}{NREF}, $FileChannelSG{$file}{$channel}{NDEL}+$FileChannelSG{$file}{$channel}{NINS}+$FileChannelSG{$file}{$channel}{NSUB}+$FileChannelSG{$file}{$channel}{NSPKRERR});
|
| 765 |
+
$percSpErr = sprintf("%.1f%% (%d)", 100*$FileChannelSG{$file}{$channel}{NSPKRERR}/$FileChannelSG{$file}{$channel}{NREF}, $FileChannelSG{$file}{$channel}{NSPKRERR});
|
| 766 |
+
|
| 767 |
+
$TpercCorr += sprintf("%.3f", 100*$FileChannelSG{$file}{$channel}{NCORR}/$FileChannelSG{$file}{$channel}{NREF});
|
| 768 |
+
$TpercSub += sprintf("%.3f", 100*$FileChannelSG{$file}{$channel}{NSUB}/$FileChannelSG{$file}{$channel}{NREF});
|
| 769 |
+
$TpercIns += sprintf("%.3f", 100*$FileChannelSG{$file}{$channel}{NINS}/$FileChannelSG{$file}{$channel}{NREF});
|
| 770 |
+
$TpercDel += sprintf("%.3f", 100*$FileChannelSG{$file}{$channel}{NDEL}/$FileChannelSG{$file}{$channel}{NREF});
|
| 771 |
+
$TpercSpErr += sprintf("%.3f", 100*$FileChannelSG{$file}{$channel}{NSPKRERR}/$FileChannelSG{$file}{$channel}{NREF});
|
| 772 |
+
$TpercErr += sprintf("%.3f", 100*($FileChannelSG{$file}{$channel}{NDEL}+$FileChannelSG{$file}{$channel}{NINS}+$FileChannelSG{$file}{$channel}{NSUB}+$FileChannelSG{$file}{$channel}{NSPKRERR})/$FileChannelSG{$file}{$channel}{NREF});
|
| 773 |
+
$TnumCorr += $FileChannelSG{$file}{$channel}{NCORR};
|
| 774 |
+
$TnumSub += $FileChannelSG{$file}{$channel}{NSUB};
|
| 775 |
+
$TnumIns += $FileChannelSG{$file}{$channel}{NINS};
|
| 776 |
+
$TnumDel += $FileChannelSG{$file}{$channel}{NDEL};
|
| 777 |
+
$TnumSpErr += $FileChannelSG{$file}{$channel}{NSPKRERR};
|
| 778 |
+
$TnumErr += $FileChannelSG{$file}{$channel}{NDEL}+$FileChannelSG{$file}{$channel}{NINS}+$FileChannelSG{$file}{$channel}{NSUB}+$FileChannelSG{$file}{$channel}{NSPKRERR};
|
| 779 |
+
|
| 780 |
+
$ccount++;
|
| 781 |
+
}
|
| 782 |
+
|
| 783 |
+
print FILEINDEX "<tr>\n";
|
| 784 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: left;\"><a href=\"$filename\" target=\"_blank\">$file\/$channel</a></td>\n";
|
| 785 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$nbrSG</td>\n";
|
| 786 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$tottime</td>\n";
|
| 787 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$nbrSGAligned</td>\n";
|
| 788 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$tottimealigned</td>\n";
|
| 789 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$numref</td>\n";
|
| 790 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$percCorr</td>\n";
|
| 791 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$percSub</td>\n";
|
| 792 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$percIns</td>\n";
|
| 793 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$percDel</td>\n";
|
| 794 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$percSpErr</td>\n";
|
| 795 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$percErr</td>\n";
|
| 796 |
+
print FILEINDEX "</tr>\n";
|
| 797 |
+
}
|
| 798 |
+
}
|
| 799 |
+
|
| 800 |
+
my $dTpercCorr = sprintf("%.1f%% (%d)", 100*$TnumCorr/$Tnumref, $TnumCorr);
|
| 801 |
+
my $dTpercSub = sprintf("%.1f%% (%d)", 100*$TnumSub/$Tnumref, $TnumSub);
|
| 802 |
+
my $dTpercIns = sprintf("%.1f%% (%d)", 100*$TnumIns/$Tnumref, $TnumIns);
|
| 803 |
+
my $dTpercDel = sprintf("%.1f%% (%d)", 100*$TnumDel/$Tnumref, $TnumDel);
|
| 804 |
+
my $dTpercSpErr = sprintf("%.1f%% (%d)", 100*$TnumSpErr/$Tnumref, $TnumSpErr);
|
| 805 |
+
my $dTpercErr = sprintf("%.1f%% (%d)", 100*$TnumErr/$Tnumref, $TnumErr);
|
| 806 |
+
|
| 807 |
+
print FILEINDEX "<tr>\n";
|
| 808 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: left;\"><b>Ensemble</b></td>\n";
|
| 809 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$TnbrSG</td>\n";
|
| 810 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$Ttottime</td>\n";
|
| 811 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$TnbrSGAligned</td>\n";
|
| 812 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$Ttottimealigned</td>\n";
|
| 813 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$Tnumref</td>\n";
|
| 814 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$dTpercCorr</td>\n";
|
| 815 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$dTpercSub</td>\n";
|
| 816 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$dTpercIns</td>\n";
|
| 817 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$dTpercDel</td>\n";
|
| 818 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$dTpercSpErr</td>\n";
|
| 819 |
+
print FILEINDEX "<td style=\"vertical-align: top; text-align: center;\">$dTpercErr</td>\n";
|
| 820 |
+
print FILEINDEX "</tr>\n";
|
| 821 |
+
print FILEINDEX "</tbody>\n";
|
| 822 |
+
print FILEINDEX "</table>\n";
|
| 823 |
+
|
| 824 |
+
print FILEINDEX "<br>\n";
|
| 825 |
+
|
| 826 |
+
my $Total_regs = 0;
|
| 827 |
+
my $Total_tottime = 0;
|
| 828 |
+
my $Total_regsalign = 0;
|
| 829 |
+
my $Total_tottimealign = 0;
|
| 830 |
+
my $Total_nref = 0;
|
| 831 |
+
my $Total_ncorr = 0;
|
| 832 |
+
my $Total_nsub = 0;
|
| 833 |
+
my $Total_nins = 0;
|
| 834 |
+
my $Total_ndel = 0;
|
| 835 |
+
my $Total_nspkerr = 0;
|
| 836 |
+
my $Total_nerr = 0;
|
| 837 |
+
|
| 838 |
+
print FILEINDEX "<table style=\"text-align: left;\" border=\"1\" cellpadding=\"1\" cellspacing=\"0\">\n";
|
| 839 |
+
print FILEINDEX "<tbody>\n";
|
| 840 |
+
print FILEINDEX "<tr>\n";
|
| 841 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Ref Speaker<br>Overlap</b></td>\n";
|
| 842 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Regions</b></td>\n";
|
| 843 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Total<br>Time</b></td>\n";
|
| 844 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Regions<br>Aligned</b></td>\n";
|
| 845 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Total Time<br>Aligned</b></td>\n";
|
| 846 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Ref Aligned<br>Words</b></td>\n";
|
| 847 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Corr</b></td>\n";
|
| 848 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Sub</b></td>\n";
|
| 849 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Ins</b></td>\n";
|
| 850 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Del</b></td>\n";
|
| 851 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>SpErr</b></td>\n";
|
| 852 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Err</b></td>\n";
|
| 853 |
+
print FILEINDEX "</tr>\n";
|
| 854 |
+
|
| 855 |
+
foreach my $spkover (sort {$a <=> $b} keys %Overlap)
|
| 856 |
+
{
|
| 857 |
+
my $display_regs = $Overlap{$spkover}{NLISTSG};
|
| 858 |
+
my $display_tottime = sprintf("%.3f", $Overlap{$spkover}{TOTTIME});
|
| 859 |
+
my $display_regsalign = $Overlap{$spkover}{NLISTSGALIGNED};
|
| 860 |
+
my $display_tottimealign = sprintf("%.3f", $Overlap{$spkover}{TOTTIMEALIGNED});
|
| 861 |
+
my $display_nref = "-";
|
| 862 |
+
my $display_ncorr = "-";
|
| 863 |
+
my $display_nsub = "-";
|
| 864 |
+
my $display_nins = "-";
|
| 865 |
+
my $display_ndel = "-";
|
| 866 |
+
my $display_nspkerr = "-";
|
| 867 |
+
my $display_nerr = "-";
|
| 868 |
+
|
| 869 |
+
$Total_regs += $Overlap{$spkover}{NLISTSG};
|
| 870 |
+
$Total_tottime += $Overlap{$spkover}{TOTTIME};
|
| 871 |
+
$Total_regsalign += $Overlap{$spkover}{NLISTSGALIGNED};
|
| 872 |
+
$Total_tottimealign += $Overlap{$spkover}{TOTTIMEALIGNED};
|
| 873 |
+
|
| 874 |
+
if($spkover == 0)
|
| 875 |
+
{
|
| 876 |
+
$display_nins = sprintf("(%d)", $Overlap{$spkover}{NUMHYPTOKENS});
|
| 877 |
+
|
| 878 |
+
$Total_nins += $Overlap{$spkover}{NUMHYPTOKENS};
|
| 879 |
+
$Total_nerr += $Total_nins;
|
| 880 |
+
}
|
| 881 |
+
|
| 882 |
+
if($Overlap{$spkover}{NREF} != 0)
|
| 883 |
+
{
|
| 884 |
+
$display_nref = $Overlap{$spkover}{NREF};
|
| 885 |
+
$display_ncorr = sprintf("%.1f%% (%d)", $Overlap{$spkover}{PCORR}, $Overlap{$spkover}{NCORR});
|
| 886 |
+
$display_nsub = sprintf("%.1f%% (%d)", $Overlap{$spkover}{PSUB}, $Overlap{$spkover}{NSUB});
|
| 887 |
+
$display_nins = sprintf("%.1f%% (%d)", $Overlap{$spkover}{PINS}, $Overlap{$spkover}{NINS});
|
| 888 |
+
$display_ndel = sprintf("%.1f%% (%d)", $Overlap{$spkover}{PDEL}, $Overlap{$spkover}{NDEL});
|
| 889 |
+
$display_nspkerr = sprintf("%.1f%% (%d)", $Overlap{$spkover}{PSPKRERR}, $Overlap{$spkover}{NSPKRERR});
|
| 890 |
+
$display_nerr = sprintf("%.1f%% (%d)", $Overlap{$spkover}{PERR}, $Overlap{$spkover}{NERR});
|
| 891 |
+
|
| 892 |
+
$Total_nref += $Overlap{$spkover}{NREF};
|
| 893 |
+
$Total_ncorr += $Overlap{$spkover}{NCORR};
|
| 894 |
+
$Total_nsub += $Overlap{$spkover}{NSUB};
|
| 895 |
+
$Total_nins += $Overlap{$spkover}{NINS};
|
| 896 |
+
$Total_ndel += $Overlap{$spkover}{NDEL};
|
| 897 |
+
$Total_nspkerr += $Overlap{$spkover}{NSPKRERR};
|
| 898 |
+
$Total_nerr += $Overlap{$spkover}{NERR};
|
| 899 |
+
}
|
| 900 |
+
|
| 901 |
+
print FILEINDEX "<tr>\n";
|
| 902 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>$spkover<b></td>\n";
|
| 903 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_regs</td>\n";
|
| 904 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_tottime</td>\n";
|
| 905 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_regsalign</td>\n";
|
| 906 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_tottimealign</td>\n";
|
| 907 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nref</td>\n";
|
| 908 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_ncorr</td>\n";
|
| 909 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nsub</td>\n";
|
| 910 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nins</td>\n";
|
| 911 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_ndel</td>\n";
|
| 912 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nspkerr</td>\n";
|
| 913 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nerr</td>\n";
|
| 914 |
+
print FILEINDEX "</tr>\n";
|
| 915 |
+
|
| 916 |
+
# data for Cumuloverlap table
|
| 917 |
+
$CumulOverlap{$spkover}{NLISTSG} = $Total_regs;
|
| 918 |
+
$CumulOverlap{$spkover}{TOTTIME} = $Total_tottime;
|
| 919 |
+
$CumulOverlap{$spkover}{NLISTSGALIGNED} = $Total_regsalign;
|
| 920 |
+
$CumulOverlap{$spkover}{TOTTIMEALIGNED} = $Total_tottimealign;
|
| 921 |
+
$CumulOverlap{$spkover}{NREF} = $Total_nref;
|
| 922 |
+
$CumulOverlap{$spkover}{NCORR} = $Total_ncorr;
|
| 923 |
+
$CumulOverlap{$spkover}{NSUB} = $Total_nsub;
|
| 924 |
+
$CumulOverlap{$spkover}{NINS} = $Total_nins;
|
| 925 |
+
$CumulOverlap{$spkover}{NDEL} = $Total_ndel;
|
| 926 |
+
$CumulOverlap{$spkover}{NSPKRERR} = $Total_nspkerr;
|
| 927 |
+
$CumulOverlap{$spkover}{NERR} = $Total_nerr;
|
| 928 |
+
}
|
| 929 |
+
|
| 930 |
+
my $display_Total_regs = $Total_regs;
|
| 931 |
+
my $display_Total_tottime = sprintf("%.3f", $Total_tottime);
|
| 932 |
+
my $display_Total_regsalign = $Total_regsalign;
|
| 933 |
+
my $display_Total_tottimealign = sprintf("%.3f", $Total_tottimealign);
|
| 934 |
+
my $display_Total_nref = $Total_nref;
|
| 935 |
+
my $display_Total_ncorr = sprintf("%.1f%% (%d)", 100*$Total_ncorr/$Total_nref, $Total_ncorr);
|
| 936 |
+
my $display_Total_nsub = sprintf("%.1f%% (%d)", 100*$Total_nsub/$Total_nref, $Total_nsub);
|
| 937 |
+
my $display_Total_nins = sprintf("%.1f%% (%d)", 100*$Total_nins/$Total_nref, $Total_nins);
|
| 938 |
+
my $display_Total_ndel = sprintf("%.1f%% (%d)", 100*$Total_ndel/$Total_nref, $Total_ndel);
|
| 939 |
+
my $display_Total_nspkerr = sprintf("%.1f%% (%d)", 100*$Total_nspkerr/$Total_nref, $Total_nspkerr);
|
| 940 |
+
my $display_Total_nerr = sprintf("%.1f%% (%d)", 100*$Total_nerr/$Total_nref, $Total_nerr);
|
| 941 |
+
|
| 942 |
+
print FILEINDEX "<tr>\n";
|
| 943 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Ensemble</b></td>\n";
|
| 944 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_regs</td>\n";
|
| 945 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_tottime</td>\n";
|
| 946 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_regsalign</td>\n";
|
| 947 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_tottimealign</td>\n";
|
| 948 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_nref</td>\n";
|
| 949 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_ncorr</td>\n";
|
| 950 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_nsub</td>\n";
|
| 951 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_nins</td>\n";
|
| 952 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_ndel</td>\n";
|
| 953 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_nspkerr</td>\n";
|
| 954 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_nerr</td>\n";
|
| 955 |
+
print FILEINDEX "</tr>\n";
|
| 956 |
+
|
| 957 |
+
print FILEINDEX "</tbody>\n";
|
| 958 |
+
print FILEINDEX "</table>\n";
|
| 959 |
+
|
| 960 |
+
print FILEINDEX "<br>\n";
|
| 961 |
+
|
| 962 |
+
print FILEINDEX "<table style=\"text-align: left;\" border=\"1\" cellpadding=\"1\" cellspacing=\"0\">\n";
|
| 963 |
+
print FILEINDEX "<tbody>\n";
|
| 964 |
+
print FILEINDEX "<tr>\n";
|
| 965 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Ref Speaker<br>Cumulative<br>Overlap</b></td>\n";
|
| 966 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Regions</b></td>\n";
|
| 967 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Total<br>Time</b></td>\n";
|
| 968 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Regions<br>Aligned</b></td>\n";
|
| 969 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Total Time<br>Aligned</b></td>\n";
|
| 970 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Ref Aligned<br>Words</b></td>\n";
|
| 971 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Corr</b></td>\n";
|
| 972 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Sub</b></td>\n";
|
| 973 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Ins</b></td>\n";
|
| 974 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Del</b></td>\n";
|
| 975 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>SpErr</b></td>\n";
|
| 976 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Err</b></td>\n";
|
| 977 |
+
print FILEINDEX "</tr>\n";
|
| 978 |
+
|
| 979 |
+
foreach my $cumulspkover (sort {$a <=> $b} keys %CumulOverlap)
|
| 980 |
+
{
|
| 981 |
+
my $display_regs = $CumulOverlap{$cumulspkover}{NLISTSG};
|
| 982 |
+
my $display_tottime = sprintf("%.3f", $CumulOverlap{$cumulspkover}{TOTTIME});
|
| 983 |
+
my $display_regsalign = $CumulOverlap{$cumulspkover}{NLISTSGALIGNED};
|
| 984 |
+
my $display_tottimealign = sprintf("%.3f", $CumulOverlap{$cumulspkover}{TOTTIMEALIGNED});
|
| 985 |
+
my $display_nref = "-";
|
| 986 |
+
my $display_ncorr = "-";
|
| 987 |
+
my $display_nsub = "-";
|
| 988 |
+
my $display_nins = "-";
|
| 989 |
+
my $display_ndel = "-";
|
| 990 |
+
my $display_nspkerr = "-";
|
| 991 |
+
my $display_nerr = "-";
|
| 992 |
+
|
| 993 |
+
if($cumulspkover == 0)
|
| 994 |
+
{
|
| 995 |
+
$display_nins = sprintf("(%d)", $CumulOverlap{$cumulspkover}{NINS});
|
| 996 |
+
}
|
| 997 |
+
|
| 998 |
+
if($CumulOverlap{$cumulspkover}{NREF} != 0)
|
| 999 |
+
{
|
| 1000 |
+
$display_nref = $CumulOverlap{$cumulspkover}{NREF};
|
| 1001 |
+
$display_ncorr = sprintf("%.1f%% (%d)", $CumulOverlap{$cumulspkover}{NCORR} *100/$CumulOverlap{$cumulspkover}{NREF}, $CumulOverlap{$cumulspkover}{NCORR});
|
| 1002 |
+
$display_nsub = sprintf("%.1f%% (%d)", $CumulOverlap{$cumulspkover}{NSUB} *100/$CumulOverlap{$cumulspkover}{NREF}, $CumulOverlap{$cumulspkover}{NSUB});
|
| 1003 |
+
$display_nins = sprintf("%.1f%% (%d)", $CumulOverlap{$cumulspkover}{NINS} *100/$CumulOverlap{$cumulspkover}{NREF}, $CumulOverlap{$cumulspkover}{NINS});
|
| 1004 |
+
$display_ndel = sprintf("%.1f%% (%d)", $CumulOverlap{$cumulspkover}{NDEL} *100/$CumulOverlap{$cumulspkover}{NREF}, $CumulOverlap{$cumulspkover}{NDEL});
|
| 1005 |
+
$display_nspkerr = sprintf("%.1f%% (%d)", $CumulOverlap{$cumulspkover}{NSPKRERR}*100/$CumulOverlap{$cumulspkover}{NREF}, $CumulOverlap{$cumulspkover}{NSPKRERR});
|
| 1006 |
+
$display_nerr = sprintf("%.1f%% (%d)", $CumulOverlap{$cumulspkover}{NERR} *100/$CumulOverlap{$cumulspkover}{NREF}, $CumulOverlap{$cumulspkover}{NERR});
|
| 1007 |
+
}
|
| 1008 |
+
|
| 1009 |
+
print FILEINDEX "<tr>\n";
|
| 1010 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>$cumulspkover<b></td>\n";
|
| 1011 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_regs</td>\n";
|
| 1012 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_tottime</td>\n";
|
| 1013 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_regsalign</td>\n";
|
| 1014 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_tottimealign</td>\n";
|
| 1015 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nref</td>\n";
|
| 1016 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_ncorr</td>\n";
|
| 1017 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nsub</td>\n";
|
| 1018 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nins</td>\n";
|
| 1019 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_ndel</td>\n";
|
| 1020 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nspkerr</td>\n";
|
| 1021 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nerr</td>\n";
|
| 1022 |
+
print FILEINDEX "</tr>\n";
|
| 1023 |
+
}
|
| 1024 |
+
|
| 1025 |
+
|
| 1026 |
+
print FILEINDEX "</tbody>\n";
|
| 1027 |
+
print FILEINDEX "</table>\n";
|
| 1028 |
+
|
| 1029 |
+
|
| 1030 |
+
print FILEINDEX "</center>\n";
|
| 1031 |
+
print FILEINDEX "</body>\n";
|
| 1032 |
+
print FILEINDEX "</html>\n";
|
| 1033 |
+
|
| 1034 |
+
close FILEINDEX;
|
| 1035 |
+
|
| 1036 |
+
foreach my $file(sort keys %FileChannelSG)
|
| 1037 |
+
{
|
| 1038 |
+
foreach my $channel(sort keys %{ $FileChannelSG{$file} })
|
| 1039 |
+
{
|
| 1040 |
+
my %overallmeeting;
|
| 1041 |
+
my %cumuloverallmeeting;
|
| 1042 |
+
my $cleanfile = $file;
|
| 1043 |
+
$cleanfile =~ s/\//\_/g;
|
| 1044 |
+
my $filename = "$cleanfile" . "_" . "$channel" . ".html";
|
| 1045 |
+
my $bottom = "";
|
| 1046 |
+
|
| 1047 |
+
open(FILEINDEX, ">$Outputdir/$filename") or die "$?";
|
| 1048 |
+
|
| 1049 |
+
print FILEINDEX "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
|
| 1050 |
+
print FILEINDEX "<html>\n";
|
| 1051 |
+
print FILEINDEX "<head>\n";
|
| 1052 |
+
print FILEINDEX "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=ISO-8859-1\">\n";
|
| 1053 |
+
print FILEINDEX "<title>Overall Performance Summary for Meeting $file\/$channel</title>\n";
|
| 1054 |
+
print FILEINDEX "</head>\n";
|
| 1055 |
+
print FILEINDEX "<body>\n";
|
| 1056 |
+
|
| 1057 |
+
print FILEINDEX "<center>\n";
|
| 1058 |
+
print FILEINDEX "<h2>Overall Performance Summary for Meeting $file\/$channel</h2>\n";
|
| 1059 |
+
print FILEINDEX "<table style=\"text-align: left;\" border=\"1\" cellpadding=\"1\" cellspacing=\"0\">\n";
|
| 1060 |
+
print FILEINDEX "<tbody>\n";
|
| 1061 |
+
|
| 1062 |
+
print FILEINDEX "<tr>\n";
|
| 1063 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: left;\"><b>Region ID</b></b></td>\n";
|
| 1064 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Begin<br>Time</td>\n";
|
| 1065 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>End<br>Time</b></td>\n";
|
| 1066 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Duration</b></td>\n";
|
| 1067 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Ref<br>Speaker</b></td>\n";
|
| 1068 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Hyp<br>Speaker</b></td>\n";
|
| 1069 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Ref Aligned<br>Words</b></td>\n";
|
| 1070 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Corr</b></td>\n";
|
| 1071 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Sub</b></td>\n";
|
| 1072 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Ins</b></td>\n";
|
| 1073 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Del</b></td>\n";
|
| 1074 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>SpErr</b></td>\n";
|
| 1075 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Err</b></td>\n";
|
| 1076 |
+
print FILEINDEX "</tr>\n";
|
| 1077 |
+
|
| 1078 |
+
foreach my $SG_ID (sort {$a <=> $b} @{ $FileChannelSG{$file}{$channel}{LISTSG} })
|
| 1079 |
+
{
|
| 1080 |
+
my $BT = sprintf("%.3f", $SegGroups{$SG_ID}->{BT});
|
| 1081 |
+
my $ET = sprintf("%.3f", $SegGroups{$SG_ID}->{ET});
|
| 1082 |
+
my $Duration = sprintf("%.3f", $SegGroups{$SG_ID}->{ET} - $SegGroups{$SG_ID}->{BT});
|
| 1083 |
+
|
| 1084 |
+
my @refspkrs;
|
| 1085 |
+
my @sysspkrs;
|
| 1086 |
+
|
| 1087 |
+
foreach my $segref (sort keys %{ $SegGroups{$SG_ID}->{REF} }) { push(@refspkrs, $SegGroups{$SG_ID}->{REF}{$segref}->{SPKRID}) if($SegGroups{$SG_ID}->{REF}{$segref}->{SPKRID} ne "ref:INTER_SEGMENT_GAP"); }
|
| 1088 |
+
foreach my $segsys (sort keys %{ $SegGroups{$SG_ID}->{SYS} }) { push(@sysspkrs, $SegGroups{$SG_ID}->{SYS}{$segsys}->{SPKRID}) if(!($SegGroups{$SG_ID}->{SYS}{$segsys}->HasOnlyOneFakeToken())); }
|
| 1089 |
+
|
| 1090 |
+
my $nrefspkr = scalar unique @refspkrs;
|
| 1091 |
+
my $nhypspkr = scalar unique @sysspkrs;
|
| 1092 |
+
|
| 1093 |
+
$SegGroups{$SG_ID}->{ALIGNED} = 1 if( ($nrefspkr == 0) && ($nhypspkr == 0) );
|
| 1094 |
+
$SegGroups{$SG_ID}->{ALIGNED} = 1 if( ($SegGroups{$SG_ID}->{ALIGNED} == 0) && ($nrefspkr == 1) && ($nhypspkr == 0) && ($SegGroups{$SG_ID}->{HASFAKETIME} == 1) );
|
| 1095 |
+
|
| 1096 |
+
my $titleSG = "<a href=\"segmentgroup-$SG_ID.html\" target=\"_blank\">$SG_ID</a>";
|
| 1097 |
+
my $nref = "-";
|
| 1098 |
+
my $percCorr = "-";
|
| 1099 |
+
my $percSub = "-";
|
| 1100 |
+
my $percIns = "-";
|
| 1101 |
+
my $percDel = "-";
|
| 1102 |
+
my $percErr = "-";
|
| 1103 |
+
my $percSpErr = "-";
|
| 1104 |
+
|
| 1105 |
+
if($SegGroups{$SG_ID}->{NREF} != 0)
|
| 1106 |
+
{
|
| 1107 |
+
$percCorr = sprintf("%.1f%% (%d)", 100*$SegGroups{$SG_ID}->{NCORR}/$SegGroups{$SG_ID}->{NREF}, $SegGroups{$SG_ID}->{NCORR});
|
| 1108 |
+
$percSub = sprintf("%.1f%% (%d)", 100*$SegGroups{$SG_ID}->{NSUB}/$SegGroups{$SG_ID}->{NREF}, $SegGroups{$SG_ID}->{NSUB});
|
| 1109 |
+
$percIns = sprintf("%.1f%% (%d)", 100*$SegGroups{$SG_ID}->{NINS}/$SegGroups{$SG_ID}->{NREF}, $SegGroups{$SG_ID}->{NINS});
|
| 1110 |
+
$percDel = sprintf("%.1f%% (%d)", 100*$SegGroups{$SG_ID}->{NDEL}/$SegGroups{$SG_ID}->{NREF}, $SegGroups{$SG_ID}->{NDEL});
|
| 1111 |
+
$percErr = sprintf("%.1f%% (%d)", 100*($SegGroups{$SG_ID}->{NDEL}+$SegGroups{$SG_ID}->{NINS}+$SegGroups{$SG_ID}->{NSUB}+$SegGroups{$SG_ID}->{NSPKRERR})/$SegGroups{$SG_ID}->{NREF}, $SegGroups{$SG_ID}->{NDEL}+$SegGroups{$SG_ID}->{NINS}+$SegGroups{$SG_ID}->{NSUB}+$SegGroups{$SG_ID}->{NSPKRERR});
|
| 1112 |
+
$percSpErr = sprintf("%.1f%% (%d)", 100*$SegGroups{$SG_ID}->{NSPKRERR}/$SegGroups{$SG_ID}->{NREF}, $SegGroups{$SG_ID}->{NSPKRERR});
|
| 1113 |
+
}
|
| 1114 |
+
else
|
| 1115 |
+
{
|
| 1116 |
+
$percIns = sprintf("(%d)", $SegGroups{$SG_ID}->{NINS}) if($SegGroups{$SG_ID}->{ALIGNED} == 1);
|
| 1117 |
+
}
|
| 1118 |
+
|
| 1119 |
+
if($SegGroups{$SG_ID}->{ALIGNED} == 0)
|
| 1120 |
+
{
|
| 1121 |
+
$titleSG = "*<i>$titleSG</i>";
|
| 1122 |
+
$nrefspkr = "<i>$nrefspkr</i>";
|
| 1123 |
+
$nhypspkr = "<i>$nhypspkr</i>";
|
| 1124 |
+
$BT = "<i>$BT</i>";
|
| 1125 |
+
$ET = "<i>$ET</i>";
|
| 1126 |
+
$Duration = "<i>$Duration</i>";
|
| 1127 |
+
$bottom = "<br>*: Segment Group ignored for scoring.<br>";
|
| 1128 |
+
}
|
| 1129 |
+
else
|
| 1130 |
+
{
|
| 1131 |
+
$nref = $SegGroups{$SG_ID}->{NREF};
|
| 1132 |
+
}
|
| 1133 |
+
|
| 1134 |
+
print FILEINDEX "<tr>\n";
|
| 1135 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: left;\">$titleSG</td>\n";
|
| 1136 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$BT</td>\n";
|
| 1137 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$ET</td>\n";
|
| 1138 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$Duration</td>\n";
|
| 1139 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$nrefspkr</td>\n";
|
| 1140 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$nhypspkr</td>\n";
|
| 1141 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$nref</td>\n";
|
| 1142 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$percCorr</td>\n";
|
| 1143 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$percSub</td>\n";
|
| 1144 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$percIns</td>\n";
|
| 1145 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$percDel</td>\n";
|
| 1146 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$percSpErr</td>\n";
|
| 1147 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$percErr</td>\n";
|
| 1148 |
+
print FILEINDEX "</tr>\n";
|
| 1149 |
+
|
| 1150 |
+
$BT =~ s/<i>//;
|
| 1151 |
+
$ET =~ s/<i>//;
|
| 1152 |
+
$nrefspkr =~ s/<i>//;
|
| 1153 |
+
$nhypspkr =~ s/<i>//;
|
| 1154 |
+
$BT =~ s/<\/i>//;
|
| 1155 |
+
$ET =~ s/<\/i>//;
|
| 1156 |
+
$nrefspkr =~ s/<\/i>//;
|
| 1157 |
+
$nhypspkr =~ s/<\/i>//;
|
| 1158 |
+
|
| 1159 |
+
my $countSpeakers = $nrefspkr;
|
| 1160 |
+
|
| 1161 |
+
$overallmeeting{$countSpeakers}{NREF} = 0 if(!exists($overallmeeting{$countSpeakers}{NREF}));
|
| 1162 |
+
$overallmeeting{$countSpeakers}{NREF} += $SegGroups{$SG_ID}->{NREF};
|
| 1163 |
+
|
| 1164 |
+
$overallmeeting{$countSpeakers}{NCORR} = 0 if(!exists($overallmeeting{$countSpeakers}{NCORR}));
|
| 1165 |
+
$overallmeeting{$countSpeakers}{NCORR} += $SegGroups{$SG_ID}->{NCORR};
|
| 1166 |
+
$overallmeeting{$countSpeakers}{PCORR} = "NA";
|
| 1167 |
+
$overallmeeting{$countSpeakers}{PCORR} = sprintf("%.1f", 100*$overallmeeting{$countSpeakers}{NCORR}/$overallmeeting{$countSpeakers}{NREF}) if($overallmeeting{$countSpeakers}{NREF} != 0);
|
| 1168 |
+
|
| 1169 |
+
$overallmeeting{$countSpeakers}{NSUB} = 0 if(!exists($overallmeeting{$countSpeakers}{NSUB}));
|
| 1170 |
+
$overallmeeting{$countSpeakers}{NSUB} += $SegGroups{$SG_ID}->{NSUB};
|
| 1171 |
+
$overallmeeting{$countSpeakers}{PSUB} = "NA";
|
| 1172 |
+
$overallmeeting{$countSpeakers}{PSUB} = sprintf("%.1f", 100*$overallmeeting{$countSpeakers}{NSUB}/$overallmeeting{$countSpeakers}{NREF}) if($overallmeeting{$countSpeakers}{NREF} != 0);
|
| 1173 |
+
|
| 1174 |
+
$overallmeeting{$countSpeakers}{NINS} = 0 if(!exists($overallmeeting{$countSpeakers}{NINS}));
|
| 1175 |
+
$overallmeeting{$countSpeakers}{NINS} += $SegGroups{$SG_ID}->{NINS};
|
| 1176 |
+
$overallmeeting{$countSpeakers}{PINS} = "NA";
|
| 1177 |
+
$overallmeeting{$countSpeakers}{PINS} = sprintf("%.1f", 100*$overallmeeting{$countSpeakers}{NINS}/$overallmeeting{$countSpeakers}{NREF}) if($overallmeeting{$countSpeakers}{NREF} != 0);
|
| 1178 |
+
|
| 1179 |
+
$overallmeeting{$countSpeakers}{NDEL} = 0 if(!exists($overallmeeting{$countSpeakers}{NDEL}));
|
| 1180 |
+
$overallmeeting{$countSpeakers}{NDEL} += $SegGroups{$SG_ID}->{NDEL};
|
| 1181 |
+
$overallmeeting{$countSpeakers}{PDEL} = "NA";
|
| 1182 |
+
$overallmeeting{$countSpeakers}{PDEL} = sprintf("%.1f", 100*$overallmeeting{$countSpeakers}{NDEL}/$overallmeeting{$countSpeakers}{NREF}) if($overallmeeting{$countSpeakers}{NREF} != 0);
|
| 1183 |
+
|
| 1184 |
+
$overallmeeting{$countSpeakers}{NSPKRERR} = 0 if(!exists($overallmeeting{$countSpeakers}{NSPKRERR}));
|
| 1185 |
+
$overallmeeting{$countSpeakers}{NSPKRERR} += $SegGroups{$SG_ID}->{NSPKRERR};
|
| 1186 |
+
$overallmeeting{$countSpeakers}{PSPKRERR} = "NA";
|
| 1187 |
+
$overallmeeting{$countSpeakers}{PSPKRERR} = sprintf("%.1f", 100*$overallmeeting{$countSpeakers}{NSPKRERR}/$overallmeeting{$countSpeakers}{NREF}) if($overallmeeting{$countSpeakers}{NREF} != 0);
|
| 1188 |
+
|
| 1189 |
+
$overallmeeting{$countSpeakers}{NERR} = $overallmeeting{$countSpeakers}{NSUB} + $overallmeeting{$countSpeakers}{NINS} + $overallmeeting{$countSpeakers}{NDEL} + $overallmeeting{$countSpeakers}{NSPKRERR};
|
| 1190 |
+
$overallmeeting{$countSpeakers}{PERR} = "NA";
|
| 1191 |
+
$overallmeeting{$countSpeakers}{PERR} = sprintf("%.1f", 100*$overallmeeting{$countSpeakers}{NERR}/$overallmeeting{$countSpeakers}{NREF}) if($overallmeeting{$countSpeakers}{NREF} != 0);
|
| 1192 |
+
|
| 1193 |
+
$overallmeeting{$countSpeakers}{TOTTIME} = 0 if(!exists($overallmeeting{$countSpeakers}{TOTTIME}));
|
| 1194 |
+
$overallmeeting{$countSpeakers}{TOTTIME} += $SegGroups{$SG_ID}->{ET} - $SegGroups{$SG_ID}->{BT};
|
| 1195 |
+
|
| 1196 |
+
push( @{ $overallmeeting{$countSpeakers}{LISTSG} }, $SG_ID);
|
| 1197 |
+
$overallmeeting{$countSpeakers}{NLISTSG} = scalar @{ $overallmeeting{$countSpeakers}{LISTSG} };
|
| 1198 |
+
|
| 1199 |
+
$overallmeeting{$countSpeakers}{TOTTIMEALIGNED} = 0 if(!exists($overallmeeting{$countSpeakers}{TOTTIMEALIGNED}));
|
| 1200 |
+
$overallmeeting{$countSpeakers}{TOTTIMEALIGNED} += $SegGroups{$SG_ID}->{ET} - $SegGroups{$SG_ID}->{BT} if($SegGroups{$SG_ID}->{ALIGNED} == 1);
|
| 1201 |
+
|
| 1202 |
+
push( @{ $overallmeeting{$countSpeakers}{LISTSGALIGNED} }, $SG_ID) if($SegGroups{$SG_ID}->{ALIGNED} == 1);
|
| 1203 |
+
$overallmeeting{$countSpeakers}{NLISTSGALIGNED} = 0;
|
| 1204 |
+
$overallmeeting{$countSpeakers}{NLISTSGALIGNED} = scalar(@{ $overallmeeting{$countSpeakers}{LISTSGALIGNED} }) if(exists($overallmeeting{$countSpeakers}{LISTSGALIGNED}));
|
| 1205 |
+
|
| 1206 |
+
$overallmeeting{$countSpeakers}{NUMHYPTOKENS} = 0 if(!exists($overallmeeting{$countSpeakers}{NUMHYPTOKENS}));
|
| 1207 |
+
$overallmeeting{$countSpeakers}{NUMHYPTOKENS} += $SegGroups{$SG_ID}->GetNumHypWords();
|
| 1208 |
+
}
|
| 1209 |
+
|
| 1210 |
+
print FILEINDEX "</tbody>\n";
|
| 1211 |
+
print FILEINDEX "</table>\n";
|
| 1212 |
+
print FILEINDEX "$bottom";
|
| 1213 |
+
print FILEINDEX "<br>\n";
|
| 1214 |
+
|
| 1215 |
+
my $Total_regs = 0;
|
| 1216 |
+
my $Total_tottime = 0;
|
| 1217 |
+
my $Total_regsalign = 0;
|
| 1218 |
+
my $Total_tottimealign = 0;
|
| 1219 |
+
my $Total_nref = 0;
|
| 1220 |
+
my $Total_ncorr = 0;
|
| 1221 |
+
my $Total_nsub = 0;
|
| 1222 |
+
my $Total_nins = 0;
|
| 1223 |
+
my $Total_ndel = 0;
|
| 1224 |
+
my $Total_nspkerr = 0;
|
| 1225 |
+
my $Total_nerr = 0;
|
| 1226 |
+
|
| 1227 |
+
print FILEINDEX "<table style=\"text-align: left;\" border=\"1\" cellpadding=\"1\" cellspacing=\"0\">\n";
|
| 1228 |
+
print FILEINDEX "<tbody>\n";
|
| 1229 |
+
print FILEINDEX "<tr>\n";
|
| 1230 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Ref Speaker<br>Overlap</b></td>\n";
|
| 1231 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Regions</b></td>\n";
|
| 1232 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Total<br>Time</b></td>\n";
|
| 1233 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Regions<br>Aligned</b></td>\n";
|
| 1234 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Total Time<br>Aligned</b></td>\n";
|
| 1235 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Ref Aligned<br>Words</b></td>\n";
|
| 1236 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Corr</b></td>\n";
|
| 1237 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Sub</b></td>\n";
|
| 1238 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Ins</b></td>\n";
|
| 1239 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Del</b></td>\n";
|
| 1240 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>SpErr</b></td>\n";
|
| 1241 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Err</b></td>\n";
|
| 1242 |
+
print FILEINDEX "</tr>\n";
|
| 1243 |
+
|
| 1244 |
+
foreach my $spkover (sort {$a <=> $b} keys %overallmeeting)
|
| 1245 |
+
{
|
| 1246 |
+
my $display_regs = $overallmeeting{$spkover}{NLISTSG};
|
| 1247 |
+
my $display_tottime = sprintf("%.3f", $overallmeeting{$spkover}{TOTTIME});
|
| 1248 |
+
my $display_regsalign = $overallmeeting{$spkover}{NLISTSGALIGNED};
|
| 1249 |
+
my $display_tottimealign = sprintf("%.3f", $overallmeeting{$spkover}{TOTTIMEALIGNED});
|
| 1250 |
+
my $display_nref = "-";
|
| 1251 |
+
my $display_ncorr = "-";
|
| 1252 |
+
my $display_nsub = "-";
|
| 1253 |
+
my $display_nins = "-";
|
| 1254 |
+
my $display_ndel = "-";
|
| 1255 |
+
my $display_nspkerr = "-";
|
| 1256 |
+
my $display_nerr = "-";
|
| 1257 |
+
|
| 1258 |
+
$Total_regs += $overallmeeting{$spkover}{NLISTSG};
|
| 1259 |
+
$Total_tottime += $overallmeeting{$spkover}{TOTTIME};
|
| 1260 |
+
$Total_regsalign += $overallmeeting{$spkover}{NLISTSGALIGNED};
|
| 1261 |
+
$Total_tottimealign += $overallmeeting{$spkover}{TOTTIMEALIGNED};
|
| 1262 |
+
|
| 1263 |
+
if($spkover == 0)
|
| 1264 |
+
{
|
| 1265 |
+
$display_nins = sprintf("(%d)", $overallmeeting{$spkover}{NUMHYPTOKENS});
|
| 1266 |
+
$Total_nins += $overallmeeting{$spkover}{NUMHYPTOKENS};
|
| 1267 |
+
$Total_nerr += $Total_nins;
|
| 1268 |
+
}
|
| 1269 |
+
|
| 1270 |
+
if($overallmeeting{$spkover}{NREF} != 0)
|
| 1271 |
+
{
|
| 1272 |
+
$display_nref = $overallmeeting{$spkover}{NREF};
|
| 1273 |
+
$display_ncorr = sprintf("%.1f%% (%d)", $overallmeeting{$spkover}{PCORR}, $overallmeeting{$spkover}{NCORR});
|
| 1274 |
+
$display_nsub = sprintf("%.1f%% (%d)", $overallmeeting{$spkover}{PSUB}, $overallmeeting{$spkover}{NSUB});
|
| 1275 |
+
$display_nins = sprintf("%.1f%% (%d)", $overallmeeting{$spkover}{PINS}, $overallmeeting{$spkover}{NINS});
|
| 1276 |
+
$display_ndel = sprintf("%.1f%% (%d)", $overallmeeting{$spkover}{PDEL}, $overallmeeting{$spkover}{NDEL});
|
| 1277 |
+
$display_nspkerr = sprintf("%.1f%% (%d)", $overallmeeting{$spkover}{PSPKRERR}, $overallmeeting{$spkover}{NSPKRERR});
|
| 1278 |
+
$display_nerr = sprintf("%.1f%% (%d)", $overallmeeting{$spkover}{PERR}, $overallmeeting{$spkover}{NERR});
|
| 1279 |
+
$Total_nref += $overallmeeting{$spkover}{NREF};
|
| 1280 |
+
$Total_ncorr += $overallmeeting{$spkover}{NCORR};
|
| 1281 |
+
$Total_nsub += $overallmeeting{$spkover}{NSUB};
|
| 1282 |
+
$Total_nins += $overallmeeting{$spkover}{NINS};
|
| 1283 |
+
$Total_ndel += $overallmeeting{$spkover}{NDEL};
|
| 1284 |
+
$Total_nspkerr += $overallmeeting{$spkover}{NSPKRERR};
|
| 1285 |
+
$Total_nerr += $overallmeeting{$spkover}{NERR};
|
| 1286 |
+
}
|
| 1287 |
+
|
| 1288 |
+
print FILEINDEX "<tr>\n";
|
| 1289 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>$spkover<b></td>\n";
|
| 1290 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_regs</td>\n";
|
| 1291 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_tottime</td>\n";
|
| 1292 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_regsalign</td>\n";
|
| 1293 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_tottimealign</td>\n";
|
| 1294 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nref</td>\n";
|
| 1295 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_ncorr</td>\n";
|
| 1296 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nsub</td>\n";
|
| 1297 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nins</td>\n";
|
| 1298 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_ndel</td>\n";
|
| 1299 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nspkerr</td>\n";
|
| 1300 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nerr</td>\n";
|
| 1301 |
+
print FILEINDEX "</tr>\n";
|
| 1302 |
+
|
| 1303 |
+
# data for Cumuloverlap table
|
| 1304 |
+
$cumuloverallmeeting{$spkover}{NLISTSG} = $Total_regs;
|
| 1305 |
+
$cumuloverallmeeting{$spkover}{TOTTIME} = $Total_tottime;
|
| 1306 |
+
$cumuloverallmeeting{$spkover}{NLISTSGALIGNED} = $Total_regsalign;
|
| 1307 |
+
$cumuloverallmeeting{$spkover}{TOTTIMEALIGNED} = $Total_tottimealign;
|
| 1308 |
+
$cumuloverallmeeting{$spkover}{NREF} = $Total_nref;
|
| 1309 |
+
$cumuloverallmeeting{$spkover}{NCORR} = $Total_ncorr;
|
| 1310 |
+
$cumuloverallmeeting{$spkover}{NSUB} = $Total_nsub;
|
| 1311 |
+
$cumuloverallmeeting{$spkover}{NINS} = $Total_nins;
|
| 1312 |
+
$cumuloverallmeeting{$spkover}{NDEL} = $Total_ndel;
|
| 1313 |
+
$cumuloverallmeeting{$spkover}{NSPKRERR} = $Total_nspkerr;
|
| 1314 |
+
$cumuloverallmeeting{$spkover}{NERR} = $Total_nerr;
|
| 1315 |
+
}
|
| 1316 |
+
|
| 1317 |
+
my $display_Total_regs = $Total_regs;
|
| 1318 |
+
my $display_Total_tottime = sprintf("%.3f", $Total_tottime);
|
| 1319 |
+
my $display_Total_regsalign = $Total_regsalign;
|
| 1320 |
+
my $display_Total_tottimealign = sprintf("%.3f", $Total_tottimealign);
|
| 1321 |
+
my $display_Total_nref = $Total_nref;
|
| 1322 |
+
my $display_Total_ncorr = sprintf("%.1f%% (%d)", 100*$Total_ncorr/$Total_nref, $Total_ncorr);
|
| 1323 |
+
my $display_Total_nsub = sprintf("%.1f%% (%d)", 100*$Total_nsub/$Total_nref, $Total_nsub);
|
| 1324 |
+
my $display_Total_nins = sprintf("%.1f%% (%d)", 100*$Total_nins/$Total_nref, $Total_nins);
|
| 1325 |
+
my $display_Total_ndel = sprintf("%.1f%% (%d)", 100*$Total_ndel/$Total_nref, $Total_ndel);
|
| 1326 |
+
my $display_Total_nspkerr = sprintf("%.1f%% (%d)", 100*$Total_nspkerr/$Total_nref, $Total_nspkerr);
|
| 1327 |
+
my $display_Total_nerr = sprintf("%.1f%% (%d)", 100*$Total_nerr/$Total_nref, $Total_nerr);
|
| 1328 |
+
|
| 1329 |
+
print FILEINDEX "<tr>\n";
|
| 1330 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Ensemble</b></td>\n";
|
| 1331 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_regs</td>\n";
|
| 1332 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_tottime</td>\n";
|
| 1333 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_regsalign</td>\n";
|
| 1334 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_tottimealign</td>\n";
|
| 1335 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_nref</td>\n";
|
| 1336 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_ncorr</td>\n";
|
| 1337 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_nsub</td>\n";
|
| 1338 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_nins</td>\n";
|
| 1339 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_ndel</td>\n";
|
| 1340 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_nspkerr</td>\n";
|
| 1341 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_Total_nerr</td>\n";
|
| 1342 |
+
print FILEINDEX "</tr>\n";
|
| 1343 |
+
|
| 1344 |
+
print FILEINDEX "</tbody>\n";
|
| 1345 |
+
print FILEINDEX "</table>\n";
|
| 1346 |
+
|
| 1347 |
+
print FILEINDEX "<br>\n";
|
| 1348 |
+
|
| 1349 |
+
print FILEINDEX "<table style=\"text-align: left;\" border=\"1\" cellpadding=\"1\" cellspacing=\"0\">\n";
|
| 1350 |
+
print FILEINDEX "<tbody>\n";
|
| 1351 |
+
print FILEINDEX "<tr>\n";
|
| 1352 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Ref Speaker<br>Cumulative<br>Overlap</b></td>\n";
|
| 1353 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Regions</b></td>\n";
|
| 1354 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Total<br>Time</b></td>\n";
|
| 1355 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Regions<br>Aligned</b></td>\n";
|
| 1356 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Total Time<br>Aligned</b></td>\n";
|
| 1357 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>\#Ref Aligned<br>Words</b></td>\n";
|
| 1358 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Corr</b></td>\n";
|
| 1359 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Sub</b></td>\n";
|
| 1360 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Ins</b></td>\n";
|
| 1361 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Del</b></td>\n";
|
| 1362 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>SpErr</b></td>\n";
|
| 1363 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>Err</b></td>\n";
|
| 1364 |
+
print FILEINDEX "</tr>\n";
|
| 1365 |
+
|
| 1366 |
+
foreach my $cumulspkover (sort {$a <=> $b} keys %cumuloverallmeeting)
|
| 1367 |
+
{
|
| 1368 |
+
my $display_regs = $cumuloverallmeeting{$cumulspkover}{NLISTSG};
|
| 1369 |
+
my $display_tottime = sprintf("%.3f", $cumuloverallmeeting{$cumulspkover}{TOTTIME});
|
| 1370 |
+
my $display_regsalign = $cumuloverallmeeting{$cumulspkover}{NLISTSGALIGNED};
|
| 1371 |
+
my $display_tottimealign = sprintf("%.3f", $cumuloverallmeeting{$cumulspkover}{TOTTIMEALIGNED});
|
| 1372 |
+
my $display_nref = "-";
|
| 1373 |
+
my $display_ncorr = "-";
|
| 1374 |
+
my $display_nsub = "-";
|
| 1375 |
+
my $display_nins = "-";
|
| 1376 |
+
my $display_ndel = "-";
|
| 1377 |
+
my $display_nspkerr = "-";
|
| 1378 |
+
my $display_nerr = "-";
|
| 1379 |
+
|
| 1380 |
+
if($cumulspkover == 0)
|
| 1381 |
+
{
|
| 1382 |
+
$display_nins = sprintf("(%d)", $CumulOverlap{$cumulspkover}{NINS});
|
| 1383 |
+
}
|
| 1384 |
+
|
| 1385 |
+
if($cumuloverallmeeting{$cumulspkover}{NREF} != 0)
|
| 1386 |
+
{
|
| 1387 |
+
$display_nref = $cumuloverallmeeting{$cumulspkover}{NREF};
|
| 1388 |
+
$display_ncorr = sprintf("%.1f%% (%d)", $cumuloverallmeeting{$cumulspkover}{NCORR} *100/$cumuloverallmeeting{$cumulspkover}{NREF}, $cumuloverallmeeting{$cumulspkover}{NCORR});
|
| 1389 |
+
$display_nsub = sprintf("%.1f%% (%d)", $cumuloverallmeeting{$cumulspkover}{NSUB} *100/$cumuloverallmeeting{$cumulspkover}{NREF}, $cumuloverallmeeting{$cumulspkover}{NSUB});
|
| 1390 |
+
$display_nins = sprintf("%.1f%% (%d)", $cumuloverallmeeting{$cumulspkover}{NINS} *100/$cumuloverallmeeting{$cumulspkover}{NREF}, $cumuloverallmeeting{$cumulspkover}{NINS});
|
| 1391 |
+
$display_ndel = sprintf("%.1f%% (%d)", $cumuloverallmeeting{$cumulspkover}{NDEL} *100/$cumuloverallmeeting{$cumulspkover}{NREF}, $cumuloverallmeeting{$cumulspkover}{NDEL});
|
| 1392 |
+
$display_nspkerr = sprintf("%.1f%% (%d)", $cumuloverallmeeting{$cumulspkover}{NSPKRERR}*100/$cumuloverallmeeting{$cumulspkover}{NREF}, $cumuloverallmeeting{$cumulspkover}{NSPKRERR});
|
| 1393 |
+
$display_nerr = sprintf("%.1f%% (%d)", $cumuloverallmeeting{$cumulspkover}{NERR} *100/$cumuloverallmeeting{$cumulspkover}{NREF}, $cumuloverallmeeting{$cumulspkover}{NERR});
|
| 1394 |
+
}
|
| 1395 |
+
|
| 1396 |
+
print FILEINDEX "<tr>\n";
|
| 1397 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\"><b>$cumulspkover<b></td>\n";
|
| 1398 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_regs</td>\n";
|
| 1399 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_tottime</td>\n";
|
| 1400 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_regsalign</td>\n";
|
| 1401 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_tottimealign</td>\n";
|
| 1402 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nref</td>\n";
|
| 1403 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_ncorr</td>\n";
|
| 1404 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nsub</td>\n";
|
| 1405 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nins</td>\n";
|
| 1406 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_ndel</td>\n";
|
| 1407 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nspkerr</td>\n";
|
| 1408 |
+
print FILEINDEX "<td style=\"vertical-align: center; text-align: center;\">$display_nerr</td>\n";
|
| 1409 |
+
print FILEINDEX "</tr>\n";
|
| 1410 |
+
}
|
| 1411 |
+
|
| 1412 |
+
|
| 1413 |
+
print FILEINDEX "</tbody>\n";
|
| 1414 |
+
print FILEINDEX "</table>\n";
|
| 1415 |
+
|
| 1416 |
+
|
| 1417 |
+
print FILEINDEX "<center>\n";
|
| 1418 |
+
print FILEINDEX "</body>\n";
|
| 1419 |
+
print FILEINDEX "</html>\n";
|
| 1420 |
+
|
| 1421 |
+
close FILEINDEX;
|
| 1422 |
+
}
|
| 1423 |
+
}
|
| 1424 |
+
|
| 1425 |
+
if (! $Installed)
|
| 1426 |
+
{
|
| 1427 |
+
system ('cp', '-r', 'js', $Outputdir);
|
| 1428 |
+
system ('cp', '-r', 'images', $Outputdir);
|
| 1429 |
+
}
|
| 1430 |
+
else
|
| 1431 |
+
{
|
| 1432 |
+
extractJavaImages($Outputdir);
|
| 1433 |
+
}
|
| 1434 |
+
|
| 1435 |
+
1;
|
| 1436 |
+
|
SCTK/src/align2html/align2html.pl
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
SCTK/src/align2html/buildInstallVersion.pl
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/perl
|
| 2 |
+
|
| 3 |
+
# ALIGN2HTML
|
| 4 |
+
# Author: Jerome Ajot
|
| 5 |
+
#
|
| 6 |
+
# This software was developed at the National Institute of Standards and Technology by
|
| 7 |
+
# employees of the Federal Government in the course of their official duties. Pursuant
|
| 8 |
+
# to title 17 Section 105 of the United States Code this software is not subject to
|
| 9 |
+
# copyright protection and is in the public domain. ALIGN2HTML is an experimental system.
|
| 10 |
+
# NIST assumes no responsibility whatsoever for its use by other parties, and makes no
|
| 11 |
+
# guarantees, expressed or implied, about its quality, reliability, or any other
|
| 12 |
+
# characteristic. We would appreciate acknowledgement if the software is used.
|
| 13 |
+
#
|
| 14 |
+
# THIS SOFTWARE IS PROVIDED "AS IS." With regard to this software, NIST MAKES NO EXPRESS
|
| 15 |
+
# OR IMPLIED WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING MERCHANTABILITY,
|
| 16 |
+
# OR FITNESS FOR A PARTICULAR PURPOSE.
|
| 17 |
+
|
| 18 |
+
use strict;
|
| 19 |
+
|
| 20 |
+
my $exe = "align2html-main.pl";
|
| 21 |
+
|
| 22 |
+
my @modules = ();
|
| 23 |
+
my @file = ();
|
| 24 |
+
|
| 25 |
+
open EXE,"<$exe" || die "Failed to open executable $exe";
|
| 26 |
+
while (<EXE>){
|
| 27 |
+
if ($_ =~ /my \$Installed = 0;/){
|
| 28 |
+
push @file, "my \$Installed = 1;\n";
|
| 29 |
+
} elsif ($_ =~ /\#\#\# Begin Local Modules/){
|
| 30 |
+
do {
|
| 31 |
+
if ($_ =~ /use\s+(\S+)\s*;/){
|
| 32 |
+
push @modules, $1;
|
| 33 |
+
}
|
| 34 |
+
$_ = <EXE>;
|
| 35 |
+
} while ($_ !~ /\#\#\# End Local Modules/);
|
| 36 |
+
my $modExp = "use\\s+(".join("|",@modules).")";
|
| 37 |
+
#print "Modes = ".join(" ",@modules)." $modExp\n";
|
| 38 |
+
### Insert the modules
|
| 39 |
+
foreach my $mod(@modules){
|
| 40 |
+
open (MOD, "<$mod.pm") || die "Failed to open $mod.pm";
|
| 41 |
+
while (<MOD>){
|
| 42 |
+
push(@file, $_) if ($_ !~ /$modExp/);
|
| 43 |
+
}
|
| 44 |
+
close MOD;
|
| 45 |
+
}
|
| 46 |
+
### Reset the package
|
| 47 |
+
push @file, "package main;\n"
|
| 48 |
+
} elsif ($_ =~ /die "HERE DOCUMENT NOT BUILT"/){
|
| 49 |
+
push @file, 'my $here = "";'."\n";
|
| 50 |
+
push @file, "\$here = << 'EOTAR';\n";
|
| 51 |
+
open TARPACK, "packImageTarFile" || die "Failed to open the packed Image tar file";
|
| 52 |
+
while (<TARPACK>){
|
| 53 |
+
push @file, $_;
|
| 54 |
+
}
|
| 55 |
+
close TARPACK;
|
| 56 |
+
push @file, pack("u", $_);
|
| 57 |
+
push @file, "EOTAR\n";
|
| 58 |
+
|
| 59 |
+
push @file, 'open UNTAR, "| (cd $outDir ; tar zxf -)" || die "Failed to UUDECODE/TAR"'.";\n";
|
| 60 |
+
push @file, 'binmode(UNTAR);'."\n";
|
| 61 |
+
push @file, 'print UNTAR unpack("u",$here);'."\n";
|
| 62 |
+
push @file, 'close UNTAR'."\n";
|
| 63 |
+
} else {
|
| 64 |
+
push @file, $_;
|
| 65 |
+
}
|
| 66 |
+
}
|
| 67 |
+
print @file;
|
| 68 |
+
|
| 69 |
+
# cat align2html.pl | perl -ne 'if ($$_ =~ /die "HERE DOCUMENT NOT BUILT"/) { system "cat DATA.tgz.uu" } else { print }' > align2html-combined.pl
|
SCTK/src/align2html/buildPack.pl
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env perl
|
| 2 |
+
|
| 3 |
+
# ALIGN2HTML
|
| 4 |
+
# Author: Jerome Ajot
|
| 5 |
+
#
|
| 6 |
+
# This software was developed at the National Institute of Standards and Technology by
|
| 7 |
+
# employees of the Federal Government in the course of their official duties. Pursuant
|
| 8 |
+
# to title 17 Section 105 of the United States Code this software is not subject to
|
| 9 |
+
# copyright protection and is in the public domain. ALIGN2HTML is an experimental system.
|
| 10 |
+
# NIST assumes no responsibility whatsoever for its use by other parties, and makes no
|
| 11 |
+
# guarantees, expressed or implied, about its quality, reliability, or any other
|
| 12 |
+
# characteristic. We would appreciate acknowledgement if the software is used.
|
| 13 |
+
#
|
| 14 |
+
# THIS SOFTWARE IS PROVIDED "AS IS." With regard to this software, NIST MAKES NO EXPRESS
|
| 15 |
+
# OR IMPLIED WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING MERCHANTABILITY,
|
| 16 |
+
# OR FITNESS FOR A PARTICULAR PURPOSE.
|
| 17 |
+
|
| 18 |
+
use strict;
|
| 19 |
+
use warnings;
|
| 20 |
+
|
| 21 |
+
my $str = "";
|
| 22 |
+
|
| 23 |
+
open TAR, "tar zcf - --exclude CVS --exclude .DS_Store ./js/wz_jsgraphics.js ./images/*gif |" || die "TAR/UUENCODE Fialed";
|
| 24 |
+
binmode TAR;
|
| 25 |
+
read(TAR, $_, 90000000);
|
| 26 |
+
$str .= pack("u", $_) . "\n";
|
| 27 |
+
close TAR;
|
| 28 |
+
|
| 29 |
+
print "$str";
|
SCTK/src/align2html/makefile
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
SHELL = /bin/sh
|
| 2 |
+
PREFIX=/home/userube/mozilla/zz__temp_5_rover/SCTK
|
| 3 |
+
bindir = $(PREFIX)/bin
|
| 4 |
+
|
| 5 |
+
all: align2html.pl
|
| 6 |
+
|
| 7 |
+
align2html.pl: align2html-main.pl buildInstallVersion.pl
|
| 8 |
+
perl buildInstallVersion.pl > align2html.pl
|
| 9 |
+
chmod +x align2html.pl
|
| 10 |
+
|
| 11 |
+
check: all
|
| 12 |
+
@echo "No Tests for align2html.pl"
|
| 13 |
+
|
| 14 |
+
install: all
|
| 15 |
+
perl buildInstallVersion.pl > $(DESTDIR)$(bindir)/align2html.pl
|
| 16 |
+
chmod +x $(DESTDIR)$(bindir)/align2html.pl
|
| 17 |
+
|
| 18 |
+
buildPackFile:
|
| 19 |
+
buildPack.pl > packImageTarFile
|
| 20 |
+
|
| 21 |
+
clean:
|
| 22 |
+
$(RM) align2html.pl
|
| 23 |
+
|
| 24 |
+
distclean: clean
|
| 25 |
+
$(RM) -r *~ makefile
|
SCTK/src/align2html/makefile.in
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
SHELL = /bin/sh
|
| 2 |
+
PREFIX=
|
| 3 |
+
bindir = $(PREFIX)/bin
|
| 4 |
+
|
| 5 |
+
all: align2html.pl
|
| 6 |
+
|
| 7 |
+
align2html.pl: align2html-main.pl buildInstallVersion.pl
|
| 8 |
+
perl buildInstallVersion.pl > align2html.pl
|
| 9 |
+
chmod +x align2html.pl
|
| 10 |
+
|
| 11 |
+
check: all
|
| 12 |
+
@echo "No Tests for align2html.pl"
|
| 13 |
+
|
| 14 |
+
install: all
|
| 15 |
+
perl buildInstallVersion.pl > $(DESTDIR)$(bindir)/align2html.pl
|
| 16 |
+
chmod +x $(DESTDIR)$(bindir)/align2html.pl
|
| 17 |
+
|
| 18 |
+
buildPackFile:
|
| 19 |
+
buildPack.pl > packImageTarFile
|
| 20 |
+
|
| 21 |
+
clean:
|
| 22 |
+
$(RM) align2html.pl
|
| 23 |
+
|
| 24 |
+
distclean: clean
|
| 25 |
+
$(RM) -r *~ makefile
|
SCTK/src/align2html/packImageTarFile
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
M'XL(`-QX"$H``^P\2VSD1G9*$`21$!D.L,@:>RI-9J;9ZH^Z6Z.QK1Y)UDCS
|
| 2 |
+
MD5<>:4<RG(EWTF:3U4W.L,E>DJUN3G:`1>($"`(DU\#'/03(<6][VTO@`+DX
|
| 3 |
+
MR,'W('O.+0CVDLU[KXID\=.2QI8=>Q$"HLCZO'^]]ZJZBLVU9\':]$7O63#T
|
| 4 |
+
M];%E&T'S6;!PM5<+KC??W%AHM5NW;[77X;W37M_8H/)6Z];&[=NW%MJMC3<W
|
| 5 |
+
M-J!THP7M-M;7UQ=8ZXKI*+TF0:C[C"WHS[SPO';!F'/#FE\OF&DE_[\EU]HJ
|
| 6 |
+
M.[7L@+E>:!N<C4`<K,_9Q`V]B6%QD^DATQV'A?:(!\WEI>6EO+$PN,Z:K--<
|
| 7 |
+
MO[V\=&IQYN@A!RAGW`]LSV4`7#_3;4?O.QR@+2]983C>7%N;3J?-J>Z$W'_A
|
| 8 |
+
M^6[3\$;+2Y[/E%J3G]F^7E:C]#,Y$K7GC2/?'EHATXPJZX"%->!VBWU`#=F?
|
| 9 |
+
M8$NV"WQ0HX#Y/.#^&3>!HSV?`\$F6V^R=KM)?5D_4GLR[0/>WYR#'ZACU>6E
|
| 10 |
+
M0QU8'GFF/;"YN<DZ`.DV`;N-Y!US?^#Y(]T%$7MCD*7]0@]!.`G;@`C"7
|
| 11 |
+
MA^S>;.QX/O>7EX"`4\L;Z0&[[^ON<Z:[)GO7LUSVT'/,8.KYH06D#VS'.?:<
|
| 12 |
+
M:`AB'O'0\DQFC\8.'W$7.0(@[^EA:-E\PAZ"$KE/"GP((F`J1>^"?DX,WQZ'
|
| 13 |
+
M[('4*SNT^[[N1]#AV/?.;),'$D.PO-1@H<=,7Y\RQW9Y4`=I&J'N#AU\YHYC
|
| 14 |
+
MCP-\&@O*H,/BU`XM!B/(`/&0'6!'!I09SP%`4)<PD1\%&'$=PU/1AGP6`F6/
|
| 15 |
+
MCD[O;;*C,?>%,.ML,'$-(5?L"ARXAF6[0V;I9YQ!*PLTVN?<C97`S>4E`,H'
|
| 16 |
+
M`]NPN6M$U`^'N@G4Z2YB#"R0-E+)O`$+O(D/$C,\DY,L#P_V[CTZ`2H.'QP?
|
| 17 |
+
M8@$-)D<(#TU_X',.O0;A5/=YET7>A!D`U^>F'82^W9^$G-DAHEWS0.]D01&6
|
| 18 |
+
M3%P3B`6*@5M_1,CQY<&C]]DA$`-U#[@+G#OL>-)W;`-H@0'L!IQI2$N5@>V,
|
| 19 |
+
ML2:PA"E@[_M(S8FDAMWW``F)KLNXC<)97HI';:?9CE%*N'4&IJJ!.P`>?!*@
|
| 20 |
+
MYP(6-Z(![\?CO5DFA919L%"7H%K>&"T`X`&S4U0\NIV`#R8.F`,T91\<G#X\
|
| 21 |
+
M>O^4[3YZPC[8??QX]]'IDRY#4_*@EI]Q`0@M'L8<`Y9`WV$$9"\OO7?O\=Y#
|
| 22 |
+
MZ+![]^#PX/0)DG[_X/31O9,3=O_H,=MEQ[N/3P_VWC_<?<R.WW]\?'1RK\G8
|
| 23 |
+
M">>QD$&<95*.A4'C=@1CE9D\!.<F7.,3T"Z8R\0QI<5Q@]MGZ$3!8L;1*^A0
|
| 24 |
+
M=SPP6QHVH2+++K,'Z*KK;.K;8#E@G@6U+B^E>JV#;S&:=;;Q-COEZ!G8L:,;
|
| 25 |
+
MH,J3"79?7V_5V5TO"+'E>[N,06!NMQOM]=:;C+U_LELGOQL`<,7W#=U)T_.'
|
| 26 |
+
M:\B1PP?AFD.L-*UPY"POK:ZA(,".(*@^&_9L**W3`Z=_`W"3]&!ZHGSDO0`L
|
| 27 |
+
M\.#>8EM,,SUC@MZKZ>@1V!.[>9.%T9B#X)(:P]$!7\!6MM@U'"0#<"7FM6I7
|
| 28 |
+
MX(T]`#.LY_L/3]_39G5F@W_^,_!",\"0@.E[9L1^_&/F3AP'^BX2C=!@IN"<
|
| 29 |
+
M-6U0AA_NFL]`:FX(\`YS>&578`?)I\XK`M3-FU"UF$#2QV/NFGN6#<:1!9%M
|
| 30 |
+
MF?))<>DQN$)^;@?-5ME2>FG5:C/@X0GD-^%=/D!C/0^.+?ON>2[ZUXGN0.@9
|
| 31 |
+
M(M`242]*W0+JA%UZ0D'`8UZ*8.7SA8=&`8`2.`DSF'@@W*GMFMZTZ:&GEWW`
|
| 32 |
+
M;D07B3#!%81@E<WWO!='8]VPP1T44+[,6<K8#?<]0Y-&@L.M.77-9D(%#35-
|
| 33 |
+
MTKE#XQ&-_?$8^K#-Y)W$$K\`;95*.:X]]VS?&\7H<)R@71;19C2)L&<Y;6K4
|
| 34 |
+
MQW#/1"W:[EP57I)\>Y`"9?&3:KK:[!78/.`QE^5PBX-+NR98N^>:UQ)_<24B
|
| 35 |
+
M/X`6%U$3&VEM*\%P>009^SFG]>CYOGV&7BD")UYG5KX;(*_<,>TS1H:\=6WL
|
| 36 |
+
M!39VW-3[@>=`!.U6:CAJ*^A[-RNL!N938Y7Q+"X/O3$51]GBJ6V&%E5,LQ46
|
| 37 |
+
MQY28:JQLC0&9UR:F8UJK7JE-:U`%_RWZWZK&K?JZ\7SH8\AI&!ZDKP1)2!5?
|
| 38 |
+
M&;725L28W6&5K@>9PL#QIIN6;9K<K8!"*Y6J`-:]MGWGAVO`_O9<V8%5G2^]
|
| 39 |
+
M&S<JM11_K0*$SN@>T7U*=POO\U`<^^%5:*CO^9##-1)%2<%#.NC8)LN+B56^
|
| 40 |
+
ME&9;WU*-'D;^1;*F7(`IPMFZEDCG&DN%(XJC3#$)1U1,,Q5"2*+&RM3TA\2F
|
| 41 |
+
MJ,IJB'@A<K9_Z"K\H!?W^9"C$V9K-VYH'_YI]VFMVKWH_]JPJP@C]G!"!CX/
|
| 42 |
+
M)[Z;>**FS\>8NVE((^&J$[6J)>;TT"U:9E&U@N?K[2Y9W?5.%ZWL^GI76-7U
|
| 43 |
+
M6UUI3=<W@'G2(W!>+5$ET`CCYIO,0%<=D-=O)2/Q>OL"UL!*;5>;M<%,X6_6
|
| 44 |
+
M@?^=))9`UM=FVU`*)8M81#&]-^M@0.YTDX(("R)1("K;]"S*Q3-`VL*NHH)>
|
| 45 |
+
M1(^7,E4P*<QW&D@+Y*];.,&WFB`=+>HTHG:U'F<"2"O!Q9((9@$^YJ<14@JT
|
| 46 |
+
M[[!&&P9IFY)FX@$`;T,:&668&&,G,[ISAZ`LCOT)O$-A`]M#:5444V'#%/KT
|
| 47 |
+
M"#TQ,(6,`::CT+;1J`+B%@(7T!=K-=&&D(^32EDK'(`(E9[P#K,&/K2KHM=B
|
| 48 |
+
MA*Z!^)(%8RP`"N6K0@8);W&1.S"ODJVHG(I+$'4`4ZT=XR);H,Y%R<Q*)1,5
|
| 49 |
+
M)!,)R9!""#4R#7J_@PI2A)((+%(%%LLD)ZFX6&5A5JL1#T"]%S6B6B*NHKSR
|
| 50 |
+
M`E/)BT46LZT@FPLGTU'<5<)HS"2$=6+*J&&,Y3)"*."_K%0\(9:HX4755Q5!
|
| 51 |
+
MQFS*F8O!@_%$*G,OYWB3SOYOKC]!P$$\IPE"WWO.N_/<3%S(6CB+"QKK.3]!
|
| 52 |
+
MK"(P+5@U9ZM$7O`CR,_:-3-:-:,UZ`T5U2KXGX86;&^WJU!:96O`FE"7Z+VB
|
| 53 |
+
M!8U;0"<!,+CM:+T`IQ+T3O$$"ZH0Y-M9PV0)!4$B>]V,)460@K6.6'[X9GK-
|
| 54 |
+
MFF[6@8.ORW/J)CI/B:_H/9'R"]0<9=6,^@4UH[9!S;&.9PVIYNAK4+/H6:KG
|
| 55 |
+
MJXX!-1!@]VJC02^0X4`WOVGQ(":MD]#V]48$Q(\A017-%4<%0M$1."X3&?:]
|
| 56 |
+
M,/Q-C`U8:?I3C`O^9'Y`^`(>]$*W28C\J5SL45=@VFE**6A;@7_GN=@+O.<<
|
| 57 |
+
MAYDX[I=)S#N?G"O).K-RB:Y(+GD)E,LIB527$]`KR*4X:([.-)S2U1G,_.J,
|
| 58 |
+
MYGUU)F9]RBJK#EQ0'<2/.NO#FVB"K]!DZIEQ@YM0;]&K)IK<;%=KU,A`>T=<
|
| 59 |
+
M-;W.##1Z0%GKQR.A)08"O7NRP$M*=*1`TU?U*BJ0]9$$K;_:KTI]TB*XINL4
|
| 60 |
+
MW[1V0^NC2C%6]:E_2/7]/M:#RG5]51--&D+QN'Z",I(:CV*=I&$W9'<R^H<"
|
| 61 |
+
M4$&_#X!H6-76I<Y#J@!<6+JJ@3)SSAE_A]+"2\!#V]1U`29JM.?#CSG2T$Z)
|
| 62 |
+
MJY@8-#_,8\2;!6\8,5+CF][L8.YHW>R4)4-'9S\P`\V8H;[JK#&KH5N>U4#=
|
| 63 |
+
M\(;^&8"U:Q:^*D8_MS?Z9&@OND-/T'BALV+CYX#)$V$).+0*)N"HF9@2A$HB
|
| 64 |
+
M),BSL27D%V5D%U!%HH%&(\H$(#5>&;,&&371H\LYL.81/"0M76R/V]=B%L[O
|
| 65 |
+
M5#9@8?ISB2%;,HF@IF@\08/"F.BC%/P?#/6O<F!WDQ4:2&QQN*&I4YK;J>+/
|
| 66 |
+
ME\1%8Z,=SZ`$%[*@FHFJ18]$+D/$C)E39^.9C[<0;WV\3=4($I4$#\6CQ,-N
|
| 67 |
+
MKD^9ZU34\9)S*^<`+7<LK^99<JY%]2W+22HY;;1SB20(!NVGUJYIP<UTB<5*
|
| 68 |
+
M)@_9-!&!6'.`!&EG(#L+,)-J4FL5P[F>I0'M:U/%OX!W\:2C@JK4Q61\3";3
|
| 69 |
+
M3962<:KS',U<3R,`Y6>,&6<3%/U,SM'HR$HC0.;F]RG/F7HT.,4PT6#8M,D$
|
| 70 |
+
MJM(5+/;ZZ=@OK9>#IH>BZ8E1TQ,#OJ>O]N20[XDQW^NO]I)1#S/24#1+!WXO
|
| 71 |
+
M&?F]OH0E!G\O&?T]$FY/">QR?$(SET_9KN_KD28SO5E84MJ#T9LM[DH0'[:>
|
| 72 |
+
M(C?R-12O_6[<2;SW^L*1?O7CGDB"OZ;#W6%H/54L$:F#/Z6F8)9?MZ_X4L1^
|
| 73 |
+
M^3&4R+X7E:X%]%2=)%ZF)Z31(W'T<HHAXZL)ZXM%T)NEM6@2>%,8ZT72.(HN
|
| 74 |
+
MKA=>G@!42"]FLZ>H9`Y)R;C`QGG%O`*A.=J$)N2(B_)0I39ZJ3IZT5R<C?;3
|
| 75 |
+
M1J.XYO$R72XJ";\]>I9#CTIPE*=&EL1H`HQ;SC2$9-,@AG]WF`/_:K7<Z)1[
|
| 76 |
+
M80BN_32_>Z=@.++9'8;D0$J!YDSO7I13YDQ0![6Q&"Z;W_;BZ"-^QH$@VU/6
|
| 77 |
+
MX3-!2$0A040B[5102:&ZLI0?8@5"LZ%GI@22DB0WWSZ?YY9W*492E8>+HV`9
|
| 78 |
+
MU%<E8\[TF):4OJ(I<IPVOW+.W,DDS;J.^_^@]/P4NG/I'+J3FQUGEYZ^:7-D
|
| 79 |
+
M8/\R\^-.66@Z9S[8F3,A)'29R6!A\24_I&'HQK/>DCEO=I&HU`P?X[:3PDZ/
|
| 80 |
+
M.=.\P@H0=`GR,U`@B.J".)_-]:J!C4]K05E/K`U$ST90/DE%>L5:;.GN%-R(
|
| 81 |
+
M?@@>558+6E(\:;4D4ORO665-)*T7-($&276>W&?!\+[GAIE-:,>'NP>/0+25
|
| 82 |
+
M`=0TIF(7A(N;_AW:^B1:W3TZW,\WZGN.J30Y.-T]/-A+&M%>C4T[U!W;*+3J
|
| 83 |
+
M27AJ1[F+!FLR:'L)X#P`P2':!G(ED]F$QVZ1^1.RG`S[^T>GI_>0%$H$)#C1
|
| 84 |
+
M+@48]RN"C$]":#8NRKBF"CK@X1YM"1)P[LM>6D7WAY4ZJRB;AF"L^<-FZ!UZ
|
| 85 |
+
M4^[OZ0'BJLA9?0PK(2I&K\T2GZ2,BR2\X%!=`<-J5Q6_DK$7:)K\EM!-JW%4
|
| 86 |
+
M4Y4("=UL1S1XJHTMO\2=S1KMW'2@%&]GOQQKIKR`<ZXW*T-1CN!2X%]*;2<*
|
| 87 |
+
M./9M-Z1S*8H.0&]9+8R55E"9J$)N4\W+A#P-(:=-BPIE8I^7@+*3[IMBFW('
|
| 88 |
+
M6$[N&6BT4WY'[)N##@0AWK,([_38+>-1#J2$O8$^`O_WHHY;K[)\#L+[.FY?
|
| 89 |
+
MA19=I?`$-UP'+S)%(<9S`(!I(R(0/J>('W6!!Y4<H<!,F51J:OO"IR<TI6GO
|
| 90 |
+
M5HM!NGMGEJ3<C+)?5BU:B3:#S`L`T1V>:VWQ!O^K1?+PW)$TE1P9TNLKTBGL
|
| 91 |
+
MWYW/+1[+RD',PE+%(JJ[F3K)2<HP,9%YG>',`0I;97PAC'OB_)0J]:,SW;D<
|
| 92 |
+
MJT<7<(J"RR'`HCP"-?54L<0YIS;%I*1=3=).S4H+L*'(/+6I6)U-5FR3Q=KS
|
| 93 |
+
M,L]"ZEGRT\RKIJ,7YZ,7)Z1BS=4$@9A6XDNFX-39-W;!-9>ERE4IG%#)`A.S
|
| 94 |
+
M0-D#=';!.DMI-@M`LC_QJ,..1":G/T)R)1,VV:@FD]1LNR^XWEE,I$LSZ4M,
|
| 95 |
+
M\Z9E/ZO$HVIME17/=-8O/M1)Y^V>Z6=Z((YQ)GD,'KYUF6[JXY`.A,5'T(;F
|
| 96 |
+
MP4@?\ON`C)LQ.O2TZK%7Q^[C^=CXT"-T?;#/VLVWFK>@Z<2EL\'*P;"^-PFY
|
| 97 |
+
MX^")V+6A2>?`3A_N/OK^"1Y3^[[M!R%WV8EA39P7A`KI&,>H[1D/5L3103!*
|
| 98 |
+
M/!`;<,'"P'9-/,,9<L-R[1]-N.`!.,-3F'##XW9].@?H>V=XHA-$Y(.X1GWN
|
| 99 |
+
M4T?$X_,SVYL$`G0*O2X.BD9L$L1-`\<;<Y(IL">@6]P9(Q.Z^0S/1ZOD!5@.
|
| 100 |
+
MB,T)2$AGKFV`_5`#V_-[?!8")7J3X;&XU&66!`<\O!CUP-F*A^Q^"+L;/T7)
|
| 101 |
+
MT\AVP9I&^BPM$IM&TE?:.Y*\@ABA'NYJ41ATTQ4JEU(2HD.&&%E)":=;96)'
|
| 102 |
+
M=QP!%I&$I`N&(`*,)!5+*8KCPE5;+%RY90M7<1]:?4+H<OTIAXC65,HZ;9,\
|
| 103 |
+
MXDY9.N1"S,N$&*Q$P%V(#'>VA"1A>J721'LN0%<'(*>2%?5%6Y2+!?64Q5:!
|
| 104 |
+
M176];<7.K:JA8A!ZLF"))9T4[OP%3-G3+O2TLSUI=T\B".@4+XO1?B"EHA-7
|
| 105 |
+
MT.:T-C`1=?)K@"FL60:6V&BDU'2>%NEG$O!V$7">EA1PGOS.7)0*,>U+$&-`
|
| 106 |
+
MRFJ[M"(D2MG:6G*(7WP-@,[P9[XCD`H((S3MWJ/?9",A+<G58FPW'Z*1U&JX
|
| 107 |
+
M)JUL)82PA_U6(5CB!BO<R"AW5>'!EOAG7U5H:*_"2F-TVRKJK2O%G<@IAM0,
|
| 108 |
+
M/#_4T*\-N=\##S_6?5XMMWOR*F#Z6[&&U=B<4/:4\LKT'3+SAE*;;L`OF;)A
|
| 109 |
+
M$@N39O38B@L-\9?K8I)]N2-;D'.%O!&,=8-ONMX4)O_R--3<XUCSSF,MBE42
|
| 110 |
+
MF#W93D3U3)E6I<>\9+O`?L'3`U8TS5+;E!_`P@9*EU"<>=J6G4`03'97CEZI
|
| 111 |
+
M248J0%J5JT)D,T5N\=@VGK.[CC<:08B#*+CK.-Z4@ISX?(/XC@`2':<2>-(T
|
| 112 |
+
M_6@#Q5,,E8X]I//YRTO4H.^%%N3MOOT"F(:T)6(:;PZ;XGL<5>IU!H'9-J@.
|
| 113 |
+
M#[[3=P)T%70:1+/TEQI!NLI-I'P1F\B?1OK"!B'/7M;DYI5,%Q!.@RB$>D%J
|
| 114 |
+
MK?)ML:14&91-JGJP1\,3WTA4@?M,F/Y%E/!EA8Y2F^:J2@Y()BQ7[@#I+/`-
|
| 115 |
+
M<?Y/\"'.!Q;/$A8/$>*3IN\PK<(J-;TJ3D)B30I_KB`-A^N^*L2BO+;8M6O)
|
| 116 |
+
M9/'<0\SQ?)\/Y#'F+"ZYP*]BB]?Z<?J$.X$B&$E1_YPU$+^&7:*P9J@K!&5-
|
| 117 |
+
M^N<T<2[=)(?H9=DJJM9.5\_EJI=6@7%LZJY>'W*7G^EU2.?/.+J:>J"[02.`
|
| 118 |
+
M7'U0J3/A4)H#WQOM6;J_![,+K35;AT`$]P[>WVS1_:UJ75GM2O'%*[Z5/Q+?
|
| 119 |
+
M@$K7QI7SX*)@ZM)/:7"G/5SX>8-NLM-K11.?0H`J^8$#\80?7*A6DR];R!/[
|
| 120 |
+
MR>^]-GU8HA(0&Q7LLV*;TC;&NDW+?^);!]A1W2<3FP_;RGQ[84>:6.:S!%#^
|
| 121 |
+
MH6T^C3^=(4+\9MIOR,-[8K)Z-SHP2T%DFVA(9`Y:_%&.1<6&<64A(12_^%"P
|
| 122 |
+
M^>I.V4#8E')?S`A""'8G_2`#M".I[R0?+Y`E@'I'^8@`E(H7,L'R961MH(-T
|
| 123 |
+
ME=]IE%\6<CF4-JM'V?.RV@P3R2J3^^8U#4]'1=75=@+O*K__U5RST74':Y0`
|
| 124 |
+
M]<SGS:$]N$H$"^+3:/B-M_+OO[5:&ZW;^>^_==H;___]MZ_C>G!P_ZVW]=<6
|
| 125 |
+
M7EOXKX6%7\Z_/O_\\\\^^^S33S_]]:__YQ=T_3Q[_2R^_I&NG_[TIY]\\LG?
|
| 126 |
+
MT/7QQQ^_?/ER0M>0KH\^^NC)DR<_H.LN75?"S,JO?N>W%A9^?Z&.+\C3PN\:
|
| 127 |
+
M[_S5^&']>W_W3^_N7_OKT[]]_9___2</_YC=^Y=?OO/Z&]_YP]?^\HVWW_CM
|
| 128 |
+
MG_SY?_S;KUZ_\7M_\=&__GS\SC_\]]V?_;WYG]>CO3_X[G??^-[T1F5E_SO_
|
| 129 |
+
MVTX=HB`01'$8]P86FZZXKLS:!8M)4/0P1N]B,HH6XP2C8<($+S#!8#`8MDR8
|
| 130 |
+
MJ,,#PPJV106_WPG>"]\_:26=;J^?-Z?U+%/YNCUKI$JEJ_EV-QG71I5<_Q4O
|
| 131 |
+
M_2^6/]+_8$C_GU#J__Y>",%[7Q1%[/\FKF67I[-PSL7).`EKK3'F*`Y":QV7
|
| 132 |
+
M8B\VHI)GZ!\```````````````!_Y@%8KS5]`'@`````````````````````
|
| 133 |
+
M````````````````````````````````````````````````````````````
|
| 134 |
+
M````````````````````````````````````````````````````````````
|
| 135 |
+
M````````````````````````````````````````````````````````````
|
| 136 |
+
M````````````````````````````````````````````````````````````
|
| 137 |
+
M````````````````````````````````````````````````````````````
|
| 138 |
+
M````````````````````````````````````````````````````````````
|
| 139 |
+
M````````````````````````````````````````````````````````````
|
| 140 |
+
M````````````````````````````````````````````````````````````
|
| 141 |
+
M````````````````````````````````````````````````````````````
|
| 142 |
+
M````````````````````````````````````````````````````````````
|
| 143 |
+
M````````````````````````````````````````````````````````````
|
| 144 |
+
M````````````````````````````````````````````````````````````
|
| 145 |
+
M````````````````````````````````````````````````````````````
|
| 146 |
+
M````````````````````````````````````````````````````````````
|
| 147 |
+
M````````````````````````````````````````````````````````````
|
| 148 |
+
M````````````````````````````````````````````````````````````
|
| 149 |
+
M````````````````````````````````````````````````````````````
|
| 150 |
+
M````````````````````````````````````````````````````````````
|
| 151 |
+
M````````````````````````````````````````````````````````````
|
| 152 |
+
M````````````````````````````````````````````````````````````
|
| 153 |
+
M````````````````````````````````````````````````````````````
|
| 154 |
+
M````````````````````````````````````````````````````````````
|
| 155 |
+
M````````````````````````````````````````````````````````````
|
| 156 |
+
M````````````````````````````````````````````````````````````
|
| 157 |
+
M````````````````````````````````````````````````````````````
|
| 158 |
+
M````````````````````````````````````````````````````````````
|
| 159 |
+
M````````````````````````````````````````````````````````````
|
| 160 |
+
M````````````````````````````````````````````````````````````
|
| 161 |
+
M````````````````````````````````````````````````````````````
|
| 162 |
+
M````````````````````````````````````````````````````````````
|
| 163 |
+
M````````````````````````````````````````````````````````````
|
| 164 |
+
M````````````````````````````````````````````````````````````
|
| 165 |
+
M````````````````````````````````````````````````````````````
|
| 166 |
+
M````````````````````````````````````````````````````````````
|
| 167 |
+
M````````````````````````````````````````````````````````````
|
| 168 |
+
M````````````````````````````````````````````````````````````
|
| 169 |
+
M````````````````````````````````````````````````````````````
|
| 170 |
+
M````````````````````````````````````````````````````````````
|
| 171 |
+
M````````````````````````````````````````````````````````````
|
| 172 |
+
M````````````````````````````````````````````````````````````
|
| 173 |
+
M````````````````````````````````````````````````````````````
|
| 174 |
+
M````````````````````````````````````````````````````````````
|
| 175 |
+
M````````````````````````````````````````````````````````````
|
| 176 |
+
M````````````````````````````````````````````````````````````
|
| 177 |
+
M````````````````````````````````````````````````````````````
|
| 178 |
+
M````````````````````````````````````````````````````````````
|
| 179 |
+
M````````````````````````````````````````````````````````````
|
| 180 |
+
M````````````````````````````````````````````````````````````
|
| 181 |
+
M````````````````````````````````````````````````````````````
|
| 182 |
+
M````````````````````````````````````````````````````````````
|
| 183 |
+
M````````````````````````````````````````````````````````````
|
| 184 |
+
M````````````````````````````````````````````````````````````
|
| 185 |
+
M````````````````````````````````````````````````````````````
|
| 186 |
+
M````````````````````````````````````````````````````````````
|
| 187 |
+
M````````````````````````````````````````````````````````````
|
| 188 |
+
M````````````````````````````````````````````````````````````
|
| 189 |
+
M````````````````````````````````````````````````````````````
|
| 190 |
+
M````````````````````````````````````````````````````````````
|
| 191 |
+
M````````````````````````````````````````````````````````````
|
| 192 |
+
M````````````````````````````````````````````````````````````
|
| 193 |
+
M````````````````````````````````````````````````````````````
|
| 194 |
+
M````````````````````````````````````````````````````````````
|
| 195 |
+
M````````````````````````````````````````````````````````````
|
| 196 |
+
M````````````````````````````````````````````````````````````
|
| 197 |
+
M````````````````````````````````````````````````````````````
|
| 198 |
+
M````````````````````````````````````````````````````````````
|
| 199 |
+
M````````````````````````````````````````````````````````````
|
| 200 |
+
M````````````````````````````````````````````````````````````
|
| 201 |
+
M````````````````````````````````````````````````````````````
|
| 202 |
+
M````````````````````````````````````````````````````````````
|
| 203 |
+
M````````````````````````````````````````````````````````````
|
| 204 |
+
M````````````````````````````````````````````````````````````
|
| 205 |
+
M````````````````````````````````````````````````````````````
|
| 206 |
+
M````````````````````````````````````````````````````````````
|
| 207 |
+
M````````````````````````````````````````````````````````````
|
| 208 |
+
M````````````````````````````````````````````````````````````
|
| 209 |
+
M````````````````````````````````````````````````````````````
|
| 210 |
+
M````````````````````````````````````````````````````````````
|
| 211 |
+
M````````````````````````````````````````````````````````````
|
| 212 |
+
M````````````````````````````````````````````````````````````
|
| 213 |
+
M````````````````````````````````````````````````````````````
|
| 214 |
+
M````````````````````````````````````````````````````````````
|
| 215 |
+
M````````````````````````````````````````````````````````````
|
| 216 |
+
M````````````````````````````````````````````````````````````
|
| 217 |
+
M````````````````````````````````````````````````````````````
|
| 218 |
+
M````````````````````````````````````````````````````````````
|
| 219 |
+
M````````````````````````````````````````````````````````````
|
| 220 |
+
M````````````````````````````````````````````````````````````
|
| 221 |
+
M````````````````````````````````````````````````````````````
|
| 222 |
+
M````````````````````````````````````````````````````````````
|
| 223 |
+
M````````````````````````````````````````````````````````````
|
| 224 |
+
M````````````````````````````````````````````````````````````
|
| 225 |
+
M````````````````````````````````````````````````````````````
|
| 226 |
+
M````````````````````````````````````````````````````````````
|
| 227 |
+
M````````````````````````````````````````````````````````````
|
| 228 |
+
9````````````````````````````````````
|
| 229 |
+
|
SCTK/src/chfilt/chfilt.pl
ADDED
|
@@ -0,0 +1,1042 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env perl
|
| 2 |
+
|
| 3 |
+
### This changes the function of a runtime warning to dump a stack trace
|
| 4 |
+
#use Carp (); local $SIG{__WARN__} = \&Carp::cluck;
|
| 5 |
+
### This dies on a warning after the stack dump
|
| 6 |
+
#use Carp (); local $SIG{__WARN__} = sub { Carp::cluck(); die; };
|
| 7 |
+
#use Carp (); local $SIG{__DIE__} = sub { Carp::cluck(); die; };
|
| 8 |
+
|
| 9 |
+
use strict;
|
| 10 |
+
|
| 11 |
+
# File: chfilt
|
| 12 |
+
# History:
|
| 13 |
+
# version 1.0 Released 950921
|
| 14 |
+
# version 1.1 Released 951006
|
| 15 |
+
# - For Spanish, it now converts a set of predefined words to
|
| 16 |
+
# interjections.
|
| 17 |
+
# - Corrected the order of deleting "--" from the transcripts
|
| 18 |
+
# - Normalized improperly formatted words in (( )) markers
|
| 19 |
+
# version 1.2 Released 951025
|
| 20 |
+
# - The "add_spaces_for_japanese_punctuation" function was splitting
|
| 21 |
+
# words that contained vowel elongation characters
|
| 22 |
+
# - Japapese quotation characters are now removed
|
| 23 |
+
# version 1.3 Released 960418
|
| 24 |
+
# - changed the exit codes to be 0 for successful completion, or
|
| 25 |
+
# 1 otherwise, (thanks Barb).
|
| 26 |
+
# - added English support
|
| 27 |
+
# - modified the main loop to first read in the entire file, then normalize
|
| 28 |
+
# it, by deleting empty lines and concatenating continued lines together.
|
| 29 |
+
# - added the -i option
|
| 30 |
+
# - added the translation flag option "-t"
|
| 31 |
+
# - added the option -I to not make alternations for interjection words.
|
| 32 |
+
# - added the equivalence class option "-q"
|
| 33 |
+
# - added the hyphenated word alternation flag "-a"
|
| 34 |
+
# version 1.4 Released 970711
|
| 35 |
+
# - added a the pem output format
|
| 36 |
+
# - added the -u option
|
| 37 |
+
# ????? is there an unresolved issue for Japanese ????
|
| 38 |
+
# version 1.5 Release 971010
|
| 39 |
+
# - Spanish: installed hesitation filter, removing interjections.
|
| 40 |
+
# - German: installed hesitation filter
|
| 41 |
+
# - Arabic: updated hesitation filter for *romanized script*
|
| 42 |
+
# - removed the -i, -u and -I flags
|
| 43 |
+
# - removed all code that made altenations with NULL
|
| 44 |
+
# - added the '-d' optionally deletable flag
|
| 45 |
+
# version 1.6 Released
|
| 46 |
+
# - For Arabic scoring, translated the arabic script for an apostrophy to a hyphen
|
| 47 |
+
# version 1.7 Released April 7, 1998
|
| 48 |
+
# - fixed a problem with Out-of-Language markers within an unintelligible markers
|
| 49 |
+
# - fixed a problem with unintelligible markers within an OOL markers
|
| 50 |
+
# - added a filter to remove empty optionally deletable flags.
|
| 51 |
+
# Version 1.10
|
| 52 |
+
# JGF updated to new version or perl
|
| 53 |
+
# Version 1.11
|
| 54 |
+
# JGF added support for Miss. State transcript
|
| 55 |
+
# JGF modified the PEM output to pass through the duration times as strings
|
| 56 |
+
# Version 1.12
|
| 57 |
+
# JGF commented out part of the MState code that converted 'OH' and 'AW' to hesitations
|
| 58 |
+
# JGF Correctly handle possessive ancronyms in MState transcripts
|
| 59 |
+
# Version 1.13
|
| 60 |
+
# JGF Added processing for spoken letters. Previously they did not exist.
|
| 61 |
+
# JGF Added code to remove '^' for proper names
|
| 62 |
+
# JGF Corrected the line header extraction code to handle empty transcripts
|
| 63 |
+
# JGF Added -i and -k options
|
| 64 |
+
# JGF Added code to remove 'aside' sgml tags
|
| 65 |
+
# JGF Added -p to pad segment times with silence and -s to smooth segmentations
|
| 66 |
+
# JGF Added -E to exclude overlapping speech
|
| 67 |
+
# Version 1.14
|
| 68 |
+
# JGF Added -c to read contractions
|
| 69 |
+
# JGF disabled all old arabic character-specific processing
|
| 70 |
+
# JGF Uses Getopt::Long now tp process the command line arguments
|
| 71 |
+
# JGF Modified the output for stdout to be "-- -". The new Getopt
|
| 72 |
+
# is interpreting '-' as an ambiguous arguement.
|
| 73 |
+
# Version 1.15
|
| 74 |
+
# JGF added Arabic processing steps for 2004 arabic transcripts. See the Eval
|
| 75 |
+
# plan appendix for Arabic.
|
| 76 |
+
# JGF add use strict pragma
|
| 77 |
+
# Version 1.16
|
| 78 |
+
# JGF added code to check for unannotated, non-posessive contractions IFF contractions
|
| 79 |
+
# are to be processed.
|
| 80 |
+
# Version 1.17
|
| 81 |
+
# JGF Added -C
|
| 82 |
+
# Version 1.18
|
| 83 |
+
# JGF Added two new hesitations
|
| 84 |
+
|
| 85 |
+
my $Version="1.18";
|
| 86 |
+
|
| 87 |
+
my $usage = "Usage: chfilt <OPTIONS> infile outfile|-- -\n".
|
| 88 |
+
"Version: $Version\n".
|
| 89 |
+
"\n".
|
| 90 |
+
"Desc: chfilt converts a Callhome transcription file, 'infile', to STM\n".
|
| 91 |
+
" format, written to 'outfile'. If '-- -' is used as output, the output goes to stdout.\n".
|
| 92 |
+
"\n".
|
| 93 |
+
" OPTIONS :==\n".
|
| 94 |
+
" -l <language> Identifies the language on the transcript\n".
|
| 95 |
+
" Current chfilt can handle: mandarin\n".
|
| 96 |
+
" spanish\n".
|
| 97 |
+
" japanese\n".
|
| 98 |
+
" english\n".
|
| 99 |
+
" arabic\n".
|
| 100 |
+
" german\n".
|
| 101 |
+
" -m Read Miss. State Transcripts\n".
|
| 102 |
+
" -b b_time Output segments After 'b_time'.\n".
|
| 103 |
+
" -e e_time Output segments ending before 'e_time'.\n".
|
| 104 |
+
" -d Output text with optionally deletable tags.\n".
|
| 105 |
+
" -q Word1=Word2\n".
|
| 106 |
+
" Add alternations to the output such that Word1 and Word2\n".
|
| 107 |
+
" are equivalent\n".
|
| 108 |
+
" -t Word1=Word2\n".
|
| 109 |
+
" Translate Word1 to Word2\n".
|
| 110 |
+
" -a Convert all hyphenated word to alternations whereby the \n".
|
| 111 |
+
" two alternations are the word with hyphens deleted, or\n".
|
| 112 |
+
" the word(s) with hyphens converted to spaces\n".
|
| 113 |
+
" -i Add inter-segment gaps to the stm records. This option\n".
|
| 114 |
+
" requires -b and -e to be used\n".
|
| 115 |
+
" -k Keep lines with no lexemes in the transcript rather than\n".
|
| 116 |
+
" ignoring them\n".
|
| 117 |
+
" -o fmt Set the output format to: \n".
|
| 118 |
+
" stm -> Output STM format (default)\n".
|
| 119 |
+
" pem -> Output PEM format\n".
|
| 120 |
+
" -s time Smooth the segmentation (i.e., merge segments) that hava gap\n".
|
| 121 |
+
" intersegment gaps less than 'time'\n".
|
| 122 |
+
" -p time Pad segment boundaries with 'time' seconds of silence if\n".
|
| 123 |
+
" the time is available\n".
|
| 124 |
+
" -c Don't expand the contractions if they are annotated\n".
|
| 125 |
+
" -C (numbers|letters)\n".
|
| 126 |
+
" If 'numbers', change channels A and B to 1 and 2 respectively \n".
|
| 127 |
+
" If 'letters', change channels 1 and 2 to A and B respectively \n".
|
| 128 |
+
" -E Exclude overlapping segments in the output STMs\n";;
|
| 129 |
+
|
| 130 |
+
##########3 Globals
|
| 131 |
+
my $Language;
|
| 132 |
+
my $OptDel;
|
| 133 |
+
my ($NewBeginTime, $NewEndTime);
|
| 134 |
+
my $Format;
|
| 135 |
+
my $KeepEmptyLines;
|
| 136 |
+
my @Translate;
|
| 137 |
+
my @Equivs;
|
| 138 |
+
my $AltHyphens;
|
| 139 |
+
my $ReadMSstate;
|
| 140 |
+
my $ExcludeOverlap;
|
| 141 |
+
my $PadSilence;
|
| 142 |
+
my $SmoothSegments;
|
| 143 |
+
my $ExpandContractions;
|
| 144 |
+
my $AddInterSegGap;
|
| 145 |
+
my $HES;
|
| 146 |
+
my $InFile;
|
| 147 |
+
my $OutFile;
|
| 148 |
+
my $id;
|
| 149 |
+
my %TranslateAArray;
|
| 150 |
+
my %EquivsAArray;
|
| 151 |
+
my @Trans;
|
| 152 |
+
my $ChannelsTo = "asis";
|
| 153 |
+
|
| 154 |
+
use Getopt::Long;
|
| 155 |
+
$Getopt::Long::ignorecase = 0;
|
| 156 |
+
my $ret = GetOptions ("s:f", "p:f", "l=s", "b:f", "e:f", "o=s", "t:s", "q:s", "a", "d", "m", "i", "k", "E", "c", "C=s");
|
| 157 |
+
die "\n$usage\nError: Failed to parse argements" if (! $ret);
|
| 158 |
+
if (defined($main::opt_o)) {
|
| 159 |
+
$Format = $main::opt_o;
|
| 160 |
+
if($Format !~ /^(stm|pem)$/){
|
| 161 |
+
print "\n$usage\nError: Unrecognized format type --> $Format\n\n";
|
| 162 |
+
exit 1;
|
| 163 |
+
}
|
| 164 |
+
} else {
|
| 165 |
+
$Format = "stm";
|
| 166 |
+
}
|
| 167 |
+
if (!defined($main::opt_l)){
|
| 168 |
+
print "\n$usage\nError: Language option is required\n\n";
|
| 169 |
+
exit 1;
|
| 170 |
+
} else {
|
| 171 |
+
$Language = $main::opt_l;
|
| 172 |
+
if ($Language !~ /japanese/ &&
|
| 173 |
+
$Language !~ /mandarin/ &&
|
| 174 |
+
$Language !~ /english/ &&
|
| 175 |
+
$Language !~ /spanish/ &&
|
| 176 |
+
$Language !~ /arabic/ &&
|
| 177 |
+
$Language !~ /german/) {
|
| 178 |
+
print "\n$usage\nError: Language not recognized\n\n";
|
| 179 |
+
exit 1;
|
| 180 |
+
}
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
if (defined($main::opt_b)) { $NewBeginTime = $main::opt_b; } else { $NewBeginTime = 0.0}
|
| 184 |
+
if (defined($main::opt_e)) { $NewEndTime = $main::opt_e; } else { $NewEndTime = 999999; }
|
| 185 |
+
if (defined($main::opt_k)) { $KeepEmptyLines= $main::opt_k; } else { $KeepEmptyLines = 0; }
|
| 186 |
+
if (defined($main::opt_t)) { @Translate = split(/:/,$main::opt_t); } else { @Translate = (); }
|
| 187 |
+
if (defined($main::opt_q)) { @Equivs = split(/:/,$main::opt_q); } else { @Equivs = (); }
|
| 188 |
+
if (defined($main::opt_a)) { $AltHyphens = 1; $main::opt_a = 1; } else{ $AltHyphens = 0;$main::opt_a=0;}
|
| 189 |
+
if (defined($main::opt_m)) { $ReadMSstate = 1; $main::opt_m = 1; } else{ $ReadMSstate = 0;$main::opt_m=0;}
|
| 190 |
+
if (defined($main::opt_E)) { $ExcludeOverlap = $main::opt_E } else{ $ExcludeOverlap = 0}
|
| 191 |
+
if (defined($main::opt_p)) { $PadSilence = $main::opt_p } else{ $PadSilence = -1.0}
|
| 192 |
+
if (defined($main::opt_s)) { $SmoothSegments = $main::opt_s } else{ $SmoothSegments = -1.0}
|
| 193 |
+
if (defined($main::opt_c)) { $ExpandContractions = !(defined($main::opt_c))} else{ $ExpandContractions = 1}
|
| 194 |
+
if (defined($main::opt_C)) {
|
| 195 |
+
die "Error: Unknown channel conversion '$main::opt_C'" if ($main::opt_C !~ /^(numbers|letters)/);
|
| 196 |
+
$ChannelsTo = $main::opt_C;
|
| 197 |
+
}
|
| 198 |
+
$AddInterSegGap = defined($main::opt_i);
|
| 199 |
+
die "$usage\nError: -i requires -b and -e to be used"
|
| 200 |
+
if (defined($main::opt_i) && (! defined($main::opt_b) || !defined($main::opt_e)));
|
| 201 |
+
|
| 202 |
+
if (defined($main::opt_d)) {
|
| 203 |
+
$OptDel = 1; $main::opt_d = 1;
|
| 204 |
+
$HES = " (%HESITATION) ";
|
| 205 |
+
} else {
|
| 206 |
+
$OptDel = 0; $main::opt_d = 0;
|
| 207 |
+
$HES = "%HESITATION";
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
#### The main functions arguments:
|
| 211 |
+
if ($#ARGV > 1) { print "\n$usage\nToo many arguments \n\n"; exit 1; }
|
| 212 |
+
if ($#ARGV == 0) { print "\n$usage\nOutput Not Specified\n\n"; exit 1; }
|
| 213 |
+
if ($#ARGV == -1) { print "\n$usage\nInput and Output Not Specified\n\n";
|
| 214 |
+
exit 1; }
|
| 215 |
+
|
| 216 |
+
$InFile=$ARGV[0];
|
| 217 |
+
$OutFile=$ARGV[1];
|
| 218 |
+
|
| 219 |
+
if (! -r $InFile){
|
| 220 |
+
print "\n$usage\nInput file $InFile does not exist\n\n";
|
| 221 |
+
exit 1;
|
| 222 |
+
}
|
| 223 |
+
|
| 224 |
+
if ($OutFile eq "-"){
|
| 225 |
+
$OutFile = "";
|
| 226 |
+
} else {
|
| 227 |
+
$OutFile = " > ".$OutFile;
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
($id=$InFile) =~ s:^.*/::;
|
| 231 |
+
$id =~ s/\.[^\.]*$//;
|
| 232 |
+
|
| 233 |
+
# Check the translation classes. If they exist, make an associative
|
| 234 |
+
# array to house them
|
| 235 |
+
if ($#Translate >= 0){
|
| 236 |
+
foreach my $tlate (@Translate){
|
| 237 |
+
$tlate =~ tr/a-z/A-Z/;
|
| 238 |
+
if ($Language eq "german" || $Language eq "spanish") {
|
| 239 |
+
$tlate =~ tr/\340-\377/\300-\337/; #Upper-Case accented letters
|
| 240 |
+
}
|
| 241 |
+
my @tl = split(/=/,$tlate);
|
| 242 |
+
$TranslateAArray{$tl[0]} = $tl[1];
|
| 243 |
+
}
|
| 244 |
+
}
|
| 245 |
+
|
| 246 |
+
# Check the equivalence classes. If they exist, make an associative
|
| 247 |
+
# array to house them
|
| 248 |
+
if ($#Equivs >= 0){
|
| 249 |
+
foreach my $equiv (@Equivs){
|
| 250 |
+
$equiv =~ tr/a-z/A-Z/;
|
| 251 |
+
if ($Language eq "german" || $Language eq "spanish") {
|
| 252 |
+
$equiv =~ tr/\340-\377/\300-\337/; #Upper-Case accented letters
|
| 253 |
+
}
|
| 254 |
+
my $alt;
|
| 255 |
+
($alt = $equiv) =~ s/^/{ /;
|
| 256 |
+
$alt =~ s/$/ }/;
|
| 257 |
+
$alt =~ s:=: / :g;
|
| 258 |
+
foreach my $eq (split(/=/,$equiv)){
|
| 259 |
+
$EquivsAArray{$eq} = $alt;
|
| 260 |
+
}
|
| 261 |
+
}
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
open(FILE,"< $InFile") || die("cannot open input Callhome file $InFile");
|
| 265 |
+
#binmode FILE;
|
| 266 |
+
|
| 267 |
+
my $hubscr_path = "../hubscr/hubscr.pl";
|
| 268 |
+
die "ERROR: 'hubscr.pl' cannot be found, please edit 'chfilt.pl line 267 and set hubscr.pl path."if(! -e $hubscr_path);
|
| 269 |
+
|
| 270 |
+
#open(OUTPUT,"| sort -t \\ +0 -1 +1 -2 +3nb -4 $OutFile") ||
|
| 271 |
+
open(OUTPUT,"| perl $hubscr_path sortSTM $OutFile") ||
|
| 272 |
+
die("cannot open output file $OutFile");
|
| 273 |
+
|
| 274 |
+
## make a place holder for the LUR reports
|
| 275 |
+
print OUTPUT ';; CATEGORY "0" "" ""'."\n";
|
| 276 |
+
print OUTPUT ';; LABEL "O" "Overall" "All Segments in the test set"'."\n";
|
| 277 |
+
|
| 278 |
+
# read in the file, deleting blank lines:
|
| 279 |
+
while (<FILE>){
|
| 280 |
+
s/\[\[[^]]*\]\]//g; #remove comments '[[words]]'
|
| 281 |
+
|
| 282 |
+
if ($_ !~ /^\s*$/ && $_ !~ /^#/){
|
| 283 |
+
if ($ReadMSstate){
|
| 284 |
+
s/^\S+\s+//;
|
| 285 |
+
}
|
| 286 |
+
push(@Trans,$_);
|
| 287 |
+
}
|
| 288 |
+
}
|
| 289 |
+
close (FILE);
|
| 290 |
+
|
| 291 |
+
# normalize the transcript so that each turn is on a line by itself
|
| 292 |
+
for (my $n=0; $n<=$#Trans; $n++){
|
| 293 |
+
if ($Trans[$n] =~ /^\s*\d+\.\d*\s+\d+\.\d*\s+[AB]\d*:/){
|
| 294 |
+
my $orig = $Trans[$n];
|
| 295 |
+
if ($ExpandContractions){
|
| 296 |
+
### Scan the transcript looking for un-annotated non-possessive contractions
|
| 297 |
+
my $ct = $Trans[$n];
|
| 298 |
+
### delete all tokens annotated as contractions
|
| 299 |
+
$ct =~ s/(<contraction\s+e_form=\"([^\"]+)\">([^ \t\n\r\f\)]+))//gi;
|
| 300 |
+
foreach my $ctt(split(/[\s\,\.\?]+/,$ct)){
|
| 301 |
+
print STDERR "Warning: Possible non-annotated contraction \"$ctt\"\n" if ($ctt =~ /\w'\w+/ && $ctt !~ /\w's$/);
|
| 302 |
+
}
|
| 303 |
+
}
|
| 304 |
+
while ($Trans[$n] =~ /(<contraction\s+e_form=\"([^\"]+)\">([^ \t\n\r\f\)]+))/i){
|
| 305 |
+
my ($tag, $rep, $token) = (quotemeta($1), $2, $3);
|
| 306 |
+
my $exp;
|
| 307 |
+
($exp = $rep) =~ s/\[[^\[=]+=>/ /g;
|
| 308 |
+
$exp =~ s/\]//g;
|
| 309 |
+
$exp =~ s/^\s+//g;
|
| 310 |
+
|
| 311 |
+
# print "Found $tag $rep $token '$exp' ------------ in $Trans[$n]";
|
| 312 |
+
if ($ExpandContractions){
|
| 313 |
+
$Trans[$n] =~ s/$tag/$exp/;
|
| 314 |
+
} else {
|
| 315 |
+
$Trans[$n] =~ s/$tag/$token/;
|
| 316 |
+
}
|
| 317 |
+
die "Error: unable to expand the contraction\n" if ($orig eq $Trans[$n]);
|
| 318 |
+
$orig = $Trans[$n];
|
| 319 |
+
}
|
| 320 |
+
die "Error: Contraction not handled $Trans[$n]" if ($Trans[$n] =~ /<contrac/);
|
| 321 |
+
} else {
|
| 322 |
+
# print "no match $Trans[$n]";
|
| 323 |
+
if ($n == 0){
|
| 324 |
+
die("Illegal format, first line does not have a begin time, end time and channel");
|
| 325 |
+
}
|
| 326 |
+
chop($Trans[$n - 1]);
|
| 327 |
+
$Trans[$n - 1] = $Trans[$n - 1]." ".$Trans[$n];
|
| 328 |
+
splice(@Trans,$n,1);
|
| 329 |
+
$n--;
|
| 330 |
+
}
|
| 331 |
+
}
|
| 332 |
+
|
| 333 |
+
#print @Trans;
|
| 334 |
+
|
| 335 |
+
my @STMS = ();
|
| 336 |
+
|
| 337 |
+
### Normalize the text
|
| 338 |
+
foreach $_ (@Trans){
|
| 339 |
+
#match the lines header
|
| 340 |
+
chomp;
|
| 341 |
+
die "Unable to strip the line header of '$_'" unless s/^(.*[AB][0-9]*):\s*//;
|
| 342 |
+
my $line_header = $1; #Store the header in a variable
|
| 343 |
+
|
| 344 |
+
tr/\011/ /; #change all tabs to spaces
|
| 345 |
+
s/ / /g; #multiple spaces go to one
|
| 346 |
+
s/^/ /; #add spaces at begining of line
|
| 347 |
+
s/$/ /; #put a space at the end of each line
|
| 348 |
+
s/\s\(\(/ (( /g; #add spaces around unintelligble markers
|
| 349 |
+
s/\)\)\s/ )) /g; #add spaces around unintelligble markers
|
| 350 |
+
if ($OptDel == 0){
|
| 351 |
+
s:<foreign\s+language=[^>]+>([^><]+)</foreign>:$1:gi;
|
| 352 |
+
} else {
|
| 353 |
+
s/\(\(\s*<foreign\s+language=\"[^"]+\">([^><]+)<\/foreign>\s*\)\)/\(\($1\)\)/gi;
|
| 354 |
+
s/<foreign\s+language=\"[^"]+\">([^><]+)<\/foreign>/\(\($1\)\)/gi;
|
| 355 |
+
}
|
| 356 |
+
#print "$_ here\n";
|
| 357 |
+
if ($Language ne "arabic") {
|
| 358 |
+
tr/a-z/A-Z/; #Upper-Case all letters
|
| 359 |
+
if ($Language eq "german" || $Language eq "spanish") {
|
| 360 |
+
tr/\340-\377/\300-\337/ #Upper-Case accented letters
|
| 361 |
+
}
|
| 362 |
+
}
|
| 363 |
+
s/\{[^{}]*\}//g; #remove non-speech vocal noises '{words}'
|
| 364 |
+
|
| 365 |
+
### LANGUAGE Specific Normalizations
|
| 366 |
+
if ($Language eq "arabic") {
|
| 367 |
+
my $hes;
|
| 368 |
+
if ($OptDel == 0){
|
| 369 |
+
$hes="%\330\252\330\261\330\257\331\221\330\257";
|
| 370 |
+
} else {
|
| 371 |
+
$hes=" (%\330\252\330\261\330\257\331\221\330\257) ";
|
| 372 |
+
}
|
| 373 |
+
s/[% ]\330\243\331\207 /$hes /g; ## %>h
|
| 374 |
+
s/[% ]\330\245\331\212\331\207 /$hes /g; ## %<yh
|
| 375 |
+
s/[% ]\330\243\331\205 /$hes /g; ## >m
|
| 376 |
+
s/[% ]\330\243\331\210\331\210 /$hes /g; ## >ww
|
| 377 |
+
s/[% ]\331\207\330\247\331\212 /$hes /g; ## hAy
|
| 378 |
+
s/[% ]\331\205\331\207\331\205 /$hes /g; ## mhm
|
| 379 |
+
|
| 380 |
+
s/%*(\330\243\331\207\331\207) /$1 /g; ## Back Channel
|
| 381 |
+
s/%\330\243\330\254\331\206\330\250\331\212 / /g; ## Foreign lexeme
|
| 382 |
+
s/%\330\252\330\257\330\247\330\256\331\204.*%\330\252\330\257\330\247\330\256\331\204\\ / /g; ## End cross channel
|
| 383 |
+
|
| 384 |
+
### Remove non speech markers
|
| 385 |
+
s/%\330\265\331\205\330\252\\* / /g; # silence
|
| 386 |
+
s/%\330\245\331\206\331\202\330\267\330\247\330\271\\* / /g; # pause symbol
|
| 387 |
+
s/%\330\266\330\254\331\221\330\251\\* / /g; # noise symbol
|
| 388 |
+
s/%\330\252\331\206\331\201\331\221\330\263\\* / /g; # breath symbol
|
| 389 |
+
s/%\330\263\330\271\330\247\331\204\\* / /g; # cough
|
| 390 |
+
s/%\330\266\330\255\331\203\\* / /g; # laugh
|
| 391 |
+
s/%\330\243\330\265\331\210\330\247\330\252\\* / /g; # people talk
|
| 392 |
+
|
| 393 |
+
# ## The LDC Transcripts have a special case encoded in them for
|
| 394 |
+
# ## foreign words with an attached definite article. The next few commands
|
| 395 |
+
# ## move the definite article into the foreign tag.
|
| 396 |
+
# s/\s(\S+)(<\S+)\s+(\S+)/ $2 $1$3/g;
|
| 397 |
+
# ## translate the arabic signle apostrophies to hyphens
|
| 398 |
+
# s/\254\s/- /g;
|
| 399 |
+
# s/\254$/- /g;
|
| 400 |
+
# s/\s\254/ -/g;
|
| 401 |
+
# ## Arabic Semi colon
|
| 402 |
+
# s/\s\273/ /g;
|
| 403 |
+
} elsif ($Language eq "english") {
|
| 404 |
+
;
|
| 405 |
+
} elsif ($Language eq "japanese") {
|
| 406 |
+
$_ = &add_spaces_for_japanese_punctuation($_);
|
| 407 |
+
s/\241\242 /, /g; # Change the Japanese coma
|
| 408 |
+
s/\241\243 /. /g; # Change the Japanese periods
|
| 409 |
+
s/\241\244 /, /g; # Change the Japanese periods
|
| 410 |
+
s/\241\250 /; /g; # Change the Japanese semi-colon
|
| 411 |
+
s/\241\251 /? /g; # Change the Japanese question marks
|
| 412 |
+
s/\241\252 /! /g; # Change the Japanese exclaimation marks
|
| 413 |
+
s/\241\327 / /g; # Change the Japanese quotation mark
|
| 414 |
+
s/ \241\326/ /g; # Change the Japanese quotation mark
|
| 415 |
+
s/\241\343([\000-\177])/<$1/g; # Change the Japanese '<'
|
| 416 |
+
s/([\000-\177])\241\344/$1>/g; # Change the Japanese '>'
|
| 417 |
+
# Convert Japanese col and dia flags to alternations
|
| 418 |
+
s/@([^@\[\]]+)\[\[([^,\[\]]+)\s*,[^\[\]]+\]\]/ { $1 \/ $2 } /g;
|
| 419 |
+
} elsif ($Language eq "mandarin") {
|
| 420 |
+
while (s/(<[^_>]*)_/$1 /) { # Removes underlines from OOL items
|
| 421 |
+
;
|
| 422 |
+
}
|
| 423 |
+
s/@([^@]+)@/$1/g; # Removes obviously the @'s !!!
|
| 424 |
+
s/\*([^\*]+)\*/$1/g; # Removes obviously the *'s !!!
|
| 425 |
+
}
|
| 426 |
+
|
| 427 |
+
### Call Home filtering (General)
|
| 428 |
+
|
| 429 |
+
s/\-\-//g; #whatever they are??
|
| 430 |
+
s/[.,?!;]//g; #Remove normal punctuation
|
| 431 |
+
s/"//g; #Remove quotation marks
|
| 432 |
+
s/\#/ /g; #remove simultaneous speech markers '#'
|
| 433 |
+
s/\[\[[^]]*\]\]//g; #remove comments '[[words]]'
|
| 434 |
+
s/\[[^]]*\]//g; #remove other sounds '[words]'
|
| 435 |
+
s/\/\///g; #remove speech to someone else markers '//'
|
| 436 |
+
s/<\/*aside\/*>//g; #remove aside sgml tags
|
| 437 |
+
|
| 438 |
+
if ($ReadMSstate){
|
| 439 |
+
s/\^(\S)/$1/g; #remove proper name markers? '^'
|
| 440 |
+
s/\*(\S)/$1/g; #remove ??? name markers? '*'
|
| 441 |
+
s/\@(\S)/$1/g; #remove ??? name markers? '@'
|
| 442 |
+
s:<as/>[^<>]+</as>::ig; #remove asides
|
| 443 |
+
while ($_ =~ /~/){ # Deal with acronyms
|
| 444 |
+
s/~(\S) /$1 /;
|
| 445 |
+
s/~(\S\'[sS]) /$1 /; # Deal with a possessive acronym
|
| 446 |
+
s/~(\S)(\S)/$1 ~$2/;
|
| 447 |
+
}
|
| 448 |
+
}
|
| 449 |
+
|
| 450 |
+
s/\(\(\s*\)\)//g; #remove unintelligable speech with no words
|
| 451 |
+
|
| 452 |
+
## Changes from new LDC transcription practices (Jan 2003)_
|
| 453 |
+
s/~([A-Z-a-z])/$1./g; #Change the spoken letters to the Hub4 form
|
| 454 |
+
s/\^//g; #Remove proper names
|
| 455 |
+
|
| 456 |
+
|
| 457 |
+
if ($OptDel == 1){
|
| 458 |
+
s/\(\s+/(/g; #Normalize the variablity in the LDC trans
|
| 459 |
+
s/\s+\)/)/g; #Normalize the variablity in the LDC trans
|
| 460 |
+
my $vb = 0;
|
| 461 |
+
my $iteration = 1;
|
| 462 |
+
print "Start $_\n" if ($vb);
|
| 463 |
+
my $loop_end = "xxxxxxxxxxxxxxxxx";
|
| 464 |
+
|
| 465 |
+
my $plainWord = "[^ \t\n\r\f\(\)\{\}]+";
|
| 466 |
+
my $optDelWord = "\\([^ \t\n\r\f\(\)\{\}]+\\)";
|
| 467 |
+
# my $wordSet = "($plainWord|$optDelWord)(\s+($plainWord|$optDelWord))*";
|
| 468 |
+
|
| 469 |
+
while ($_ =~ /\(\(.*\)\)/) {
|
| 470 |
+
# if the unintell is out side of a OOL marker, just delete them
|
| 471 |
+
s/\(\((\s*<[^>]+>\s*)\)\)/$1/;
|
| 472 |
+
print " Step 1 $_\n" if ($vb);
|
| 473 |
+
|
| 474 |
+
# handle unintelligle markers within OOL markers
|
| 475 |
+
s/\(\((\s*<[^>]+>\s*)([^\)]*)\)\)/$1 \(\($2\)\)/;
|
| 476 |
+
print " Step 2 $_\n" if ($vb);
|
| 477 |
+
|
| 478 |
+
#Change 1st unintelligable word, if its already optionally deletable
|
| 479 |
+
s/\(\(\s*($optDelWord)\s+(($plainWord|$optDelWord)(\s+($plainWord|$optDelWord))*\s*\)\))/ $1 \(\($2/g;
|
| 480 |
+
print " Step 3 $_\n" if ($vb);
|
| 481 |
+
|
| 482 |
+
#Change 1st unintelligable word, if its an alternate
|
| 483 |
+
s:\(\(\s*({[^{}]+})\s+(($plainWord|$optDelWord)(\s+($plainWord|$optDelWord))*\s*\)\)): \($1\) \(\($2:g;
|
| 484 |
+
print " Step 4 $_\n" if ($vb);
|
| 485 |
+
|
| 486 |
+
#Change 1st unintelligable word, if its a plain word
|
| 487 |
+
s/\(\(\s*($plainWord)\s+(($plainWord|$optDelWord)(\s+($plainWord|$optDelWord))*\s*\)\))/ \($1\) \(\($2/g;
|
| 488 |
+
print " Step 5 $_\n" if ($vb);
|
| 489 |
+
|
| 490 |
+
## Change a single optionally deletable word
|
| 491 |
+
s/\(\(\s*($optDelWord)\s*\)\)/ $1 /g;
|
| 492 |
+
print " Step 8 $_\n" if ($vb);
|
| 493 |
+
|
| 494 |
+
#alternate single unintelligable with alternate
|
| 495 |
+
s/\(\(\s*({[^{}]+})\s*\)\)/ \($1\) /g;
|
| 496 |
+
print " Step 9 $_\n" if ($vb);
|
| 497 |
+
|
| 498 |
+
#alternate single unintelligable words
|
| 499 |
+
s/\(\(\s*($plainWord)\s*\)\)/ \($1\) /g;
|
| 500 |
+
print " Step A $_\n" if ($vb);
|
| 501 |
+
|
| 502 |
+
# remove empty unintellegible markers
|
| 503 |
+
s/\(\(\s*\)\)//g;
|
| 504 |
+
$iteration ++;
|
| 505 |
+
|
| 506 |
+
if ($_ eq $loop_end){
|
| 507 |
+
print STDERR "Warning: unable to fully alternate an unitelligible marker\n".
|
| 508 |
+
" $_\n";
|
| 509 |
+
last;
|
| 510 |
+
}
|
| 511 |
+
if ($iteration > 100){
|
| 512 |
+
die "Unable to alternate an unitelligible marker '$_'\n";
|
| 513 |
+
}
|
| 514 |
+
# Remember what the last line was so that We don't get it an infinite loop
|
| 515 |
+
$loop_end = $_;
|
| 516 |
+
print " End $_\n" if ($vb);
|
| 517 |
+
}
|
| 518 |
+
} else {
|
| 519 |
+
# print "Delete (( $_\n";
|
| 520 |
+
s/\s\(\(/ /g; #Strip the unintelligible markers
|
| 521 |
+
s/\)\)\s/ /g; #Strip the unintelligible markers
|
| 522 |
+
# print " $_\n";
|
| 523 |
+
}
|
| 524 |
+
|
| 525 |
+
if (! $OptDel){
|
| 526 |
+
s/<\s*\S+\s+([^<>]*)>/$1/g; #remove out-of-language speech markers
|
| 527 |
+
s/<[^<>]*>//g; #remove out-of-language speech markers
|
| 528 |
+
} else {
|
| 529 |
+
while ($_ =~ /(<\s*\S+\s+)([^<>]*)>/) {
|
| 530 |
+
my ($otxt, $head) = ($2, $1);
|
| 531 |
+
my $txt = $otxt;
|
| 532 |
+
$txt =~ s/^\s+//;;
|
| 533 |
+
$txt =~ s/\s+$//;;
|
| 534 |
+
my $new= "";
|
| 535 |
+
foreach my $w(split(/\s+/,$txt)){
|
| 536 |
+
if ($w !~ /^\(.+\)$/){
|
| 537 |
+
if ($new eq ""){
|
| 538 |
+
$new = "(".$w.")";
|
| 539 |
+
} else {
|
| 540 |
+
$new .= " (".$w.")";
|
| 541 |
+
}
|
| 542 |
+
} else {
|
| 543 |
+
$new .= " $w";
|
| 544 |
+
}
|
| 545 |
+
}
|
| 546 |
+
if ( ($_ =~ s/${head}[^>]*>/$new/) != 1){
|
| 547 |
+
die("OptDel substitution of non-language marker failed\n".
|
| 548 |
+
" text: $_ head: '$head'\n otxt: '$otxt'\n new: '$new'".
|
| 549 |
+
"\n merge: '${head}${otxt}>'");
|
| 550 |
+
}
|
| 551 |
+
}
|
| 552 |
+
### delete noise tags. These are new as of 1/20/2004
|
| 553 |
+
s/<[^ \t\n\r\f<>]+>//g;
|
| 554 |
+
}
|
| 555 |
+
|
| 556 |
+
### Language Specific Filters
|
| 557 |
+
|
| 558 |
+
# SPANISH
|
| 559 |
+
if ($Language eq "spanish") {
|
| 560 |
+
y/\240-\277//d; #remove spanish punctuation
|
| 561 |
+
s/\*\*//g; #words marked with "**" (as neologisms or unknown
|
| 562 |
+
# 'words')
|
| 563 |
+
s/\+//g; #words marked with "++" (mispronunciations given
|
| 564 |
+
# in correct orthography)
|
| 565 |
+
|
| 566 |
+
# map the list of hesitiation's
|
| 567 |
+
s:%::g; # remove all hesitation markers (maybe illegal ones!)
|
| 568 |
+
# insert all hesitation markers (maybe missed ones!)
|
| 569 |
+
s/ AAA / $HES /g;
|
| 570 |
+
s/ EEE / $HES /g;
|
| 571 |
+
s/ III / $HES /g;
|
| 572 |
+
s/ MMM / $HES /g;
|
| 573 |
+
s/ EMM / $HES /g;
|
| 574 |
+
s/ AMM / $HES /g;
|
| 575 |
+
s/ IMM / $HES /g;
|
| 576 |
+
s/ EH / $HES /g;
|
| 577 |
+
s/ MMH / $HES /g;
|
| 578 |
+
s/ OH / $HES /g;
|
| 579 |
+
s/ UH / $HES /g;
|
| 580 |
+
s/ EY / $HES /g;
|
| 581 |
+
s/ UY / $HES /g;
|
| 582 |
+
s/ PSS / $HES /g;
|
| 583 |
+
s/ HM / $HES /g;
|
| 584 |
+
s/ UF / $HES /g;
|
| 585 |
+
s/ SHH / $HES /g;
|
| 586 |
+
s/ PFF / $HES /g;
|
| 587 |
+
s/ OY / $HES /g;
|
| 588 |
+
s/ HA / $HES /g;
|
| 589 |
+
s/ AH / $HES /g;
|
| 590 |
+
}
|
| 591 |
+
|
| 592 |
+
# GERMAN
|
| 593 |
+
if ($Language eq "german") {
|
| 594 |
+
|
| 595 |
+
s/\&//g; #remove proper name marker
|
| 596 |
+
s/\+//g; #words marked with "++" (mispronunciations given
|
| 597 |
+
# in correct orthography)
|
| 598 |
+
s/\*\*//g; #words marked with "**" (as neologisms
|
| 599 |
+
# or unknown 'words')
|
| 600 |
+
|
| 601 |
+
s:%::g; # remove all hesitation markers (maybe illegal ones!)
|
| 602 |
+
# insert all hesitation markers (maybe missed ones!)
|
| 603 |
+
|
| 604 |
+
s/ �H / $HES /g;
|
| 605 |
+
s/ MM / $HES /g;
|
| 606 |
+
s/ �HM / $HES /g;
|
| 607 |
+
s/ HM / $HES /g;
|
| 608 |
+
s/ HA / $HES /g;
|
| 609 |
+
s/ EI / $HES /g;
|
| 610 |
+
s/ UH / $HES /g;
|
| 611 |
+
s/ H� / $HES /g;
|
| 612 |
+
s/ HO / $HES /g;
|
| 613 |
+
s/ UFF / $HES /g;
|
| 614 |
+
s/ OI / $HES /g;
|
| 615 |
+
s/ HUH / $HES /g;
|
| 616 |
+
s/ BAH / $HES /g;
|
| 617 |
+
s/ UI / $HES /g;
|
| 618 |
+
}
|
| 619 |
+
|
| 620 |
+
|
| 621 |
+
# ARABIC
|
| 622 |
+
if ($Language eq "arabic") {
|
| 623 |
+
|
| 624 |
+
s/\&//g; #remove proper name the marker
|
| 625 |
+
s/\s\+(\S+)\+\s/ $1 /; #Remove the plus markers
|
| 626 |
+
# s:%\S+\s::g; # remove all hesitation markers (maybe illegal ones!)
|
| 627 |
+
s/\*\*//g; #words marked with "**" (as neologisms
|
| 628 |
+
# or unknown 'words')
|
| 629 |
+
s/$/ /; ## Add a space at the end of the line
|
| 630 |
+
s/ / /; ## Add double spaces
|
| 631 |
+
|
| 632 |
+
# insert all hesitation markers (maybe missed ones!)
|
| 633 |
+
# s/ ah / $HES /g;
|
| 634 |
+
# s/ E / $HES /g;
|
| 635 |
+
# s/ M / $HES /g;
|
| 636 |
+
# s/ mhm / $HES /g;
|
| 637 |
+
# s/ ha / $HES /g;
|
| 638 |
+
# s/ uh / $HES /g;
|
| 639 |
+
# s/ yA / $HES /g;
|
| 640 |
+
# s/ aha / $HES /g;
|
| 641 |
+
# s/ yaa / $HES /g;
|
| 642 |
+
# s/ hm / $HES /g;
|
| 643 |
+
# s/ hum / $HES /g;
|
| 644 |
+
# s/ Ah / $HES /g;
|
| 645 |
+
# s/ ayyO / $HES /g;
|
| 646 |
+
# s/ Eyy / $HES /g;
|
| 647 |
+
# s/ yuu / $HES /g;
|
| 648 |
+
# s/ ih / $HES /g;
|
| 649 |
+
# s/ yO / $HES /g;
|
| 650 |
+
# s/ O / $HES /g;
|
| 651 |
+
# s/ wAw / $HES /g;
|
| 652 |
+
# s/ hi / $HES /g;
|
| 653 |
+
# s/ Hay / $HES /g;
|
| 654 |
+
# s/ yOO / $HES /g;
|
| 655 |
+
# s/ OhO / $HES /g;
|
| 656 |
+
# s/ hE / $HES /g;
|
| 657 |
+
# ### Script equivalences
|
| 658 |
+
# s/ \302\347 / $HES /g;
|
| 659 |
+
# s/ \305\352\347 / $HES /g;
|
| 660 |
+
# s/ \305\352\352\347 / $HES /g;
|
| 661 |
+
# s/ \315\351 / $HES /g;
|
| 662 |
+
# s/ \345 / $HES /g;
|
| 663 |
+
# s/ \307\350 / $HES /g;
|
| 664 |
+
# s/ \307\350\347\350 / $HES /g;
|
| 665 |
+
# s/ \307\347 / $HES /g;
|
| 666 |
+
# s/ \307\347\307 / $HES /g;
|
| 667 |
+
# s/ \307\352\350 / $HES /g;
|
| 668 |
+
# s/ \347\351 / $HES /g;
|
| 669 |
+
# s/ \347\307 / $HES /g;
|
| 670 |
+
# s/ \347\351 / $HES /g;
|
| 671 |
+
# s/ \347\345 / $HES /g;
|
| 672 |
+
# s/ \347\345 / $HES /g;
|
| 673 |
+
# s/ \305\347 / $HES /g;
|
| 674 |
+
# s/ \345\345 / $HES /g;
|
| 675 |
+
# s/ \307\347 / $HES /g;
|
| 676 |
+
# s/ \350\307\350 / $HES /g;
|
| 677 |
+
# s/ \352\307\347 / $HES /g;
|
| 678 |
+
# s/ \352\350 / $HES /g;
|
| 679 |
+
# s/ \352\350\350 / $HES /g;
|
| 680 |
+
# s/ \352\307 / $HES /g;
|
| 681 |
+
# s/ \352\347 / $HES /g;
|
| 682 |
+
}
|
| 683 |
+
|
| 684 |
+
# MANDARIN
|
| 685 |
+
if ($Language eq "mandarin") {
|
| 686 |
+
s/\+//g; #remove non-standard representation marker
|
| 687 |
+
s/\&//g; #remove some the marker
|
| 688 |
+
s/\243[\254\255] / /g; # Remove Japanese punctuation
|
| 689 |
+
|
| 690 |
+
s/\s%(\S)/ $1/g; # Delete the all the percent signs at word head
|
| 691 |
+
s/\s\(\%/ (/g; # Delete the all the percent signs at word head of unclear
|
| 692 |
+
s/%\s/ /g; # Delete the all the percent signs at word tail
|
| 693 |
+
|
| 694 |
+
# NOTE: Cannot remove all hesitation markers because some "%" are used
|
| 695 |
+
# in the text (I think)
|
| 696 |
+
# So we will just filter the known hesitation markers.
|
| 697 |
+
s/\s��\s/ $HES /g;
|
| 698 |
+
s/\s��\s/ $HES /g;
|
| 699 |
+
s/\s��\s/ $HES /g;
|
| 700 |
+
s/\s��\s/ $HES /g;
|
| 701 |
+
s/\s��\s/ $HES /g;
|
| 702 |
+
}
|
| 703 |
+
|
| 704 |
+
# JAPANESE
|
| 705 |
+
if ($Language eq "japanese") {
|
| 706 |
+
s/\+//g; #remove non-standard representation marker
|
| 707 |
+
s/\=/\-/g; #change frag= to frag-
|
| 708 |
+
s/\241[\241-\256] / /g; # Remove Japanese punctuation
|
| 709 |
+
}
|
| 710 |
+
|
| 711 |
+
if ($Language eq "english") {
|
| 712 |
+
s/\&//g; #remove proper name the marker
|
| 713 |
+
s/\*\*//g; #words marked with "**" (as neologisms
|
| 714 |
+
# or unknown 'words')
|
| 715 |
+
s/\*//g; #words marked with "*" idiosyncratic words
|
| 716 |
+
# or unknown 'words')
|
| 717 |
+
s/\+//g; #words marked with "++" (mispronun-
|
| 718 |
+
# ciations given in correct orthography)
|
| 719 |
+
s/@//g; # Spoken acronyms
|
| 720 |
+
### Mapp the hesitations
|
| 721 |
+
s/[\s\(][%]*(UH|UM|EH|MM|AH|HM|HUH|HA|ER|OOF|HEE|ACH|EEE|EW)[\s\)]/ $HES /g;
|
| 722 |
+
if ($ReadMSstate){
|
| 723 |
+
#### Commented out because this should be changed in SPINE
|
| 724 |
+
#### s/[\s\(][%]*(OH|AW)[\s\)]/ $HES /g;
|
| 725 |
+
s/[\s\(][%]*(MHM)[\s\)]/ $1 /g;
|
| 726 |
+
}
|
| 727 |
+
}
|
| 728 |
+
|
| 729 |
+
# This has to be done AFTER ALL THE PROCEEDING STEPS to alternate any fragment words
|
| 730 |
+
if ($OptDel){
|
| 731 |
+
s/(\S+)-(\S+)[-=]\s/ $1 \($2-\) /g; #put in alternates for fragments
|
| 732 |
+
s/(\S*)[-=]\s/ \($1-\) /g; #put in alternates for fragments
|
| 733 |
+
s/\s[-=](\S*)/ \(-$1\) /g; #put in alternates for fragments
|
| 734 |
+
} else {
|
| 735 |
+
s/(\S*)[-=]\s/ $1- /g; #put in alternates for fragments
|
| 736 |
+
s/\s[-=](\S*)/ -$1 /g; #put in alternates for fragments
|
| 737 |
+
}
|
| 738 |
+
s/ +/ /g;
|
| 739 |
+
if ($#Translate >= 0){
|
| 740 |
+
$_ = &Map_AArray($_,\%TranslateAArray);
|
| 741 |
+
}
|
| 742 |
+
if ($#Equivs >= 0){
|
| 743 |
+
$_ = &Map_AArray($_,\%EquivsAArray);
|
| 744 |
+
}
|
| 745 |
+
if ($AltHyphens) {
|
| 746 |
+
$_ = &AlternateHyphenWords($_);
|
| 747 |
+
}
|
| 748 |
+
|
| 749 |
+
### delete any emtpy optionally deletable words
|
| 750 |
+
if ($OptDel){ s/\(\)//g; }
|
| 751 |
+
|
| 752 |
+
my($bt, $et, $spkr) = split(/\s+/,$line_header);
|
| 753 |
+
my $chan;
|
| 754 |
+
($chan = $spkr) =~ s/[0-9]$//;
|
| 755 |
+
if (&in_range($bt, $et) && ($KeepEmptyLines || $_ !~ /^\s*$/)){
|
| 756 |
+
if ($Format eq "stm"){
|
| 757 |
+
push @STMS, sprintf "%s %s %s %s %6.2f <O> %s\n",$id,makeChannel($chan),$id."_".$spkr,$bt,$et,$_;
|
| 758 |
+
} elsif ($Format eq "pem"){
|
| 759 |
+
printf OUTPUT "%s %s %s %s %s\n",$id,makeChannel($chan),"unknown_speaker",$bt,$et;
|
| 760 |
+
}
|
| 761 |
+
}
|
| 762 |
+
}
|
| 763 |
+
|
| 764 |
+
sub makeChannel{
|
| 765 |
+
my ($chan) = @_;
|
| 766 |
+
if ($ChannelsTo eq "numbers") {
|
| 767 |
+
$chan =~ s/a/1/i;
|
| 768 |
+
$chan =~ s/b/2/i;
|
| 769 |
+
} elsif ($ChannelsTo eq "letters") {
|
| 770 |
+
$chan =~ s/1/A/i;
|
| 771 |
+
$chan =~ s/2/B/i;
|
| 772 |
+
} elsif ($ChannelsTo eq "asis") {
|
| 773 |
+
;
|
| 774 |
+
} else {
|
| 775 |
+
die "Error: unknown Channel conversion $ChannelsTo";
|
| 776 |
+
}
|
| 777 |
+
$chan;
|
| 778 |
+
}
|
| 779 |
+
|
| 780 |
+
sub MIN{
|
| 781 |
+
my(@a) = @_;
|
| 782 |
+
my($min) = 99e9;
|
| 783 |
+
|
| 784 |
+
while ($#a >= 0){
|
| 785 |
+
# print " $a[0]\n";
|
| 786 |
+
$min = $a[0] if ($min > $a[0]);
|
| 787 |
+
splice(@a,0,1);
|
| 788 |
+
}
|
| 789 |
+
$min;
|
| 790 |
+
}
|
| 791 |
+
|
| 792 |
+
if ($Format eq "stm"){
|
| 793 |
+
my (%lastStmEnd, %lastStmEndId, %lastStmEndIndex, $nt);
|
| 794 |
+
### Pad the STMs segments with silence if you got it
|
| 795 |
+
if ($PadSilence >= 0){
|
| 796 |
+
for (my $i=0; $i<@STMS; $i++){
|
| 797 |
+
# print "STM[$i] = $STMS[$i]";
|
| 798 |
+
my ($id, $chan, $spkr, $bt, $et, $lur, $text) = split(/\s+/,$STMS[$i],7);
|
| 799 |
+
if (! defined($lastStmEnd{$chan})){
|
| 800 |
+
# print "Set \$lastStmEnd{$chan} = $NewBeginTime;\n";
|
| 801 |
+
$lastStmEnd{$chan} = $NewBeginTime;
|
| 802 |
+
$lastStmEndId{$chan} = $id;
|
| 803 |
+
$lastStmEndIndex{$chan} = $i;
|
| 804 |
+
}
|
| 805 |
+
if ($lastStmEnd{$chan} < $bt){
|
| 806 |
+
my $shift = MIN(($bt - $lastStmEnd{$chan}) / 2.0, $PadSilence);
|
| 807 |
+
if ($lastStmEndIndex{$chan} < $i){
|
| 808 |
+
$nt = sprintf("%.2f", $lastStmEnd{$chan} + $shift);
|
| 809 |
+
# print "fix $nt $STMS[$lastStmEndIndex{$chan}] ";
|
| 810 |
+
die "Can't fix silence pad time of previous line" unless ($STMS[$lastStmEndIndex{$chan}] =~ s/^(\S+\s+\S+\s+\S+\s+\S+\s+)\S+/$1$nt/);
|
| 811 |
+
# print "-> $STMS[$lastStmEndIndex{$chan}]\n";
|
| 812 |
+
}
|
| 813 |
+
$nt = sprintf("%.2f",$bt - $shift);
|
| 814 |
+
die "Can't fix silence pad time" unless ($STMS[$i] =~ s/^(\S+\s+\S+\s+\S+\s+)\S+/$1$nt/);
|
| 815 |
+
}
|
| 816 |
+
$lastStmEnd{$chan} = $et;
|
| 817 |
+
$lastStmEndIndex{$chan} = $i;
|
| 818 |
+
# print " \$lastStmEnd{$chan} = $et\n";
|
| 819 |
+
}
|
| 820 |
+
foreach my $chan(sort(keys %lastStmEnd)){
|
| 821 |
+
my ($id, $ccchan, $spkr, $bt, $et, $lur, $text) = split(/\s+/,$STMS[$lastStmEndIndex{$chan}],7);
|
| 822 |
+
# print "End $STMS[$lastStmEndIndex{$chan}]";
|
| 823 |
+
if ($lastStmEnd{$chan} < $NewEndTime){
|
| 824 |
+
my $shift = MIN(($NewEndTime - $lastStmEnd{$chan}) / 2.0, $PadSilence);
|
| 825 |
+
$nt = $lastStmEnd{$chan} + $shift;
|
| 826 |
+
die "Can't fix silence pad time" unless ($STMS[$lastStmEndIndex{$chan}] =~ s/^(\S+\s+\S+\s+\S+\s+\S+\s+)\S+/$1$nt/);
|
| 827 |
+
# print " end now $STMS[$lastStmEndIndex{$chan}]\n";
|
| 828 |
+
}
|
| 829 |
+
}
|
| 830 |
+
}
|
| 831 |
+
undef %lastStmEnd;
|
| 832 |
+
undef %lastStmEndId;
|
| 833 |
+
|
| 834 |
+
## Smooth the segments
|
| 835 |
+
if ($SmoothSegments >= 0){
|
| 836 |
+
for (my $i=0; $i<@STMS; $i++){
|
| 837 |
+
my ($id, $chan, $spkr, $bt, $et, $lur, $text) = split(/\s+/,$STMS[$i],7);
|
| 838 |
+
if (! defined($lastStmEnd{$chan})){
|
| 839 |
+
$lastStmEnd{$chan} = $NewBeginTime;
|
| 840 |
+
$lastStmEndId{$chan} = $id;
|
| 841 |
+
$lastStmEndIndex{$chan} = $i;
|
| 842 |
+
}
|
| 843 |
+
my $change = 0;
|
| 844 |
+
if ($lastStmEnd{$chan} > $bt - $SmoothSegments && $lastStmEndIndex{$chan} < $i){
|
| 845 |
+
my ($lid, $lchan, $lspkr, $lbt, $let, $llur, $ltext) = split(/\s+/,$STMS[$lastStmEndIndex{$chan}],7);
|
| 846 |
+
if ($id eq $lid && $chan eq $lchan && $spkr eq $lspkr && $lur eq $llur){
|
| 847 |
+
chomp $ltext;
|
| 848 |
+
chomp $text;
|
| 849 |
+
$STMS[$lastStmEndIndex{$chan}] =
|
| 850 |
+
"$id $chan $spkr $lbt $et $lur $ltext $text\n";
|
| 851 |
+
splice (@STMS, $i, 1);
|
| 852 |
+
$i --;
|
| 853 |
+
$change = 1;
|
| 854 |
+
}
|
| 855 |
+
}
|
| 856 |
+
$lastStmEnd{$chan} = $et;
|
| 857 |
+
if (! $change){
|
| 858 |
+
$lastStmEndIndex{$chan} = $i;
|
| 859 |
+
}
|
| 860 |
+
}
|
| 861 |
+
}
|
| 862 |
+
undef %lastStmEnd;
|
| 863 |
+
undef %lastStmEndId;
|
| 864 |
+
|
| 865 |
+
## Smooth the segments
|
| 866 |
+
if ($ExcludeOverlap){
|
| 867 |
+
for (my $i=0; $i<@STMS; $i++){
|
| 868 |
+
# print "STM[$i] = $STMS[$i]";
|
| 869 |
+
my ($id, $chan, $spkr, $bt, $et, $lur, $text) = split(/\s+/,$STMS[$i],7);
|
| 870 |
+
if (! defined($lastStmEnd{$chan})){
|
| 871 |
+
$lastStmEnd{$chan} = $NewBeginTime;
|
| 872 |
+
$lastStmEndId{$chan} = $id;
|
| 873 |
+
$lastStmEndIndex{$chan} = $i;
|
| 874 |
+
}
|
| 875 |
+
my $change = 0;
|
| 876 |
+
if ($lastStmEnd{$chan} > $bt && $lastStmEndIndex{$chan} < $i){
|
| 877 |
+
my ($lid, $lchan, $lspkr, $lbt, $let, $llur, $ltext) = split(/\s+/,$STMS[$lastStmEndIndex{$chan}],7);
|
| 878 |
+
if ($id eq $lid && $chan eq $lchan){
|
| 879 |
+
chomp $ltext;
|
| 880 |
+
$STMS[$lastStmEndIndex{$chan}] =
|
| 881 |
+
"$id $chan excluded_region $lbt $et $lur ignore_time_segment_in_scoring\n";
|
| 882 |
+
splice (@STMS, $i, 1);
|
| 883 |
+
$i --;
|
| 884 |
+
$change = 1;
|
| 885 |
+
}
|
| 886 |
+
}
|
| 887 |
+
$lastStmEnd{$chan} = $et;
|
| 888 |
+
if (! $change){
|
| 889 |
+
$lastStmEndIndex{$chan} = $i;
|
| 890 |
+
}
|
| 891 |
+
}
|
| 892 |
+
}
|
| 893 |
+
undef %lastStmEnd;
|
| 894 |
+
undef %lastStmEndId;
|
| 895 |
+
|
| 896 |
+
## Add the intersegment gaps
|
| 897 |
+
if ($AddInterSegGap){
|
| 898 |
+
for (my $i=0; $i<@STMS; $i++){
|
| 899 |
+
my ($id, $chan, $spkr, $bt, $et, $lur, $text) = split(/\s+/,$STMS[$i],7);
|
| 900 |
+
if (! defined($lastStmEnd{$chan})){
|
| 901 |
+
$lastStmEnd{$chan} = $NewBeginTime;
|
| 902 |
+
$lastStmEndId{$chan} = $id
|
| 903 |
+
}
|
| 904 |
+
if ($lastStmEnd{$chan} < $bt - 0.01){
|
| 905 |
+
# if (0){
|
| 906 |
+
splice (@STMS, $i, 0, sprintf("%s %s %s %s %6.2f <O> %s\n",$id,$chan,
|
| 907 |
+
"${id}_${chan}_".
|
| 908 |
+
"inter_segment_gap",
|
| 909 |
+
$lastStmEnd{$chan},$bt,""));
|
| 910 |
+
$i++;
|
| 911 |
+
}
|
| 912 |
+
$lastStmEnd{$chan} = $et;
|
| 913 |
+
}
|
| 914 |
+
foreach my $chan(sort(keys %lastStmEnd)){
|
| 915 |
+
if ($lastStmEnd{$chan} < $NewEndTime - 0.01){
|
| 916 |
+
push(@STMS, sprintf("%s %s %s %s %6.2f <O> %s\n",$lastStmEndId{$chan},$chan,
|
| 917 |
+
"${id}_${chan}_inter_segment_gap",
|
| 918 |
+
$lastStmEnd{$chan},$NewEndTime,""));
|
| 919 |
+
}
|
| 920 |
+
}
|
| 921 |
+
}
|
| 922 |
+
}
|
| 923 |
+
print OUTPUT @STMS;
|
| 924 |
+
close OUTPUT;
|
| 925 |
+
exit 0;
|
| 926 |
+
|
| 927 |
+
###############################################################################
|
| 928 |
+
#### ####
|
| 929 |
+
#### END OF MAIN PROGRAM ####
|
| 930 |
+
#### ####
|
| 931 |
+
###############################################################################
|
| 932 |
+
|
| 933 |
+
|
| 934 |
+
####
|
| 935 |
+
#### Return true if the passed in begin and end times are within the
|
| 936 |
+
#### specified range of output times. If not return false.
|
| 937 |
+
#### Inputs: - Argument 0: The begin time
|
| 938 |
+
#### - Argument 1: The end time
|
| 939 |
+
#### Outputs: - Return true if:
|
| 940 |
+
#### * the global variables $NewBeginTime or $NewEndTime
|
| 941 |
+
#### * are set, and the begin and end times are with their
|
| 942 |
+
#### * respective ranges
|
| 943 |
+
#### OR
|
| 944 |
+
#### * neither global variables are defined.
|
| 945 |
+
sub in_range{
|
| 946 |
+
my ($bt,$et) = @_;
|
| 947 |
+
my $do_prnt = 0;
|
| 948 |
+
if (defined($NewBeginTime) && defined($NewEndTime)) {
|
| 949 |
+
if (($bt >= $NewBeginTime || &eqdelta($bt,$NewBeginTime,0.5)) &&
|
| 950 |
+
($et <= $NewEndTime || &eqdelta($et,$NewEndTime,0.5))) {
|
| 951 |
+
$do_prnt = 1;
|
| 952 |
+
}
|
| 953 |
+
} elsif (defined($NewBeginTime)) {
|
| 954 |
+
if ($bt >= $NewBeginTime ||
|
| 955 |
+
&eqdelta($bt,$NewBeginTime,0.5)) {
|
| 956 |
+
$do_prnt = 1;
|
| 957 |
+
}
|
| 958 |
+
} elsif (defined($NewEndTime)) {
|
| 959 |
+
if ($et <= $NewEndTime || &eqdelta($et,$NewEndTime,0.5)) {
|
| 960 |
+
$do_prnt = 1;
|
| 961 |
+
}
|
| 962 |
+
} else {
|
| 963 |
+
$do_prnt = 1;
|
| 964 |
+
}
|
| 965 |
+
$do_prnt;
|
| 966 |
+
}
|
| 967 |
+
|
| 968 |
+
|
| 969 |
+
####
|
| 970 |
+
#### Compare two real numbers, they're equal if the absolute value of the
|
| 971 |
+
#### difference is less than delta
|
| 972 |
+
#### Inputs: - Argument 0: real number 1.
|
| 973 |
+
#### - Argument 1: real number 2.
|
| 974 |
+
#### - Argument 2: The delta.
|
| 975 |
+
#### Outputs: - True if they are equal, False if they are not
|
| 976 |
+
sub eqdelta {
|
| 977 |
+
my($v1,$v2,$del) = @_;
|
| 978 |
+
if ($v1 < $v2) {
|
| 979 |
+
$v2 - $v1 < $del;
|
| 980 |
+
} else {
|
| 981 |
+
$v1 - $v2 < $del;
|
| 982 |
+
}
|
| 983 |
+
}
|
| 984 |
+
|
| 985 |
+
sub add_spaces_for_japanese_punctuation {
|
| 986 |
+
$_ = $_[0];
|
| 987 |
+
chomp;
|
| 988 |
+
my $first = 0;
|
| 989 |
+
my $c1 = "";
|
| 990 |
+
my $lc = "";
|
| 991 |
+
my $out = "";
|
| 992 |
+
|
| 993 |
+
while (length($_) > 0){
|
| 994 |
+
s/^(.)//;
|
| 995 |
+
$c1 = $1;
|
| 996 |
+
if ($c1 =~ /^[\177-\377]/){
|
| 997 |
+
if (!$first) { $first = 1; } else { $first = 0; }
|
| 998 |
+
}
|
| 999 |
+
$out = $out.$c1;
|
| 1000 |
+
if (!$first && ($lc.$c1) =~ /^\241[\241-\270\272\273\275-\377]$/) {
|
| 1001 |
+
$out = $out." ";
|
| 1002 |
+
}
|
| 1003 |
+
$lc = $c1;
|
| 1004 |
+
}
|
| 1005 |
+
$out."\n";
|
| 1006 |
+
}
|
| 1007 |
+
|
| 1008 |
+
sub Map_AArray{
|
| 1009 |
+
$_ = $_[0];
|
| 1010 |
+
my $AArray = $_[1];
|
| 1011 |
+
my $out = "";
|
| 1012 |
+
my $word = "";
|
| 1013 |
+
foreach $word (split){
|
| 1014 |
+
if ($AArray->{$word} !~ /^$/){
|
| 1015 |
+
$out .= " ".$AArray->{$word};
|
| 1016 |
+
} else {
|
| 1017 |
+
$out .= " ".$word;
|
| 1018 |
+
}
|
| 1019 |
+
}
|
| 1020 |
+
$out .= "\n";
|
| 1021 |
+
$out;
|
| 1022 |
+
}
|
| 1023 |
+
|
| 1024 |
+
sub AlternateHyphenWords{
|
| 1025 |
+
$_ = $_[0];
|
| 1026 |
+
my $out = "";
|
| 1027 |
+
my $word = "";
|
| 1028 |
+
my $x;
|
| 1029 |
+
my $y;
|
| 1030 |
+
my $z;
|
| 1031 |
+
foreach $word (split){
|
| 1032 |
+
if ($word =~ /[A-Za-z][_-][A-Za-z]/){
|
| 1033 |
+
($x=$word) =~ s/[_-]//g;
|
| 1034 |
+
($y=$word) =~ s/[_-]/ /g;
|
| 1035 |
+
($z=$word) =~ s/[_-]/-/g;
|
| 1036 |
+
$word = "{ ".$y." / ".$x." / ".$z." }";
|
| 1037 |
+
}
|
| 1038 |
+
$out .= " ".$word;
|
| 1039 |
+
}
|
| 1040 |
+
$out .= "\n";
|
| 1041 |
+
$out;
|
| 1042 |
+
}
|
SCTK/src/chfilt/makefile
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# **********************************************************
|
| 2 |
+
# Makefile for rfilter1 Directory
|
| 3 |
+
# **********************************************************
|
| 4 |
+
SHELL = /bin/sh
|
| 5 |
+
PREFIX=/home/userube/mozilla/zz__temp_5_rover/SCTK
|
| 6 |
+
bindir = $(PREFIX)/bin
|
| 7 |
+
T=../test_suite
|
| 8 |
+
|
| 9 |
+
all: chfilt.pl
|
| 10 |
+
|
| 11 |
+
chfilt.pl:
|
| 12 |
+
chmod +x chfilt.pl
|
| 13 |
+
|
| 14 |
+
setTests:
|
| 15 |
+
./chfilt.pl -m -l english $(T)/testmss.in -- - > $(T)/testmss.stm
|
| 16 |
+
./chfilt.pl -C numbers -m -l english $(T)/testmss.in -- - > $(T)/testmss.numbers.stm
|
| 17 |
+
./chfilt.pl -l english -i -b 0 -e 999999 -k $(T)/test.txt -- - > $(T)/test.txt.-optdel.stm
|
| 18 |
+
./chfilt.pl -d -l english -i -b 0 -e 999999 -k $(T)/test.txt -- - > $(T)/test.txt.stm
|
| 19 |
+
./chfilt.pl -c -l english -i -b 0 -e 999999 -k $(T)/test.txt -- - > $(T)/test.txt.-contexp.stm
|
| 20 |
+
./chfilt.pl -c -l arabic -i -b 0 -e 999999 -d -k $(T)/test.arb2004.txt -- - > $(T)/test.arb2004.txt.stm
|
| 21 |
+
./chfilt.pl -c -l mandarin -i -b 0 -e 999999 -d -k $(T)/test.man2004.txt -- - > $(T)/test.man2004.txt.stm
|
| 22 |
+
|
| 23 |
+
check: all
|
| 24 |
+
@echo "Testing chfilt.pl"
|
| 25 |
+
./chfilt.pl -m -l english $(T)/testmss.in -- - | diff - $(T)/testmss.stm
|
| 26 |
+
./chfilt.pl -C numbers -m -l english $(T)/testmss.in -- - | diff - $(T)/testmss.numbers.stm
|
| 27 |
+
./chfilt.pl -l english -i -b 0 -e 999999 -k $(T)/test.txt -- - | diff - $(T)/test.txt.-optdel.stm
|
| 28 |
+
./chfilt.pl -d -l english -i -b 0 -e 999999 -k $(T)/test.txt -- - | diff - $(T)/test.txt.stm
|
| 29 |
+
./chfilt.pl -c -l english -i -b 0 -e 999999 -k $(T)/test.txt -- - | diff - $(T)/test.txt.-contexp.stm
|
| 30 |
+
./chfilt.pl -c -l arabic -i -b 0 -e 999999 -d -k $(T)/test.arb2004.txt -- - | diff - $(T)/test.arb2004.txt.stm
|
| 31 |
+
./chfilt.pl -c -l mandarin -i -b 0 -e 999999 -d -k $(T)/test.man2004.txt -- - | diff - $(T)/test.man2004.txt.stm
|
| 32 |
+
@echo " chfilt.pl tests successfully completed"
|
| 33 |
+
|
| 34 |
+
install: all
|
| 35 |
+
cp chfilt.pl $(DESTDIR)$(bindir)
|
| 36 |
+
|
| 37 |
+
clean:
|
| 38 |
+
|
| 39 |
+
distclean: clean
|
| 40 |
+
$(RM) -r *~ makefile
|
SCTK/src/chfilt/makefile.in
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# **********************************************************
|
| 2 |
+
# Makefile for rfilter1 Directory
|
| 3 |
+
# **********************************************************
|
| 4 |
+
SHELL = /bin/sh
|
| 5 |
+
PREFIX=
|
| 6 |
+
bindir = $(PREFIX)/bin
|
| 7 |
+
T=../test_suite
|
| 8 |
+
|
| 9 |
+
all: chfilt.pl
|
| 10 |
+
|
| 11 |
+
chfilt.pl:
|
| 12 |
+
chmod +x chfilt.pl
|
| 13 |
+
|
| 14 |
+
setTests:
|
| 15 |
+
./chfilt.pl -m -l english $(T)/testmss.in -- - > $(T)/testmss.stm
|
| 16 |
+
./chfilt.pl -C numbers -m -l english $(T)/testmss.in -- - > $(T)/testmss.numbers.stm
|
| 17 |
+
./chfilt.pl -l english -i -b 0 -e 999999 -k $(T)/test.txt -- - > $(T)/test.txt.-optdel.stm
|
| 18 |
+
./chfilt.pl -d -l english -i -b 0 -e 999999 -k $(T)/test.txt -- - > $(T)/test.txt.stm
|
| 19 |
+
./chfilt.pl -c -l english -i -b 0 -e 999999 -k $(T)/test.txt -- - > $(T)/test.txt.-contexp.stm
|
| 20 |
+
./chfilt.pl -c -l arabic -i -b 0 -e 999999 -d -k $(T)/test.arb2004.txt -- - > $(T)/test.arb2004.txt.stm
|
| 21 |
+
./chfilt.pl -c -l mandarin -i -b 0 -e 999999 -d -k $(T)/test.man2004.txt -- - > $(T)/test.man2004.txt.stm
|
| 22 |
+
|
| 23 |
+
check: all
|
| 24 |
+
@echo "Testing chfilt.pl"
|
| 25 |
+
./chfilt.pl -m -l english $(T)/testmss.in -- - | diff - $(T)/testmss.stm
|
| 26 |
+
./chfilt.pl -C numbers -m -l english $(T)/testmss.in -- - | diff - $(T)/testmss.numbers.stm
|
| 27 |
+
./chfilt.pl -l english -i -b 0 -e 999999 -k $(T)/test.txt -- - | diff - $(T)/test.txt.-optdel.stm
|
| 28 |
+
./chfilt.pl -d -l english -i -b 0 -e 999999 -k $(T)/test.txt -- - | diff - $(T)/test.txt.stm
|
| 29 |
+
./chfilt.pl -c -l english -i -b 0 -e 999999 -k $(T)/test.txt -- - | diff - $(T)/test.txt.-contexp.stm
|
| 30 |
+
./chfilt.pl -c -l arabic -i -b 0 -e 999999 -d -k $(T)/test.arb2004.txt -- - | diff - $(T)/test.arb2004.txt.stm
|
| 31 |
+
./chfilt.pl -c -l mandarin -i -b 0 -e 999999 -d -k $(T)/test.man2004.txt -- - | diff - $(T)/test.man2004.txt.stm
|
| 32 |
+
@echo " chfilt.pl tests successfully completed"
|
| 33 |
+
|
| 34 |
+
install: all
|
| 35 |
+
cp chfilt.pl $(DESTDIR)$(bindir)
|
| 36 |
+
|
| 37 |
+
clean:
|
| 38 |
+
|
| 39 |
+
distclean: clean
|
| 40 |
+
$(RM) -r *~ makefile
|
SCTK/src/ctmValidator/makefile
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
SHELL = /bin/sh
|
| 2 |
+
PREFIX=/home/userube/mozilla/zz__temp_5_rover/SCTK
|
| 3 |
+
bindir = $(PREFIX)/bin
|
| 4 |
+
|
| 5 |
+
all: ctmValidator.pl
|
| 6 |
+
|
| 7 |
+
rttmValidator.pl:
|
| 8 |
+
chmod +x ctmValidator.pl
|
| 9 |
+
|
| 10 |
+
check: all
|
| 11 |
+
(cd test_suite; $(SHELL) RunTest.sh ../ctmValidator.pl)
|
| 12 |
+
|
| 13 |
+
install: all
|
| 14 |
+
cp ctmValidator.pl $(DESTDIR)$(bindir)
|
| 15 |
+
|
| 16 |
+
clean:
|
| 17 |
+
|
| 18 |
+
distclean: clean
|
| 19 |
+
$(RM) -r *~ makefile
|
SCTK/src/hamzaNorm/hamzaNorm.pl
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env perl
|
| 2 |
+
|
| 3 |
+
use strict;
|
| 4 |
+
|
| 5 |
+
my $Version="1.0";
|
| 6 |
+
|
| 7 |
+
#####
|
| 8 |
+
# Version 1.0 Released August 25, 2004
|
| 9 |
+
# - Initial Release
|
| 10 |
+
|
| 11 |
+
my $Usage="Usage: hamzaNorm.pl [ -i fmt ] Infile|- OutFile|-\n".
|
| 12 |
+
"Version: $Version\n".
|
| 13 |
+
"Desc: hamzaNorm normalizes the hamza in the initial position of the word to be a\n".
|
| 14 |
+
" consistent form. In the Buckwalter normalization scheme, the initial letters\n".
|
| 15 |
+
" 'A', '<', '>' and '|' are all translated to 'A'".
|
| 16 |
+
"Options:\n".
|
| 17 |
+
" -i fmt Set the input file formant to 'fmt'. The possible choices are:\n".
|
| 18 |
+
" txt -> plain text, the default\n".
|
| 19 |
+
" ctm -> CTM format, ignores all but the 5th column, and if\n".
|
| 20 |
+
" a division occurs and a confidence score is present,\n".
|
| 21 |
+
" the confidence score is copied to all parts.\n".
|
| 22 |
+
" stm -> STM format, change only the text field of the stm record\n".
|
| 23 |
+
"\n";
|
| 24 |
+
|
| 25 |
+
use Getopt::Long;
|
| 26 |
+
my ($InFmt) = undef;
|
| 27 |
+
my $result = GetOptions ("i:s" => \$InFmt);
|
| 28 |
+
die "Aborting:\n$Usage\n:" if (!$result);
|
| 29 |
+
|
| 30 |
+
if (defined($InFmt)) {
|
| 31 |
+
die("$Usage\n\nError: Undefined input format '$InFmt'")
|
| 32 |
+
if ($InFmt !~ /^(txt|ctm|stm)$/);
|
| 33 |
+
} else {
|
| 34 |
+
$InFmt = "txt";
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
#### The main functions arguments:
|
| 38 |
+
die "$Usage\nToo many arguments" if ($#ARGV > 1);
|
| 39 |
+
die "$Usage\nOutput Not Specified" if ($#ARGV == 0);
|
| 40 |
+
die "$Usage\nInput and Output Not Specified" if ($#ARGV == -1);
|
| 41 |
+
|
| 42 |
+
my $InFile=$ARGV[0];
|
| 43 |
+
my $OutFile=$ARGV[1];
|
| 44 |
+
die("$Usage\nError: Input file $InFile does not exist\n")
|
| 45 |
+
if ($InFile ne "-" && ! -r $InFile);
|
| 46 |
+
|
| 47 |
+
open(IN, "$InFile") || die "Unable to open trans-file $InFile";
|
| 48 |
+
open(OUT, ">$OutFile") || die "Unable to open new-trans-file $OutFile";
|
| 49 |
+
|
| 50 |
+
while (<IN>){
|
| 51 |
+
chomp;
|
| 52 |
+
if ($InFmt eq "txt"){
|
| 53 |
+
print OUT normalize($_)."\n";
|
| 54 |
+
} elsif ($InFmt eq "ctm"){
|
| 55 |
+
if ($_ =~ /^(\;\;|\#)/){
|
| 56 |
+
print OUT $_."\n";
|
| 57 |
+
next;
|
| 58 |
+
}
|
| 59 |
+
s/^(\s+)//;
|
| 60 |
+
my $prefix = (defined($1) ? $1 : "");
|
| 61 |
+
my @ctm = split(/(\s+)/,$_);
|
| 62 |
+
$ctm[8] = normalize($ctm[8]);
|
| 63 |
+
print OUT $prefix.join("", @ctm)."\n";
|
| 64 |
+
} elsif ($InFmt eq "stm"){
|
| 65 |
+
if ($_ =~ /^(\;\;|\#)/){
|
| 66 |
+
print OUT $_."\n";
|
| 67 |
+
next;
|
| 68 |
+
}
|
| 69 |
+
s/^(\s+)//;
|
| 70 |
+
my $prefix = (defined($1) ? $1 : "");
|
| 71 |
+
my @stm = split(/(\s+)/,$_, 7);
|
| 72 |
+
if ($stm[10] =~ /^<[^<>]*>$/){
|
| 73 |
+
$stm[12] = normalize($stm[12]);
|
| 74 |
+
} else {
|
| 75 |
+
$stm[10] .= join("",splice(@stm,11,2));
|
| 76 |
+
$stm[10] = normalize($stm[10]);
|
| 77 |
+
}
|
| 78 |
+
print OUT $prefix.join("", @stm)."\n";
|
| 79 |
+
} else {
|
| 80 |
+
die "Error: unknown input format '$InFmt'\n$Usage\n";
|
| 81 |
+
}
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
close IN; close OUT;
|
| 85 |
+
exit 0;
|
| 86 |
+
|
| 87 |
+
sub normalize{
|
| 88 |
+
my ($text) = @_;
|
| 89 |
+
$text = " ".$text;
|
| 90 |
+
$text =~ s/ (\330\242|\330\243|\330\245|\330\247)/ \330\247/g;
|
| 91 |
+
$text =~ s/^ //;
|
| 92 |
+
$text;
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
|
SCTK/src/hamzaNorm/makefile
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# **********************************************************
|
| 2 |
+
# Makefile for rfilter1 Directory
|
| 3 |
+
# **********************************************************
|
| 4 |
+
SHELL = /bin/sh
|
| 5 |
+
PREFIX=/home/userube/mozilla/zz__temp_5_rover/SCTK
|
| 6 |
+
bindir = $(PREFIX)/bin
|
| 7 |
+
T=../test_suite
|
| 8 |
+
|
| 9 |
+
all: hamzaNorm.pl
|
| 10 |
+
|
| 11 |
+
hamzaNorm.pl:
|
| 12 |
+
chmod +x hamzaNorm.pl
|
| 13 |
+
|
| 14 |
+
setTests:
|
| 15 |
+
cat $(T)/test.arb2004.txt | ./hamzaNorm.pl - $(T)/test.arb2004.hamzaNorm.txt
|
| 16 |
+
cat $(T)/test.arb2004.txt.stm | sed 's/<O>//' | ./hamzaNorm.pl -i stm - $(T)/test.arb2004.txt.stm.hamza
|
| 17 |
+
cat $(T)/test.arb2004.txt.ctm | ./hamzaNorm.pl -i ctm - - | sed 's/<O>//' > $(T)/test.arb2004.txt.ctm.hamza
|
| 18 |
+
|
| 19 |
+
check: all
|
| 20 |
+
@echo "Testing hamzaNorm.pl"
|
| 21 |
+
cat $(T)/test.arb2004.txt | ./hamzaNorm.pl -- - - | diff - $(T)/test.arb2004.hamzaNorm.txt
|
| 22 |
+
cat $(T)/test.arb2004.txt.stm | sed 's/<O>//' | ./hamzaNorm.pl -i stm -- - - | diff - $(T)/test.arb2004.txt.stm.hamza
|
| 23 |
+
cat $(T)/test.arb2004.txt.stm | ./hamzaNorm.pl -i stm -- - - | sed 's/<O>//' | diff - $(T)/test.arb2004.txt.stm.hamza
|
| 24 |
+
cat $(T)/test.arb2004.txt.ctm | ./hamzaNorm.pl -i ctm -- - - | sed 's/<O>//' | diff - $(T)/test.arb2004.txt.ctm.hamza
|
| 25 |
+
@echo " hamzaNorm.pl tests successfully completed"
|
| 26 |
+
|
| 27 |
+
install: all
|
| 28 |
+
cp hamzaNorm.pl $(DESTDIR)$(bindir)
|
| 29 |
+
|
| 30 |
+
clean:
|
| 31 |
+
|
| 32 |
+
distclean: clean
|
| 33 |
+
$(RM) -r *~ makefile
|
SCTK/src/hamzaNorm/makefile.in
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# **********************************************************
|
| 2 |
+
# Makefile for rfilter1 Directory
|
| 3 |
+
# **********************************************************
|
| 4 |
+
SHELL = /bin/sh
|
| 5 |
+
PREFIX=
|
| 6 |
+
bindir = $(PREFIX)/bin
|
| 7 |
+
T=../test_suite
|
| 8 |
+
|
| 9 |
+
all: hamzaNorm.pl
|
| 10 |
+
|
| 11 |
+
hamzaNorm.pl:
|
| 12 |
+
chmod +x hamzaNorm.pl
|
| 13 |
+
|
| 14 |
+
setTests:
|
| 15 |
+
cat $(T)/test.arb2004.txt | ./hamzaNorm.pl - $(T)/test.arb2004.hamzaNorm.txt
|
| 16 |
+
cat $(T)/test.arb2004.txt.stm | sed 's/<O>//' | ./hamzaNorm.pl -i stm - $(T)/test.arb2004.txt.stm.hamza
|
| 17 |
+
cat $(T)/test.arb2004.txt.ctm | ./hamzaNorm.pl -i ctm - - | sed 's/<O>//' > $(T)/test.arb2004.txt.ctm.hamza
|
| 18 |
+
|
| 19 |
+
check: all
|
| 20 |
+
@echo "Testing hamzaNorm.pl"
|
| 21 |
+
cat $(T)/test.arb2004.txt | ./hamzaNorm.pl -- - - | diff - $(T)/test.arb2004.hamzaNorm.txt
|
| 22 |
+
cat $(T)/test.arb2004.txt.stm | sed 's/<O>//' | ./hamzaNorm.pl -i stm -- - - | diff - $(T)/test.arb2004.txt.stm.hamza
|
| 23 |
+
cat $(T)/test.arb2004.txt.stm | ./hamzaNorm.pl -i stm -- - - | sed 's/<O>//' | diff - $(T)/test.arb2004.txt.stm.hamza
|
| 24 |
+
cat $(T)/test.arb2004.txt.ctm | ./hamzaNorm.pl -i ctm -- - - | sed 's/<O>//' | diff - $(T)/test.arb2004.txt.ctm.hamza
|
| 25 |
+
@echo " hamzaNorm.pl tests successfully completed"
|
| 26 |
+
|
| 27 |
+
install: all
|
| 28 |
+
cp hamzaNorm.pl $(DESTDIR)$(bindir)
|
| 29 |
+
|
| 30 |
+
clean:
|
| 31 |
+
|
| 32 |
+
distclean: clean
|
| 33 |
+
$(RM) -r *~ makefile
|
SCTK/src/rttmValidator/makefile
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
SHELL = /bin/sh
|
| 2 |
+
PREFIX=/home/userube/mozilla/zz__temp_5_rover/SCTK
|
| 3 |
+
bindir = $(PREFIX)/bin
|
| 4 |
+
|
| 5 |
+
all: rttmValidator.pl
|
| 6 |
+
|
| 7 |
+
rttmValidator.pl:
|
| 8 |
+
chmod +x rttmValidator.pl
|
| 9 |
+
|
| 10 |
+
check: all
|
| 11 |
+
(cd test_suite; $(SHELL) RunTest.sh ../rttmValidator.pl)
|
| 12 |
+
|
| 13 |
+
install: all
|
| 14 |
+
cp rttmValidator.pl $(DESTDIR)$(bindir)
|
| 15 |
+
|
| 16 |
+
clean:
|
| 17 |
+
|
| 18 |
+
distclean: clean
|
| 19 |
+
$(RM) -r *~ makefile
|
SCTK/src/rttmValidator/makefile.in
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
SHELL = /bin/sh
|
| 2 |
+
PREFIX=
|
| 3 |
+
bindir = $(PREFIX)/bin
|
| 4 |
+
|
| 5 |
+
all: rttmValidator.pl
|
| 6 |
+
|
| 7 |
+
rttmValidator.pl:
|
| 8 |
+
chmod +x rttmValidator.pl
|
| 9 |
+
|
| 10 |
+
check: all
|
| 11 |
+
(cd test_suite; $(SHELL) RunTest.sh ../rttmValidator.pl)
|
| 12 |
+
|
| 13 |
+
install: all
|
| 14 |
+
cp rttmValidator.pl $(DESTDIR)$(bindir)
|
| 15 |
+
|
| 16 |
+
clean:
|
| 17 |
+
|
| 18 |
+
distclean: clean
|
| 19 |
+
$(RM) -r *~ makefile
|
SCTK/src/rttmValidator/rttmValidator.pl
ADDED
|
@@ -0,0 +1,917 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env perl
|
| 2 |
+
|
| 3 |
+
# RTTMVALIDATOR
|
| 4 |
+
# Author: Jon Fiscus, Jerome Ajot
|
| 5 |
+
#
|
| 6 |
+
# This software was developed at the National Institute of Standards and Technology by
|
| 7 |
+
# employees of the Federal Government in the course of their official duties. Pursuant
|
| 8 |
+
# to title 17 Section 105 of the United States Code this software is not subject to
|
| 9 |
+
# copyright protection and is in the public domain. RTTMVALIDATOR is an experimental system.
|
| 10 |
+
# NIST assumes no responsibility whatsoever for its use by other parties, and makes no
|
| 11 |
+
# guarantees, expressed or implied, about its quality, reliability, or any other
|
| 12 |
+
# characteristic. We would appreciate acknowledgement if the software is used.
|
| 13 |
+
#
|
| 14 |
+
# THIS SOFTWARE IS PROVIDED "AS IS." With regard to this software, NIST MAKES NO EXPRESS
|
| 15 |
+
# OR IMPLIED WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING MERCHANTABILITY,
|
| 16 |
+
# OR FITNESS FOR A PARTICULAR PURPOSE.
|
| 17 |
+
|
| 18 |
+
use warnings;
|
| 19 |
+
use strict;
|
| 20 |
+
use Getopt::Std;
|
| 21 |
+
use Data::Dumper;
|
| 22 |
+
|
| 23 |
+
my $debug = 0;
|
| 24 |
+
|
| 25 |
+
my $VERSION = "v13";
|
| 26 |
+
|
| 27 |
+
my $USAGE = "\n\n$0 [-useh] -i <RTTM file>\n\n".
|
| 28 |
+
"Version: $VERSION\n".
|
| 29 |
+
"Description: This Perl program (version $VERSION) validates a given RTTM file.\n".
|
| 30 |
+
"\tNote that the program will exit after it finds all the syntax errors or\n".
|
| 31 |
+
"\twhen it finds the first logic error.\n".
|
| 32 |
+
"Options:\n".
|
| 33 |
+
" -u : disable check that ensures all LEXEMEs belong to some SU object\n".
|
| 34 |
+
" -s : disable check that ensures all LEXEMEs belong to some SPEAKER object\n".
|
| 35 |
+
" -p : disable check that ensures all speakers defined in SPKR-INFO object\n".
|
| 36 |
+
" -e : disable check that ensure there is an IP for each EDIT and each FILLER object\n".
|
| 37 |
+
" -f : disable check that ensures the file columc matches the filename\n".
|
| 38 |
+
" -S : allow SCTK enhancements to allow multiple itme notations in LEXEME tags\n".
|
| 39 |
+
" -h : print this help message\n".
|
| 40 |
+
"Input:\n".
|
| 41 |
+
" -i <RTTM file>: an RTTM file\n\n";
|
| 42 |
+
|
| 43 |
+
#my $NUM_FIELDS = 9; # count from 1
|
| 44 |
+
#number of fields can be 9 or 10 (with the SLAT)
|
| 45 |
+
|
| 46 |
+
my $ROUNDING_THRESHOLD = 0.000999999;
|
| 47 |
+
|
| 48 |
+
my $checkFileName = 1; ### Check the filename against the file column
|
| 49 |
+
|
| 50 |
+
my %SORT_ORDER = ("NOSCORE" => 0,
|
| 51 |
+
"NO_RT_METADATA" => 1,
|
| 52 |
+
"SEGMENT" => 2,
|
| 53 |
+
"SPEAKER" => 3,
|
| 54 |
+
"SU" => 4,
|
| 55 |
+
"A/P" => 5,
|
| 56 |
+
"CB" => 6,
|
| 57 |
+
"IP" => 7,
|
| 58 |
+
"EDIT" => 8,
|
| 59 |
+
"FILLER" => 9,
|
| 60 |
+
"NON-SPEECH" => 10,
|
| 61 |
+
"NON-LEX" => 11,
|
| 62 |
+
"LEXEME" => 12,
|
| 63 |
+
"SPKR-INFO" => 13);
|
| 64 |
+
|
| 65 |
+
########################################################
|
| 66 |
+
# Main
|
| 67 |
+
#
|
| 68 |
+
########################################################
|
| 69 |
+
{
|
| 70 |
+
my ($date, $time) = date_time_stamp();
|
| 71 |
+
my $commandline = join(" ", @ARGV);
|
| 72 |
+
|
| 73 |
+
use vars qw ($opt_i $opt_u $opt_s $opt_e $opt_h $opt_f $opt_t $opt_p $opt_S);
|
| 74 |
+
getopts('i:usevhftpS');
|
| 75 |
+
die ("$USAGE") if ($opt_h) || (! $opt_i);
|
| 76 |
+
|
| 77 |
+
my @mde_types = ();
|
| 78 |
+
push (@mde_types, "SU") if ! $opt_u;
|
| 79 |
+
push (@mde_types, "SPEAKER") if ! $opt_s;
|
| 80 |
+
push (@mde_types, "EDIT") if ! $opt_e;
|
| 81 |
+
$checkFileName = ! $opt_f if $opt_f;
|
| 82 |
+
my $allowSCTKExtensions = 1 if $opt_S;
|
| 83 |
+
|
| 84 |
+
if (! $opt_t)
|
| 85 |
+
{
|
| 86 |
+
print "$0 (version $VERSION) run on $date at $time\n";
|
| 87 |
+
print "command line: ", $0, " (version ", $VERSION, ") ", $commandline, "\n";
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
my (%rttm_data, $data_domain);
|
| 91 |
+
get_rttm_data(\%rttm_data, \$data_domain, $opt_i, $allowSCTKExtensions);
|
| 92 |
+
|
| 93 |
+
# debug
|
| 94 |
+
#
|
| 95 |
+
my $count;
|
| 96 |
+
if ($debug) {
|
| 97 |
+
# print Dumper(%rttm_data);
|
| 98 |
+
foreach my $src (sort keys %rttm_data) {
|
| 99 |
+
foreach my $chnl (sort keys %{$rttm_data{$src}}) {
|
| 100 |
+
foreach my $spkr (sort keys %{$rttm_data{$src}{$chnl}}) {
|
| 101 |
+
foreach my $type (sort keys %{$rttm_data{$src}{$chnl}{$spkr}}) {
|
| 102 |
+
$count = 0;
|
| 103 |
+
foreach my $obj (@{$rttm_data{$src}{$chnl}{$spkr}{$type}}) {
|
| 104 |
+
print "[$src $chnl $spkr $type $count]\t$obj->{TYPE}\t$obj->{SRC}\t$obj->{CHNL}\t$obj->{TBEG}\t$obj->{TDUR}\t$obj->{ORTHO}\t$obj->{STYPE}\t$obj->{SPKR}\t$obj->{CONF}\n";
|
| 105 |
+
$count++;
|
| 106 |
+
}
|
| 107 |
+
}
|
| 108 |
+
}
|
| 109 |
+
}
|
| 110 |
+
}
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
if (check_syntax_errors(\%rttm_data, $data_domain, $opt_i, $allowSCTKExtensions) &&
|
| 114 |
+
check_logic_errors(\%rttm_data, \@mde_types)){
|
| 115 |
+
exit 0;
|
| 116 |
+
}
|
| 117 |
+
exit 1;
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
########################################################
|
| 121 |
+
# Subroutines
|
| 122 |
+
#
|
| 123 |
+
########################################################
|
| 124 |
+
sub get_rttm_data {
|
| 125 |
+
|
| 126 |
+
# read the RTTM file
|
| 127 |
+
#
|
| 128 |
+
my ($data, $domain, $file) = @_;
|
| 129 |
+
|
| 130 |
+
my (@fields, $obj);
|
| 131 |
+
|
| 132 |
+
my $line_num = 0;
|
| 133 |
+
|
| 134 |
+
${$domain} = "";
|
| 135 |
+
|
| 136 |
+
open DATA, "$file" or die ("ERROR: Unable to open file $file\n");
|
| 137 |
+
while (<DATA>) {
|
| 138 |
+
$line_num++;
|
| 139 |
+
chomp;
|
| 140 |
+
if (/^\s*;;\s*EXP-ID:\s*(.*)/) {
|
| 141 |
+
my $exp_id = $1;
|
| 142 |
+
if ($exp_id =~ /bnews/i) {
|
| 143 |
+
${$domain} = "bn";
|
| 144 |
+
} elsif ($exp_id =~ /cts/i) {
|
| 145 |
+
${$domain} = "cts";
|
| 146 |
+
}
|
| 147 |
+
} elsif (! /^\s*;;/ && ! /^\s*$/) {
|
| 148 |
+
@fields = split;
|
| 149 |
+
undef $obj;
|
| 150 |
+
$obj->{FIELD_COUNT} = scalar (@fields);
|
| 151 |
+
$obj->{LOC} = "line $line_num";
|
| 152 |
+
$obj->{TYPE} = shift @fields;
|
| 153 |
+
$obj->{SRC} = shift @fields;
|
| 154 |
+
$obj->{CHNL} = shift @fields;
|
| 155 |
+
$obj->{TBEG} = shift @fields;
|
| 156 |
+
$obj->{TDUR} = shift @fields;
|
| 157 |
+
$obj->{ORTHO} = shift @fields;
|
| 158 |
+
$obj->{STYPE} = shift @fields;
|
| 159 |
+
$obj->{SPKR} = shift @fields;
|
| 160 |
+
$obj->{CONF} = shift @fields;
|
| 161 |
+
$obj->{SLAT} = shift @fields;
|
| 162 |
+
push (@{$data->{$obj->{SRC}}{$obj->{CHNL}}{$obj->{SPKR}}{$obj->{TYPE}}}, $obj);
|
| 163 |
+
}
|
| 164 |
+
}
|
| 165 |
+
close DATA;
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
sub check_syntax_errors {
|
| 169 |
+
# check for syntax errors such as missing fields,
|
| 170 |
+
# invalid field values, etc.
|
| 171 |
+
#
|
| 172 |
+
my ($data, $domain, $file, $allowSCTKExtensions) = @_;
|
| 173 |
+
|
| 174 |
+
my $pass = 1;
|
| 175 |
+
|
| 176 |
+
$file =~ s/\.[^\.]*$//;
|
| 177 |
+
$file =~ s/.*\///;
|
| 178 |
+
|
| 179 |
+
foreach my $src (sort keys %{$data}) {
|
| 180 |
+
foreach my $chnl (sort keys %{$data->{$src}}) {
|
| 181 |
+
foreach my $spkr (sort keys %{$data->{$src}{$chnl}}) {
|
| 182 |
+
foreach my $type (sort keys %{$data->{$src}{$chnl}{$spkr}}) {
|
| 183 |
+
foreach my $obj (@{$data->{$src}{$chnl}{$spkr}{$type}}) {
|
| 184 |
+
# make sure that we have the correct number of fields
|
| 185 |
+
#
|
| 186 |
+
# if ($obj->{FIELD_COUNT} != $NUM_FIELDS) {
|
| 187 |
+
if( ($obj->{FIELD_COUNT} != 9) && ($obj->{FIELD_COUNT} != 10) ){
|
| 188 |
+
print "ERROR: This record has $obj->{FIELD_COUNT} fields instead of the required 9 or 10 fields; see $obj->{LOC}\n";
|
| 189 |
+
$pass = 0;
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
# for the following checks to work, all the fields must be defined
|
| 193 |
+
#
|
| 194 |
+
if (defined ($obj->{TYPE}) && defined ($obj->{SRC}) &&
|
| 195 |
+
defined ($obj->{CHNL}) && defined ($obj->{TBEG}) &&
|
| 196 |
+
defined ($obj->{TDUR}) && defined ($obj->{ORTHO}) &&
|
| 197 |
+
defined ($obj->{STYPE}) && defined ($obj->{SPKR}) &&
|
| 198 |
+
defined ($obj->{CONF})) {
|
| 199 |
+
|
| 200 |
+
# make sure the type field is a valid RTTM type
|
| 201 |
+
#
|
| 202 |
+
if ($obj->{TYPE} !~ /^(SEGMENT|NOSCORE|NO_RT_METADATA|LEXEME|NON-LEX|NON-SPEECH|FILLER|EDIT|SU|IP|CB|A\/P|SPEAKER|SPKR-INFO)$/i) {
|
| 203 |
+
print "ERROR: Invalid RTTM type '$obj->{TYPE}'; see field (0) in $obj->{LOC}\n";
|
| 204 |
+
$pass = 0;
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
# make sure the source field matches the base filename.
|
| 208 |
+
# This won't work if people concat all the files into one.
|
| 209 |
+
# Make it a warning instead
|
| 210 |
+
#
|
| 211 |
+
if ($checkFileName && $obj->{SRC} !~ /^$file$/i) {
|
| 212 |
+
print "WARNING: Source field '$obj->{SRC}' doesn't match the input file's base filename '$file'; see field (2) in $obj->{LOC}\n";
|
| 213 |
+
}
|
| 214 |
+
|
| 215 |
+
# make sure the channel ID has a value of 1 or 2 but 1 for BN data
|
| 216 |
+
#
|
| 217 |
+
if ($obj->{CHNL} !~ /^(1|2)$/) {
|
| 218 |
+
print "ERROR: Invalid channel ID; see field (3) in $obj->{LOC}\n";
|
| 219 |
+
$pass = 0;
|
| 220 |
+
} elsif ($domain =~ /bn/i && $obj->{CHNL} != 1) {
|
| 221 |
+
print "ERROR: Expected channel ID to be 1 for BN data; see field (3) in $obj->{LOC}\n";
|
| 222 |
+
$pass = 0;
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
# make sure that if it's a SPKR-INFO the start time is <NA>
|
| 226 |
+
# else the start time must be a number and is non-negative
|
| 227 |
+
#
|
| 228 |
+
if ($obj->{TYPE} =~ /SPKR-INFO/i) {
|
| 229 |
+
if ($obj->{TBEG} !~ /<NA>/i) {
|
| 230 |
+
print "ERROR: $obj->{TYPE} should not have any start time; see field (4) in $obj->{LOC}\n";
|
| 231 |
+
$pass = 0;
|
| 232 |
+
}
|
| 233 |
+
} else {
|
| 234 |
+
if ($obj->{TBEG} !~ /^(\-{0,1}\d+\.?\d*|\-{0,1}\.\d+)\**$/) {
|
| 235 |
+
print "ERROR: Expected start time to be a number; see field (4) in $obj->{LOC}\n";
|
| 236 |
+
$pass = 0;
|
| 237 |
+
} else {
|
| 238 |
+
my $tbeg = $obj->{TBEG};
|
| 239 |
+
$tbeg =~ s/\*//;
|
| 240 |
+
if ($tbeg < 0) {
|
| 241 |
+
print "ERROR: Negative start time; see field (4) in $obj->{LOC}\n";
|
| 242 |
+
$pass = 0;
|
| 243 |
+
}
|
| 244 |
+
}
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
# make sure that if it's a SPKR-INFO, an IP, or a CB the duration is <NA>
|
| 248 |
+
# else the duration must be a number and is non-negative
|
| 249 |
+
#
|
| 250 |
+
if ($obj->{TYPE} =~ /(SPKR-INFO|IP|CB)/i) {
|
| 251 |
+
if ($obj->{TDUR} !~ /^<NA>$/i) {
|
| 252 |
+
print "ERROR: $obj->{TYPE} should not have any duration; see field (5) in $obj->{LOC}\n";
|
| 253 |
+
$pass = 0;
|
| 254 |
+
}
|
| 255 |
+
} else {
|
| 256 |
+
if ($obj->{TDUR} !~ /^(\-{0,1}\d+\.?\d*|\-{0,1}\.\d+)\**$/) {
|
| 257 |
+
print "ERROR: Expected duration to be a number; see field (5) in $obj->{LOC}\n";
|
| 258 |
+
$pass = 0;
|
| 259 |
+
} else {
|
| 260 |
+
my $tdur = $obj->{TDUR};
|
| 261 |
+
$tdur =~ s/\*//;
|
| 262 |
+
if ($tdur < 0) {
|
| 263 |
+
print "ERROR: Negative duration; see field (5) in $obj->{LOC}\n";
|
| 264 |
+
$pass = 0;
|
| 265 |
+
}
|
| 266 |
+
}
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
# make sure that if it's not a LEXEME or a NON-LEX it doesn't have any orthography
|
| 270 |
+
#
|
| 271 |
+
if ($obj->{TYPE} =~ /(SEGMENT|NOSCORE|NO_RT_METADATA|NON-SPEECH|FILLER|EDIT|SU|IP|CB|A\/P|SPEAKER|SPKR-INFO)/i) {
|
| 272 |
+
if ($obj->{ORTHO} !~ /^<NA>$/i) {
|
| 273 |
+
print "ERROR: Value for the orthography field for $obj->{TYPE} should be <NA>; see field (6) in $obj->{LOC}\n";
|
| 274 |
+
$pass = 0;
|
| 275 |
+
}
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
# make sure the subtype for various type is valid
|
| 279 |
+
#
|
| 280 |
+
if ($obj->{TYPE} =~ /SEGMENT/i) {
|
| 281 |
+
if ($obj->{STYPE} !~ /^(eval|<NA>)$/i) {
|
| 282 |
+
print "ERROR: Invalid $obj->{TYPE} subtype; see field (7) in $obj->{LOC}\n";
|
| 283 |
+
$pass = 0;
|
| 284 |
+
}
|
| 285 |
+
} elsif ($obj->{TYPE} =~ /(NOSCORE|NO_RT_METADATA|SPEAKER)/i) {
|
| 286 |
+
if ($obj->{STYPE} !~ /^<NA>$/i) {
|
| 287 |
+
print "ERROR: Invalid $obj->{TYPE} subtype; see field (7) in $obj->{LOC}\n";
|
| 288 |
+
$pass = 0;
|
| 289 |
+
}
|
| 290 |
+
} elsif ($obj->{TYPE} =~ /A\/P/i) {
|
| 291 |
+
if ($obj->{STYPE} !~ /^<NA>$/i) {
|
| 292 |
+
print "ERROR: Invalid $obj->{TYPE} subtype; see field (7) in $obj->{LOC}\n";
|
| 293 |
+
$pass = 0;
|
| 294 |
+
}
|
| 295 |
+
} elsif ($obj->{TYPE} =~ /LEXEME/i) {
|
| 296 |
+
if ($obj->{STYPE} !~ /^(lex|fp|frag|un-lex|for-lex|alpha|acronym|interjection|propernoun|other)$/i) {
|
| 297 |
+
print "ERROR: Invalid $obj->{TYPE} subtype; see field (7) in $obj->{LOC}\n";
|
| 298 |
+
$pass = 0;
|
| 299 |
+
}
|
| 300 |
+
if ($obj->{STYPE} =~ /alpha/i && $obj->{ORTHO} !~ /^([A-Z]\.|[A-Z]\.\'*s|[\x80-\xff]{2}\.|<NA>)$/i) {
|
| 301 |
+
print "ERROR: Invalid orthography for alpha $obj->{TYPE}; see field (6) '$obj->{ORTHO}' in $obj->{LOC}\n";
|
| 302 |
+
$pass = 0;
|
| 303 |
+
}
|
| 304 |
+
my $ww = '[\[\]A-Z\.\-\'\x80-\xff]+';
|
| 305 |
+
if (! $allowSCTKExtensions){
|
| 306 |
+
if ($obj->{ORTHO} !~ /^(${ww}|<NA>|%?[A-Z\.\x80-\xff]+-?)$/i) {
|
| 307 |
+
print "WARNING: Invalid orthography for $obj->{TYPE}; see field (6) '$obj->{ORTHO}' in $obj->{LOC}\n";
|
| 308 |
+
}
|
| 309 |
+
} else {
|
| 310 |
+
### Destructively handle recursive alternations
|
| 311 |
+
my $_t = $obj->{ORTHO};
|
| 312 |
+
my $altExp = "\\{((_${ww})+_\\/)*(_${ww})+_\\}";
|
| 313 |
+
while ($_t =~ s/_${altExp}_/_/g){ ; }
|
| 314 |
+
if ($_t !~ /^(${ww}|(${ww}_)*$ww|$altExp|<NA>|%?[A-Z\.\x80-\xff]+-?)$/i) {
|
| 315 |
+
print "WARNING: Invalid orthography with SCTK Extensions for $obj->{TYPE}; see field (6) '$obj->{ORTHO}' in $obj->{LOC}\n";
|
| 316 |
+
}
|
| 317 |
+
}
|
| 318 |
+
} elsif ($obj->{TYPE} =~ /NON-LEX/i) {
|
| 319 |
+
#### fix lipsmack!!!!
|
| 320 |
+
if ($obj->{STYPE} !~ /^(laugh|breath|lipsmack|cough|sneeze|other)$/i) {
|
| 321 |
+
print "ERROR: Invalid $obj->{TYPE} subtype $obj->{STYPE}; see field (7) in $obj->{LOC}\n";
|
| 322 |
+
$pass = 0;
|
| 323 |
+
}
|
| 324 |
+
} elsif ($obj->{TYPE} =~ /NON-SPEECH/i) {
|
| 325 |
+
if ($obj->{STYPE} !~ /^(noise|music|other)$/i) {
|
| 326 |
+
print "ERROR: Invalid $obj->{TYPE} subtype; see field (7) in $obj->{LOC}\n";
|
| 327 |
+
$pass = 0;
|
| 328 |
+
}
|
| 329 |
+
} elsif ($obj->{TYPE} =~ /FILLER/i) {
|
| 330 |
+
if ($obj->{STYPE} !~ /^(filled_pause|discourse_marker|explicit_editing_term|discourse_response|other)$/i) {
|
| 331 |
+
print "ERROR: Invalid $obj->{TYPE} subtype; see field (7) in $obj->{LOC}\n";
|
| 332 |
+
$pass = 0;
|
| 333 |
+
}
|
| 334 |
+
} elsif ($obj->{TYPE} =~ /EDIT/i) {
|
| 335 |
+
if ($obj->{STYPE} !~ /^(repetition|restart|revision|simple|complex|other)$/i) {
|
| 336 |
+
print "ERROR: Invalid $obj->{TYPE} subtype; see field (7) in $obj->{LOC}\n";
|
| 337 |
+
$pass = 0;
|
| 338 |
+
}
|
| 339 |
+
} elsif ($obj->{TYPE} =~ /SU/i) {
|
| 340 |
+
if ($obj->{STYPE} !~ /^(statement|question|incomplete|backchannel|unannotated|discourse_response|other)$/i) {
|
| 341 |
+
print "ERROR: Invalid $obj->{TYPE} subtype; see field (7) in $obj->{LOC}\n";
|
| 342 |
+
$pass = 0;
|
| 343 |
+
}
|
| 344 |
+
} elsif ($obj->{TYPE} =~ /IP/i) {
|
| 345 |
+
if ($obj->{STYPE} !~ /^(edit|filler|edit\&filler|other)$/i) {
|
| 346 |
+
print "ERROR: Invalid $obj->{TYPE} subtype; see field (7) in $obj->{LOC}\n";
|
| 347 |
+
$pass = 0;
|
| 348 |
+
}
|
| 349 |
+
} elsif ($obj->{TYPE} =~ /CB/i) {
|
| 350 |
+
if ($obj->{STYPE} !~ /^(coordinating|clausal|other)$/i) {
|
| 351 |
+
print "ERROR: Invalid $obj->{TYPE} subtype; see field (7) in $obj->{LOC}\n";
|
| 352 |
+
$pass = 0;
|
| 353 |
+
}
|
| 354 |
+
} elsif ($obj->{TYPE} =~ /SPKR-INFO/i) {
|
| 355 |
+
if ($obj->{STYPE} !~ /^(adult_male|adult_female|child|unknown)$/) {
|
| 356 |
+
print "ERROR: Invalid $obj->{TYPE} subtype; see field (7) in $obj->{LOC}\n";
|
| 357 |
+
$pass = 0;
|
| 358 |
+
}
|
| 359 |
+
}
|
| 360 |
+
|
| 361 |
+
# make sure that the confidence field is a number it's from 0-1 else it's <NA>
|
| 362 |
+
#
|
| 363 |
+
if ($obj->{CONF} !~ /<NA>/) {
|
| 364 |
+
if ($obj->{CONF} !~ /^(\-{0,1}\d+\.?\d*|\-{0,1}\.\d+)$/) {
|
| 365 |
+
print "ERROR: Expected confidence value to be a number or <NA>; see field (9) in $obj->{LOC}\n";
|
| 366 |
+
$pass = 0;
|
| 367 |
+
} elsif ($obj->{CONF} < 0 || $obj->{CONF} > 1) {
|
| 368 |
+
print "ERROR: Expected confidence value to be [0,1]; see field (9) in $obj->{LOC}\n";
|
| 369 |
+
$pass = 0;
|
| 370 |
+
}
|
| 371 |
+
}
|
| 372 |
+
|
| 373 |
+
# make sure that the speaker id field for certain types match the speaker id
|
| 374 |
+
# given in the SPKR-INFO object
|
| 375 |
+
#
|
| 376 |
+
if( ! $opt_p )
|
| 377 |
+
{
|
| 378 |
+
if ($type !~ /(SPKR-INFO|NOSCORE|NONSPEECH)/i && ! find_speaker($obj->{SPKR}, $data) ) {
|
| 379 |
+
print "ERROR: Speaker $obj->{SPKR} doesn't match any of the speaker IDs in SPKR-INFO objects; see $obj->{LOC}\n";
|
| 380 |
+
$pass = 0;
|
| 381 |
+
}
|
| 382 |
+
}
|
| 383 |
+
}
|
| 384 |
+
}
|
| 385 |
+
}
|
| 386 |
+
}
|
| 387 |
+
}
|
| 388 |
+
}
|
| 389 |
+
if (! $pass) {
|
| 390 |
+
print "Validation aborted\n";
|
| 391 |
+
}
|
| 392 |
+
return $pass;
|
| 393 |
+
}
|
| 394 |
+
|
| 395 |
+
sub check_logic_errors {
|
| 396 |
+
# check for logic errors such as overlapping words from the same speaker, etc.
|
| 397 |
+
#
|
| 398 |
+
my ($data, $mde_types) = @_;
|
| 399 |
+
|
| 400 |
+
# sort the data
|
| 401 |
+
#
|
| 402 |
+
foreach my $src (sort keys %{$data}) {
|
| 403 |
+
foreach my $chnl (sort keys %{$data->{$src}}) {
|
| 404 |
+
foreach my $spkr (sort keys %{$data->{$src}{$chnl}}) {
|
| 405 |
+
foreach my $type (sort keys %{$data->{$src}{$chnl}{$spkr}}) {
|
| 406 |
+
if ($type !~ /SPKR-INFO/i) {
|
| 407 |
+
@{$data->{$src}{$chnl}{$spkr}{$type}} =
|
| 408 |
+
sort {$a->{TBEG} <=> $b->{TBEG}} @{$data->{$src}{$chnl}{$spkr}{$type}};
|
| 409 |
+
}
|
| 410 |
+
}
|
| 411 |
+
}
|
| 412 |
+
}
|
| 413 |
+
}
|
| 414 |
+
|
| 415 |
+
if (check_metadata_overlap($data) &&
|
| 416 |
+
check_metadata_content($data) &&
|
| 417 |
+
check_partial_word_coverage($data) &&
|
| 418 |
+
check_noscore_overlap($data)) {
|
| 419 |
+
foreach my $type (@$mde_types) {
|
| 420 |
+
if ($type =~ /(SU|SPEAKER)/i) {
|
| 421 |
+
if (! ensure_word_covered_by_metadata_of_type($data, $type)) {
|
| 422 |
+
return 0;
|
| 423 |
+
}
|
| 424 |
+
}
|
| 425 |
+
if ($type =~ /(EDIT|FILLER)/i) {
|
| 426 |
+
if (! ensure_ip_existed_for_edit_and_filler($data)) {
|
| 427 |
+
return 0;
|
| 428 |
+
}
|
| 429 |
+
}
|
| 430 |
+
}
|
| 431 |
+
return 1;
|
| 432 |
+
} else {
|
| 433 |
+
return 0;
|
| 434 |
+
}
|
| 435 |
+
}
|
| 436 |
+
|
| 437 |
+
sub check_metadata_overlap {
|
| 438 |
+
# check if two metadata objects of the same type
|
| 439 |
+
# from the same speaker overlap
|
| 440 |
+
#
|
| 441 |
+
my ($data) = @_;
|
| 442 |
+
|
| 443 |
+
my $pass = 1;
|
| 444 |
+
|
| 445 |
+
foreach my $src (sort keys %{$data}) {
|
| 446 |
+
foreach my $chnl (sort keys %{$data->{$src}}) {
|
| 447 |
+
foreach my $spkr (sort keys %{$data->{$src}{$chnl}}) {
|
| 448 |
+
foreach my $type (sort keys %{$data->{$src}{$chnl}{$spkr}}) {
|
| 449 |
+
if ($type !~ /SPKR-INFO/i) {
|
| 450 |
+
my $prev_etime = 0;
|
| 451 |
+
foreach my $obj (@{$data->{$src}{$chnl}{$spkr}{$type}}) {
|
| 452 |
+
if (($prev_etime - $obj->{TBEG}) > $ROUNDING_THRESHOLD) {
|
| 453 |
+
print "ERROR: Speaker $spkr has ${type}s ending at $prev_etime and starting at $obj->{TBEG}; ${type}s overlap; see $obj->{LOC}\n";
|
| 454 |
+
$pass = 0;
|
| 455 |
+
}
|
| 456 |
+
if ($type =~ /(CB|IP)/i) {
|
| 457 |
+
$prev_etime = $obj->{TBEG};
|
| 458 |
+
} else {
|
| 459 |
+
$prev_etime = $obj->{TBEG} + $obj->{TDUR};
|
| 460 |
+
}
|
| 461 |
+
}
|
| 462 |
+
}
|
| 463 |
+
}
|
| 464 |
+
}
|
| 465 |
+
}
|
| 466 |
+
}
|
| 467 |
+
if (! $pass) {
|
| 468 |
+
print "Validation aborted\n";
|
| 469 |
+
}
|
| 470 |
+
return $pass;
|
| 471 |
+
}
|
| 472 |
+
|
| 473 |
+
sub check_metadata_content {
|
| 474 |
+
# check if a metadata object of type SU, EDIT, or FILLER contains any words.
|
| 475 |
+
# The words could be missing or simply didn't get transcribed
|
| 476 |
+
#
|
| 477 |
+
my ($data) = @_;
|
| 478 |
+
|
| 479 |
+
my $pass = 1;
|
| 480 |
+
|
| 481 |
+
foreach my $src (sort keys %{$data}) {
|
| 482 |
+
foreach my $chnl (sort keys %{$data->{$src}}) {
|
| 483 |
+
foreach my $spkr (sort keys %{$data->{$src}{$chnl}}) {
|
| 484 |
+
foreach my $type (sort keys %{$data->{$src}{$chnl}{$spkr}}) {
|
| 485 |
+
if ($type =~ /(SU|EDIT|FILLER)/i) {
|
| 486 |
+
foreach my $obj (@{$data->{$src}{$chnl}{$spkr}{$type}}) {
|
| 487 |
+
if (! find_word($data->{$src}{$chnl}{$spkr}{LEXEME}, $obj->{TBEG}, $obj->{TBEG} + $obj->{TDUR})) {
|
| 488 |
+
print "ERROR: $type at $obj->{TBEG} contains no words; see $obj->{LOC}\n";
|
| 489 |
+
$pass = 0;
|
| 490 |
+
}
|
| 491 |
+
}
|
| 492 |
+
}
|
| 493 |
+
}
|
| 494 |
+
}
|
| 495 |
+
}
|
| 496 |
+
}
|
| 497 |
+
if (! $pass) {
|
| 498 |
+
print "Validation aborted\n";
|
| 499 |
+
}
|
| 500 |
+
return $pass;
|
| 501 |
+
}
|
| 502 |
+
|
| 503 |
+
sub check_partial_word_coverage {
|
| 504 |
+
# check if a given word partially overlaps with
|
| 505 |
+
# any metadata object of type SU, EDIT, or FILLER
|
| 506 |
+
#
|
| 507 |
+
my ($data) = @_;
|
| 508 |
+
|
| 509 |
+
my $pass = 1;
|
| 510 |
+
|
| 511 |
+
foreach my $src (sort keys %{$data}) {
|
| 512 |
+
foreach my $chnl (sort keys %{$data->{$src}}) {
|
| 513 |
+
foreach my $spkr (sort keys %{$data->{$src}{$chnl}}) {
|
| 514 |
+
foreach my $type (sort keys %{$data->{$src}{$chnl}{$spkr}}) {
|
| 515 |
+
if ($type =~ /LEXEME/i) {
|
| 516 |
+
foreach my $obj (@{$data->{$src}{$chnl}{$spkr}{$type}}) {
|
| 517 |
+
foreach my $mde_type (sort keys %{$data->{$src}{$chnl}{$spkr}}) {
|
| 518 |
+
if ($mde_type =~ /(SU|EDIT|FILLER)/i) {
|
| 519 |
+
if (find_partial_coverage($data->{$src}{$chnl}{$spkr}{$mde_type}, $obj->{TBEG}, $obj->{TBEG} + $obj->{TDUR})) {
|
| 520 |
+
print "ERROR: Word at $obj->{TBEG} is partially covered by $mde_type object; see $obj->{LOC}\n";
|
| 521 |
+
$pass = 0;
|
| 522 |
+
}
|
| 523 |
+
}
|
| 524 |
+
}
|
| 525 |
+
}
|
| 526 |
+
}
|
| 527 |
+
}
|
| 528 |
+
}
|
| 529 |
+
}
|
| 530 |
+
}
|
| 531 |
+
if (! $pass) {
|
| 532 |
+
print "Validation aborted\n";
|
| 533 |
+
}
|
| 534 |
+
return $pass;
|
| 535 |
+
}
|
| 536 |
+
|
| 537 |
+
sub check_noscore_overlap {
|
| 538 |
+
# check if a metadata object of type
|
| 539 |
+
# SU, EDIT, FILLER, SPEAKER, LEXEME, NONLEX, NONSPEECH
|
| 540 |
+
# partially overlap with noscore regions
|
| 541 |
+
#
|
| 542 |
+
my ($data) = @_;
|
| 543 |
+
|
| 544 |
+
my $pass = 1;
|
| 545 |
+
|
| 546 |
+
foreach my $src (sort keys %{$data}) {
|
| 547 |
+
foreach my $chnl (sort keys %{$data->{$src}}) {
|
| 548 |
+
next if (! defined ($data->{$src}{$chnl}{"<NA>"}{NOSCORE}));
|
| 549 |
+
foreach my $spkr (sort keys %{$data->{$src}{$chnl}}) {
|
| 550 |
+
foreach my $type (sort keys %{$data->{$src}{$chnl}{$spkr}}) {
|
| 551 |
+
if ($type =~ /(SU|EDIT|FILLER|SPEAKER|LEXEME|NON-LEX|NON-SPEECH)/i) {
|
| 552 |
+
foreach my $obj (@{$data->{$src}{$chnl}{$spkr}{$type}}) {
|
| 553 |
+
if (find_partial_coverage($data->{$src}{$chnl}{"<NA>"}{NOSCORE}, $obj->{TBEG}, $obj->{TBEG} + $obj->{TDUR})) {
|
| 554 |
+
print "ERROR: Speaker $spkr has $type partially overlapping with NOSCORE tag at $obj->{TBEG}; see $obj->{LOC}\n";
|
| 555 |
+
$pass = 0;
|
| 556 |
+
}
|
| 557 |
+
}
|
| 558 |
+
}
|
| 559 |
+
}
|
| 560 |
+
}
|
| 561 |
+
}
|
| 562 |
+
}
|
| 563 |
+
if (! $pass) {
|
| 564 |
+
print "Validation aborted\n";
|
| 565 |
+
}
|
| 566 |
+
return $pass;
|
| 567 |
+
}
|
| 568 |
+
|
| 569 |
+
sub ensure_word_covered_by_metadata_of_type {
|
| 570 |
+
# make sure that all words belong to some metadata object of the given type.
|
| 571 |
+
#
|
| 572 |
+
my ($data, $mde_type) = @_;
|
| 573 |
+
|
| 574 |
+
my $pass = 1;
|
| 575 |
+
|
| 576 |
+
foreach my $src (sort keys %{$data}) {
|
| 577 |
+
foreach my $chnl (sort keys %{$data->{$src}}) {
|
| 578 |
+
foreach my $spkr (sort keys %{$data->{$src}{$chnl}}) {
|
| 579 |
+
foreach my $type (sort keys %{$data->{$src}{$chnl}{$spkr}}) {
|
| 580 |
+
if ($type =~ /LEXEME/i) {
|
| 581 |
+
foreach my $obj (@{$data->{$src}{$chnl}{$spkr}{$type}}) {
|
| 582 |
+
if (! find_type($data->{$src}{$chnl}{$spkr}{$mde_type}, $obj->{TBEG}, $obj->{TBEG} + $obj->{TDUR})) {
|
| 583 |
+
print "ERROR: Word at $obj->{TBEG} doesn't belong to any $mde_type object; see $obj->{LOC}\n";
|
| 584 |
+
$pass = 0;
|
| 585 |
+
}
|
| 586 |
+
}
|
| 587 |
+
}
|
| 588 |
+
}
|
| 589 |
+
}
|
| 590 |
+
}
|
| 591 |
+
}
|
| 592 |
+
if (! $pass) {
|
| 593 |
+
print "Validation aborted\n";
|
| 594 |
+
}
|
| 595 |
+
return $pass;
|
| 596 |
+
}
|
| 597 |
+
|
| 598 |
+
sub ensure_ip_existed_for_edit_and_filler {
|
| 599 |
+
# make sure that for each EDIT or FILLER there is
|
| 600 |
+
# a valid IP that follows or precedes it
|
| 601 |
+
#
|
| 602 |
+
my ($data) = @_;
|
| 603 |
+
|
| 604 |
+
my $pass = 1;
|
| 605 |
+
|
| 606 |
+
foreach my $src (sort keys %{$data}) {
|
| 607 |
+
foreach my $chnl (sort keys %{$data->{$src}}) {
|
| 608 |
+
foreach my $spkr (sort keys %{$data->{$src}{$chnl}}) {
|
| 609 |
+
if (exists($data->{$src}{$chnl}{$spkr}{SU})) {
|
| 610 |
+
my @sus = @{$data->{$src}{$chnl}{$spkr}{SU}};
|
| 611 |
+
for (my $i = 0; $i < @sus; $i++) {
|
| 612 |
+
# print "SU $sus[$i]->{TBEG}\n";
|
| 613 |
+
my @edits = ();
|
| 614 |
+
my @fillers = ();
|
| 615 |
+
my @ips = ();
|
| 616 |
+
if (exists($data->{$src}{$chnl}{$spkr}{EDIT})) {
|
| 617 |
+
@edits = extract_mde_of_type($sus[$i]->{TBEG},
|
| 618 |
+
$sus[$i]->{TBEG} + $sus[$i]->{TDUR},
|
| 619 |
+
$i,
|
| 620 |
+
"EDIT",
|
| 621 |
+
$data->{$src}{$chnl}{$spkr}{EDIT},
|
| 622 |
+
\@sus);
|
| 623 |
+
}
|
| 624 |
+
if (exists($data->{$src}{$chnl}{$spkr}{FILLER})) {
|
| 625 |
+
@fillers = extract_mde_of_type($sus[$i]->{TBEG},
|
| 626 |
+
$sus[$i]->{TBEG} + $sus[$i]->{TDUR},
|
| 627 |
+
$i,
|
| 628 |
+
"FILLER",
|
| 629 |
+
$data->{$src}{$chnl}{$spkr}{FILLER},
|
| 630 |
+
\@sus);
|
| 631 |
+
}
|
| 632 |
+
if (exists($data->{$src}{$chnl}{$spkr}{IP})) {
|
| 633 |
+
@ips = extract_mde_of_type($sus[$i]->{TBEG},
|
| 634 |
+
$sus[$i]->{TBEG} + $sus[$i]->{TDUR},
|
| 635 |
+
$i,
|
| 636 |
+
"IP",
|
| 637 |
+
$data->{$src}{$chnl}{$spkr}{IP},
|
| 638 |
+
\@sus);
|
| 639 |
+
}
|
| 640 |
+
# print "edits\n";
|
| 641 |
+
# print Dumper(@edits);
|
| 642 |
+
# print "fillers\n";
|
| 643 |
+
# print Dumper(@fillers);
|
| 644 |
+
# print "ips\n";
|
| 645 |
+
# print Dumper(@ips);
|
| 646 |
+
|
| 647 |
+
foreach my $obj (@edits) {
|
| 648 |
+
my ($status, $ip_stype, $ip_pos) = find_object($obj->[0], $obj->[1], \@ips);
|
| 649 |
+
if ($status == 1) {
|
| 650 |
+
# print "$status, edit_type=$obj->[1] ip_stype=$ip_stype $ip_pos\n";
|
| 651 |
+
if ($ip_stype =~ /^EDIT$/i) {
|
| 652 |
+
# print "case 1\n";
|
| 653 |
+
$obj->[4] = 1;
|
| 654 |
+
$ips[$ip_pos]->[4] = 1;
|
| 655 |
+
} elsif ($ip_stype =~ /^EDIT&FILLER$/i) {
|
| 656 |
+
foreach my $obj2 (@fillers) {
|
| 657 |
+
my ($status2, $filler_type, $filler_pos) = find_object($obj->[0], "FILLER", \@fillers);
|
| 658 |
+
if ($status2 == 1) {
|
| 659 |
+
# print "$status2, filler_type=FILLER filler_type=$filler_type $filler_pos\n";
|
| 660 |
+
# print "case 2\n";
|
| 661 |
+
$obj->[4] = 1;
|
| 662 |
+
$ips[$ip_pos]->[4] = 1;
|
| 663 |
+
$fillers[$filler_pos]->[4] = 1;
|
| 664 |
+
}
|
| 665 |
+
}
|
| 666 |
+
}
|
| 667 |
+
}
|
| 668 |
+
}
|
| 669 |
+
|
| 670 |
+
foreach my $obj (@fillers) {
|
| 671 |
+
my ($status, $ip_stype, $ip_pos) = find_object($obj->[0], $obj->[1], \@ips);
|
| 672 |
+
if ($status == 1) {
|
| 673 |
+
# print "$status, filler type=$obj->[1] ip stype=$ip_stype, $ip_pos\n";
|
| 674 |
+
# print "case 3\n";
|
| 675 |
+
|
| 676 |
+
if ($ip_stype =~ /^FILLER$/i) {
|
| 677 |
+
$obj->[4] = 1;
|
| 678 |
+
$ips[$ip_pos]->[4] = 1;
|
| 679 |
+
}
|
| 680 |
+
}
|
| 681 |
+
}
|
| 682 |
+
|
| 683 |
+
foreach my $obj (@edits) {
|
| 684 |
+
if ($obj->[4] == 0) {
|
| 685 |
+
print "ERROR: EDIT at $obj->[2] doesn't have a matching IP; see $obj->[3]\n";
|
| 686 |
+
$pass = 0;
|
| 687 |
+
}
|
| 688 |
+
}
|
| 689 |
+
foreach my $obj (@fillers) {
|
| 690 |
+
if ($obj->[4] == 0) {
|
| 691 |
+
print "ERROR: FILLER at $obj->[2] doesn't have a matching IP; see $obj->[3]\n";
|
| 692 |
+
$pass = 0;
|
| 693 |
+
}
|
| 694 |
+
}
|
| 695 |
+
foreach my $obj (@ips) {
|
| 696 |
+
if ($obj->[4] == 0) {
|
| 697 |
+
print "ERROR: IP at $obj->[2] doesn't have a matching EDIT and/or FILLER; see line $obj->[3]\n";
|
| 698 |
+
$pass = 0;
|
| 699 |
+
}
|
| 700 |
+
}
|
| 701 |
+
}
|
| 702 |
+
}
|
| 703 |
+
}
|
| 704 |
+
}
|
| 705 |
+
}
|
| 706 |
+
if (! $pass) {
|
| 707 |
+
print "Validation aborted\n";
|
| 708 |
+
}
|
| 709 |
+
return $pass;
|
| 710 |
+
}
|
| 711 |
+
|
| 712 |
+
sub find_object {
|
| 713 |
+
my ($time, $type, $data1) = @_;
|
| 714 |
+
# print "find object ------------\n";
|
| 715 |
+
# print " $time $type\n";
|
| 716 |
+
for (my $i=0; $i < @$data1; $i++) {
|
| 717 |
+
# print " ${$data1}[$i]->[0]\n";
|
| 718 |
+
if (abs(${$data1}[$i]->[0] - $time) < $ROUNDING_THRESHOLD &&
|
| 719 |
+
${$data1}[$i]->[4] != 1) {
|
| 720 |
+
# print " found\n";
|
| 721 |
+
return (1, ${$data1}[$i]->[1], $i);
|
| 722 |
+
}
|
| 723 |
+
}
|
| 724 |
+
return (0, undef, undef);
|
| 725 |
+
}
|
| 726 |
+
|
| 727 |
+
sub find_partial_coverage {
|
| 728 |
+
# determine if a given object (indicated by its start and end times)
|
| 729 |
+
# partially overlap with any object of the given type
|
| 730 |
+
#
|
| 731 |
+
my ($data, $start, $end) = @_;
|
| 732 |
+
|
| 733 |
+
my $obj;
|
| 734 |
+
|
| 735 |
+
foreach $obj (@{$data}) {
|
| 736 |
+
my $curr_beg = $obj->{TBEG};
|
| 737 |
+
my $curr_end = $obj->{TBEG} + $obj->{TDUR};
|
| 738 |
+
|
| 739 |
+
# case 1 #########
|
| 740 |
+
# ####
|
| 741 |
+
#
|
| 742 |
+
# case 2 ########
|
| 743 |
+
# ####
|
| 744 |
+
#
|
| 745 |
+
# case 3 ########
|
| 746 |
+
# ####
|
| 747 |
+
#
|
| 748 |
+
# everything else is partially covered
|
| 749 |
+
#
|
| 750 |
+
if (less_than($end, $curr_beg) || equal_to($end, $curr_beg)) {
|
| 751 |
+
# case 1
|
| 752 |
+
next;
|
| 753 |
+
} elsif (greater_than($start, $curr_end) || equal_to($start, $curr_end)) {
|
| 754 |
+
# case 2
|
| 755 |
+
next;
|
| 756 |
+
} elsif ( ( greater_than($start, $curr_beg) || equal_to($start, $curr_beg) ) &&
|
| 757 |
+
( less_than($end, $curr_end) || equal_to($end, $curr_end) ) ) {
|
| 758 |
+
# case 3
|
| 759 |
+
next;
|
| 760 |
+
} else {
|
| 761 |
+
# others
|
| 762 |
+
return 1;
|
| 763 |
+
}
|
| 764 |
+
}
|
| 765 |
+
return 0;
|
| 766 |
+
}
|
| 767 |
+
|
| 768 |
+
sub find_type {
|
| 769 |
+
# determine if a given word (indicated by its start and end times)
|
| 770 |
+
# belongs to any metadata object of the given type
|
| 771 |
+
#
|
| 772 |
+
my ($data, $token_start, $token_end) = @_;
|
| 773 |
+
|
| 774 |
+
foreach my $mde_obj (@{$data}) {
|
| 775 |
+
if ($token_start + $ROUNDING_THRESHOLD >= $mde_obj->{TBEG} &&
|
| 776 |
+
$token_end - $ROUNDING_THRESHOLD <= $mde_obj->{TBEG} + $mde_obj->{TDUR}) {
|
| 777 |
+
return 1;
|
| 778 |
+
}
|
| 779 |
+
}
|
| 780 |
+
return 0;
|
| 781 |
+
}
|
| 782 |
+
|
| 783 |
+
sub find_word {
|
| 784 |
+
# determine if a given metadata object (indicated by its start and end times)
|
| 785 |
+
# contains any word
|
| 786 |
+
#
|
| 787 |
+
my ($data, $mde_obj_start, $mde_obj_end) = @_;
|
| 788 |
+
|
| 789 |
+
foreach my $token (@{$data}) {
|
| 790 |
+
if ($token->{TBEG} + $ROUNDING_THRESHOLD >= $mde_obj_start &&
|
| 791 |
+
$token->{TBEG} + $token->{TDUR} - $ROUNDING_THRESHOLD <= $mde_obj_end) {
|
| 792 |
+
return 1;
|
| 793 |
+
}
|
| 794 |
+
}
|
| 795 |
+
return 0;
|
| 796 |
+
}
|
| 797 |
+
|
| 798 |
+
sub find_ip {
|
| 799 |
+
# determine if an IP is at the time given
|
| 800 |
+
#
|
| 801 |
+
my ($data, $tbeg, $tend, $target) = @_;
|
| 802 |
+
if ($tbeg && $tend && $target) {
|
| 803 |
+
foreach my $ip (@{$data}) {
|
| 804 |
+
if ( $tbeg <= $ip->{TBEG} &&
|
| 805 |
+
$ip->{TBEG} <= $tend &&
|
| 806 |
+
abs($ip->{TBEG} - $target) < $ROUNDING_THRESHOLD ) {
|
| 807 |
+
return $ip;
|
| 808 |
+
}
|
| 809 |
+
}
|
| 810 |
+
}
|
| 811 |
+
return undef;
|
| 812 |
+
}
|
| 813 |
+
|
| 814 |
+
sub find_speaker {
|
| 815 |
+
# determine if a given speaker is in the data
|
| 816 |
+
#
|
| 817 |
+
my ($src_spkr, $data) = @_;
|
| 818 |
+
|
| 819 |
+
my ($curr_spkr);
|
| 820 |
+
foreach my $src (sort keys %{$data}) {
|
| 821 |
+
foreach my $chnl (sort keys %{$data->{$src}}) {
|
| 822 |
+
foreach my $spkr (sort keys %{$data->{$src}{$chnl}}) {
|
| 823 |
+
foreach my $obj (@{$data->{$src}{$chnl}{$spkr}{'SPKR-INFO'}}) {
|
| 824 |
+
$curr_spkr = $obj->{SPKR};
|
| 825 |
+
if ($src_spkr =~ /^$curr_spkr$/i) {
|
| 826 |
+
return 1;
|
| 827 |
+
}
|
| 828 |
+
}
|
| 829 |
+
}
|
| 830 |
+
}
|
| 831 |
+
}
|
| 832 |
+
return 0;
|
| 833 |
+
}
|
| 834 |
+
|
| 835 |
+
sub extract_mde_of_type {
|
| 836 |
+
# for a given SU (indicated by its begin and end times)
|
| 837 |
+
# return all the MDE objects of the given type in that SU
|
| 838 |
+
#
|
| 839 |
+
my ($su_tbeg, $su_tend, $su_pos, $mde_type, $data, $sus) = @_;
|
| 840 |
+
my @ip_time = ();
|
| 841 |
+
if ($mde_type =~ /EDIT/i) {
|
| 842 |
+
foreach my $obj (@$data) {
|
| 843 |
+
if ( (greater_than($obj->{TBEG}, $su_tbeg) || equal_to ($obj->{TBEG}, $su_tbeg)) &&
|
| 844 |
+
(less_than($obj->{TBEG} + $obj->{TDUR}, $su_tend) || equal_to ($obj->{TBEG} + $obj->{TDUR}, $su_tend)) ) {
|
| 845 |
+
push (@ip_time, [ $obj->{TBEG} + $obj->{TDUR}, uc($obj->{TYPE}), $obj->{TBEG}, $obj->{LOC}, 0 ]);
|
| 846 |
+
}
|
| 847 |
+
}
|
| 848 |
+
} elsif ($mde_type =~ /FILLER/i) {
|
| 849 |
+
foreach my $obj (@$data) {
|
| 850 |
+
if ( (greater_than($obj->{TBEG}, $su_tbeg) || equal_to ($obj->{TBEG}, $su_tbeg)) &&
|
| 851 |
+
(less_than($obj->{TBEG} + $obj->{TDUR}, $su_tend) || equal_to ($obj->{TBEG} + $obj->{TDUR}, $su_tend)) ) {
|
| 852 |
+
push (@ip_time, [ $obj->{TBEG}, uc($obj->{TYPE}), $obj->{TBEG}, $obj->{LOC}, 0 ]);
|
| 853 |
+
}
|
| 854 |
+
}
|
| 855 |
+
} elsif ($mde_type =~ /IP/i) {
|
| 856 |
+
foreach my $obj (@$data) {
|
| 857 |
+
if ( (greater_than($obj->{TBEG}, $su_tbeg) && less_than($obj->{TBEG}, $su_tend) ) ||
|
| 858 |
+
equal_to($obj->{TBEG}, $su_tbeg) ) {
|
| 859 |
+
push (@ip_time, [ $obj->{TBEG}, uc($obj->{STYPE}), $obj->{TBEG}, $obj->{LOC}, 0 ]);
|
| 860 |
+
} elsif ( equal_to($obj->{TBEG}, $su_tend) ) {
|
| 861 |
+
if ($su_pos + 1 <= scalar($sus)) {
|
| 862 |
+
if ( equal_to($su_tend, $sus->[$su_pos + 1]->{TBEG}) &&
|
| 863 |
+
$obj->{STYPE} !~ /filler/i ) {
|
| 864 |
+
push (@ip_time, [ $obj->{TBEG}, uc($obj->{STYPE}), $obj->{TBEG}, $obj->{LOC}, 0 ]);
|
| 865 |
+
}
|
| 866 |
+
}
|
| 867 |
+
}
|
| 868 |
+
}
|
| 869 |
+
}
|
| 870 |
+
return @ip_time;
|
| 871 |
+
}
|
| 872 |
+
|
| 873 |
+
sub sort_data {
|
| 874 |
+
return ($a->{TBEG} < $b->{TBEG} - $ROUNDING_THRESHOLD ? -1 :
|
| 875 |
+
($a->{TBEG} > $b->{TBEG} + $ROUNDING_THRESHOLD ? 1 :
|
| 876 |
+
$SORT_ORDER{$a->{TYPE}} <=> $SORT_ORDER{$b->{TYPE}}));
|
| 877 |
+
}
|
| 878 |
+
|
| 879 |
+
sub less_than {
|
| 880 |
+
# if a < b return 1
|
| 881 |
+
#
|
| 882 |
+
my ($a, $b) = @_;
|
| 883 |
+
if ($a + $ROUNDING_THRESHOLD < $b) {
|
| 884 |
+
return 1;
|
| 885 |
+
}
|
| 886 |
+
return 0;
|
| 887 |
+
}
|
| 888 |
+
|
| 889 |
+
sub greater_than {
|
| 890 |
+
# if a > b return 1
|
| 891 |
+
#
|
| 892 |
+
my ($a, $b) = @_;
|
| 893 |
+
if ($a > $b + $ROUNDING_THRESHOLD) {
|
| 894 |
+
return 1;
|
| 895 |
+
}
|
| 896 |
+
return 0;
|
| 897 |
+
}
|
| 898 |
+
|
| 899 |
+
sub equal_to {
|
| 900 |
+
# if a == b return 1
|
| 901 |
+
#
|
| 902 |
+
my ($a, $b) = @_;
|
| 903 |
+
if ( abs($a - $b) < $ROUNDING_THRESHOLD) {
|
| 904 |
+
return 1;
|
| 905 |
+
}
|
| 906 |
+
return 0;
|
| 907 |
+
}
|
| 908 |
+
|
| 909 |
+
sub date_time_stamp {
|
| 910 |
+
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime();
|
| 911 |
+
my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
|
| 912 |
+
my ($date, $time);
|
| 913 |
+
|
| 914 |
+
$time = sprintf "%2.2d:%2.2d:%2.2d", $hour, $min, $sec;
|
| 915 |
+
$date = sprintf "%4.4s %3.3s %s", 1900+$year, $months[$mon], $mday;
|
| 916 |
+
return ($date, $time);
|
| 917 |
+
}
|
SCTK/src/sclite/addarc1.o
ADDED
|
Binary file (3.22 kB). View file
|
|
|
SCTK/src/sclite/alex.h
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* File: alex.h */
|
| 2 |
+
|
| 3 |
+
typedef struct AUTO_LEX_struct{
|
| 4 |
+
int max, /* total possible tokens */
|
| 5 |
+
num; /* current number of stored tokens */
|
| 6 |
+
TEXT **str; /* pointer to the list of texts */
|
| 7 |
+
int *field_a; /* pointer to a list if intergers */
|
| 8 |
+
/* used for any purpose what-so-ever, */
|
| 9 |
+
/* Intitializd to ZERO */
|
| 10 |
+
int *field_b; /* Same usage as field_a . . . */
|
| 11 |
+
double *field_c; /* Same usage as field_a . . . */
|
| 12 |
+
int *sort; /* Sorted list of the texts */
|
| 13 |
+
} AUTO_LEX;
|
| 14 |
+
|
| 15 |
+
void AUTO_LEX_init(AUTO_LEX *alex, int size);
|
| 16 |
+
void AUTO_LEX_free(AUTO_LEX *alex);
|
| 17 |
+
int AUTO_LEX_insert(AUTO_LEX *alex, TEXT *new);
|
| 18 |
+
void AUTO_LEX_dump(AUTO_LEX *alex, FILE *fp);
|
| 19 |
+
TEXT *AUTO_LEX_get(AUTO_LEX *alex, int ind);
|
| 20 |
+
void AUTO_LEX_printout(AUTO_LEX *alex, FILE *fp, char *title, int threshhold);
|
| 21 |
+
double AUTO_LEX_get_c(AUTO_LEX *alex, int ind);
|
| 22 |
+
int AUTO_LEX_find(AUTO_LEX *alex, TEXT *str);
|
| 23 |
+
|
SCTK/src/sclite/align.c
ADDED
|
@@ -0,0 +1,1443 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <unistd.h>
|
| 2 |
+
#include "sctk.h"
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
void remove_id(TEXT *utt, TEXT **id, int *len);
|
| 6 |
+
int extract_speaker(TEXT *hyp_id, TEXT *sname, enum id_types id);
|
| 7 |
+
void load_refs(SCORES *sc, char *hyp_file, char *ref_file, TEXT ***rset, TEXT ***refid, int *refcnt, int case_sense);
|
| 8 |
+
void free_refs(TEXT ***rset, TEXT ***ref_id, int refcnt);
|
| 9 |
+
void convert_text_to_word_list(char *file, char *words,int case_sense);
|
| 10 |
+
void expand_words_to_chars(ARC *arc, void *ptr);
|
| 11 |
+
void decode_opt_del(ARC *arc, void *ptr);
|
| 12 |
+
void decode_fragment(ARC *arc, void *ptr);
|
| 13 |
+
void lookup_word_weight(ARC *arc, void *ptr);
|
| 14 |
+
void set_word_duration(ARC *arc, void *ptr);
|
| 15 |
+
void set_word_start(ARC *arc, void *ptr);
|
| 16 |
+
void set_word_conf(ARC *arc, void *ptr);
|
| 17 |
+
void set_word_opt_del(ARC *arc, void *ptr);
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
#define LOAD_BUFF_LEN 1000
|
| 21 |
+
|
| 22 |
+
void remove_id(TEXT *utt, TEXT **id, int *id_len){
|
| 23 |
+
TEXT *L_paren, *R_paren;
|
| 24 |
+
|
| 25 |
+
R_paren = TEXT_strrchr(utt,')');
|
| 26 |
+
L_paren = TEXT_strrchr(utt,'(');
|
| 27 |
+
|
| 28 |
+
**id = NULL_TEXT;
|
| 29 |
+
|
| 30 |
+
if (R_paren == NULL && L_paren == NULL)
|
| 31 |
+
return;
|
| 32 |
+
|
| 33 |
+
if (R_paren == NULL || L_paren == NULL){
|
| 34 |
+
fprintf(stderr,"Error: Unparsable utterance id %s\n",utt);
|
| 35 |
+
exit(1);
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
/* make sure there is enough space */
|
| 39 |
+
if (R_paren - L_paren + 1 + 1 > *id_len){
|
| 40 |
+
*id_len = R_paren - L_paren + 1 + 1 + 10;
|
| 41 |
+
free_singarr(*id,TEXT);
|
| 42 |
+
alloc_singZ((*id),*id_len,TEXT,'\0');
|
| 43 |
+
}
|
| 44 |
+
TEXT_strBcpy(*id,L_paren,R_paren - L_paren + 1);
|
| 45 |
+
*(*id + (R_paren - L_paren + 1)) = NULL_TEXT;
|
| 46 |
+
*L_paren = NULL_TEXT;
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
int extract_speaker(TEXT *id, TEXT *sname, enum id_types idt){
|
| 50 |
+
char *proc = "extract_speaker";
|
| 51 |
+
TEXT *p;
|
| 52 |
+
switch (idt){
|
| 53 |
+
case SP:
|
| 54 |
+
TEXT_strcpy(sname, id);
|
| 55 |
+
return(0);
|
| 56 |
+
case ATIS:
|
| 57 |
+
case WSJ:
|
| 58 |
+
TEXT_strBcpy(sname, id + 1, 3);
|
| 59 |
+
sname[3] = NULL_TEXT;
|
| 60 |
+
return(0);
|
| 61 |
+
case RM:
|
| 62 |
+
case SPUID:
|
| 63 |
+
case SWB:
|
| 64 |
+
if (((p = TEXT_strchr(id,'-')) == NULL) &&
|
| 65 |
+
((p = TEXT_strchr(id,'_')) == NULL)){
|
| 66 |
+
fprintf(stderr,"Error: %s can't locate ",proc);
|
| 67 |
+
switch (idt){
|
| 68 |
+
case RM: fprintf(stderr,"%s id %s\n","RM",id); break;
|
| 69 |
+
case SPUID: fprintf(stderr,"%s id %s\n","SPU_ID",id); break;
|
| 70 |
+
case SWB: fprintf(stderr,"%s id %s\n","SWB",id); break;
|
| 71 |
+
case WSJ:
|
| 72 |
+
case ATIS:
|
| 73 |
+
default: fprintf(stderr,"*** internal error\n");
|
| 74 |
+
}
|
| 75 |
+
return(1);
|
| 76 |
+
}
|
| 77 |
+
TEXT_strBcpy(sname, id + 1, p - (id+1));
|
| 78 |
+
sname[p - (id+1)] = NULL_TEXT;
|
| 79 |
+
return(0);
|
| 80 |
+
default:
|
| 81 |
+
fprintf(stderr,"Error: %s unknown id type\n",proc);
|
| 82 |
+
return(1);
|
| 83 |
+
}
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
/* free the reference transcripts */
|
| 87 |
+
void free_refs(TEXT ***rset, TEXT ***ref_id, int refcnt){
|
| 88 |
+
free_2dimarr((*rset),refcnt,TEXT);
|
| 89 |
+
free_2dimarr((*ref_id),refcnt,TEXT);
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
void load_refs(SCORES *sc, char *hyp_file, char *ref_file, TEXT ***rset, TEXT ***refid, int *refcnt, int case_sense){
|
| 93 |
+
TEXT *in_buf, *id_buf;
|
| 94 |
+
int in_buf_len=LOAD_BUFF_LEN, id_buf_len=LOAD_BUFF_LEN;
|
| 95 |
+
FILE *fp;
|
| 96 |
+
TEXT **idset, **tidset, **refset, **refids;
|
| 97 |
+
int max_ids, num_ids, i, num_ref, failure=0;
|
| 98 |
+
|
| 99 |
+
max_ids = 3; num_ids = 0; num_ref = 0;
|
| 100 |
+
alloc_singZ(idset,max_ids,TEXT *,(TEXT *)0);
|
| 101 |
+
alloc_singZ(in_buf,in_buf_len,TEXT,'\0');
|
| 102 |
+
alloc_singZ(id_buf,id_buf_len,TEXT,'\0');
|
| 103 |
+
|
| 104 |
+
/* Pre-Read the entire hypothesis file */
|
| 105 |
+
if ((hyp_file == NULL) || (*hyp_file == '\0') ||
|
| 106 |
+
((fp = fopen(hyp_file,"r")) == NULL)){
|
| 107 |
+
fprintf(stderr,"Can't open input hypothesis file %s\n",hyp_file);
|
| 108 |
+
exit(1);
|
| 109 |
+
}
|
| 110 |
+
while (!feof(fp)){
|
| 111 |
+
*in_buf = *(in_buf+1) = COMMENT_CHAR;
|
| 112 |
+
*(in_buf+2) = NULL_TEXT;
|
| 113 |
+
while (!feof(fp) && (parse_input_comment_line(sc,in_buf) ||
|
| 114 |
+
TEXT_is_comment_info(in_buf) ||
|
| 115 |
+
TEXT_is_empty(in_buf))){
|
| 116 |
+
if (TEXT_ensure_fgets(&in_buf,&in_buf_len,fp) == NULL)
|
| 117 |
+
*in_buf = NULL_TEXT;
|
| 118 |
+
}
|
| 119 |
+
if (!feof(fp)){
|
| 120 |
+
if (!case_sense)
|
| 121 |
+
TEXT_str_case_change_with_mem_expand(&in_buf, &in_buf_len, 1);
|
| 122 |
+
remove_id(in_buf,&id_buf,&id_buf_len);
|
| 123 |
+
if (num_ids + 1 >= max_ids) {
|
| 124 |
+
/* expanding the array */
|
| 125 |
+
alloc_singZ(tidset,max_ids*2,TEXT *, (TEXT *)0);
|
| 126 |
+
memcpy(tidset,idset,sizeof(TEXT *) * num_ids);
|
| 127 |
+
free_singarr(idset,TEXT *);
|
| 128 |
+
idset = tidset;
|
| 129 |
+
max_ids *= 2;
|
| 130 |
+
}
|
| 131 |
+
idset[num_ids++] = TEXT_strdup(id_buf);
|
| 132 |
+
}
|
| 133 |
+
}
|
| 134 |
+
fclose(fp);
|
| 135 |
+
|
| 136 |
+
/* sort the id's in-place */
|
| 137 |
+
qsort((void *)idset,num_ids,sizeof(TEXT *),qsort_TEXT_strcmp);
|
| 138 |
+
|
| 139 |
+
/* space for the reference transcripts allocate */
|
| 140 |
+
alloc_singZ(refset,num_ids,TEXT *,(TEXT *)0);
|
| 141 |
+
|
| 142 |
+
/* Read the reference file, saving the needed texts */
|
| 143 |
+
if ((ref_file == NULL) || (*ref_file == '\0') ||
|
| 144 |
+
((fp = fopen(ref_file,"r")) == NULL)){
|
| 145 |
+
fprintf(stderr,"Can't open input Reference file %s\n",ref_file);
|
| 146 |
+
exit(1);
|
| 147 |
+
}
|
| 148 |
+
while (!feof(fp)){
|
| 149 |
+
TEXT **ind;
|
| 150 |
+
int rind;
|
| 151 |
+
|
| 152 |
+
*in_buf = *(in_buf+1) = COMMENT_CHAR;
|
| 153 |
+
*(in_buf+2) = NULL_TEXT;
|
| 154 |
+
while (!feof(fp) && (parse_input_comment_line(sc,in_buf) ||
|
| 155 |
+
TEXT_is_comment_info(in_buf) ||
|
| 156 |
+
TEXT_is_empty(in_buf))){
|
| 157 |
+
if (TEXT_ensure_fgets(&in_buf,&in_buf_len,fp) == NULL)
|
| 158 |
+
*in_buf = '\0';
|
| 159 |
+
}
|
| 160 |
+
if (feof(fp))
|
| 161 |
+
break;
|
| 162 |
+
|
| 163 |
+
if (!case_sense)
|
| 164 |
+
TEXT_str_case_change_with_mem_expand(&in_buf, &in_buf_len, 1);
|
| 165 |
+
|
| 166 |
+
remove_id(in_buf,&id_buf,&id_buf_len);
|
| 167 |
+
/* Search for the id in idset */
|
| 168 |
+
if ((ind = (TEXT **)bsearch(id_buf,idset,num_ids,sizeof(TEXT *),
|
| 169 |
+
bsearch_TEXT_strcmp)) != NULL){
|
| 170 |
+
rind = ind - idset;
|
| 171 |
+
if (refset[rind] != (TEXT *)0){
|
| 172 |
+
if (TEXT_strBcmp(in_buf,refset[rind],TEXT_strlen(in_buf))!= 0){
|
| 173 |
+
fprintf(stderr,"Error: double reference text for id '%s'\n",
|
| 174 |
+
id_buf);
|
| 175 |
+
failure=1;
|
| 176 |
+
}
|
| 177 |
+
} else {
|
| 178 |
+
refset[rind] = TEXT_strdup(in_buf);
|
| 179 |
+
num_ref++;
|
| 180 |
+
}
|
| 181 |
+
}
|
| 182 |
+
}
|
| 183 |
+
fclose(fp);
|
| 184 |
+
|
| 185 |
+
if (num_ref != num_ids){
|
| 186 |
+
failure=1;
|
| 187 |
+
fprintf(stderr,"Error: Not enough Reference files loaded\nMissing:\n");
|
| 188 |
+
for (i=0; i<num_ref; i++)
|
| 189 |
+
if (refset[i] == (TEXT *)0)
|
| 190 |
+
fprintf(stderr," %s\n",idset[i]);
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
/* space for the reference id's */
|
| 194 |
+
alloc_singZ(refids,num_ref,TEXT *,(TEXT *)0);
|
| 195 |
+
/* transfer the id's to the new array */
|
| 196 |
+
memcpy(refids,idset,sizeof(TEXT *) * num_ref);
|
| 197 |
+
/* free the idset array */
|
| 198 |
+
free_singarr(idset, TEXT *)
|
| 199 |
+
|
| 200 |
+
free_singarr(in_buf,TEXT);
|
| 201 |
+
free_singarr(id_buf,TEXT);
|
| 202 |
+
|
| 203 |
+
*rset = refset;
|
| 204 |
+
*refcnt = num_ref;
|
| 205 |
+
*refid = refids;
|
| 206 |
+
|
| 207 |
+
if (failure)
|
| 208 |
+
exit(1);
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
PATH *infer_word_seg_algo2(TEXT *ref, TEXT *hyp, NETWORK *hnet, int case_sense,char *id, char *lex_fname, int fcorr, int opt_del, int flags)
|
| 212 |
+
{
|
| 213 |
+
char *proc="infer_word_seg_algo2";
|
| 214 |
+
NETWORK *refnet, *hypnet;
|
| 215 |
+
PATH *path;
|
| 216 |
+
static TEXT_LIST *tl = (TEXT_LIST *)0;
|
| 217 |
+
static int max_word_len=1;
|
| 218 |
+
int char_align = (flags == INF_ASCII_TOO) ? CALI_ON : CALI_ON+CALI_NOASCII;
|
| 219 |
+
|
| 220 |
+
if (hyp != (TEXT *)0 && hnet != (NETWORK *)0){
|
| 221 |
+
fprintf(scfp,"Error: %s passed ambiguous arguments "
|
| 222 |
+
"for 'hyp' and 'hnet'\n",proc);
|
| 223 |
+
exit(1);
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
if (tl == (TEXT_LIST *)0){
|
| 227 |
+
int i, s;
|
| 228 |
+
if ((tl = load_TEXT_LIST(lex_fname,0)) == (TEXT_LIST *)0) {
|
| 229 |
+
fprintf(scfp,"Error: Can't load lexicon file '%s'\n",lex_fname);
|
| 230 |
+
exit(0);
|
| 231 |
+
}
|
| 232 |
+
/* compute the largest word, (in characters) in the TEXT_LIST */
|
| 233 |
+
for (i=0; i<tl->num; i++)
|
| 234 |
+
if ((s = TEXT_chrlen(tl->elem[i])) > max_word_len)
|
| 235 |
+
max_word_len = s;
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
{
|
| 239 |
+
TEXT *refCC = (case_sense ? TEXT_strdup(TEXT_str_to_master(ref, 1)) : ref);
|
| 240 |
+
if ((refnet = Network_create_from_TEXT(ref, "Reference Net",
|
| 241 |
+
print_WORD,
|
| 242 |
+
equal_WORD2,
|
| 243 |
+
release_WORD, null_alt_WORD,
|
| 244 |
+
opt_del_WORD,
|
| 245 |
+
copy_WORD, make_empty_WORD,
|
| 246 |
+
use_count_WORD))
|
| 247 |
+
== NULL_NETWORK){
|
| 248 |
+
fprintf(stderr,"Network_create_from_TEXT failed\n");
|
| 249 |
+
exit(1);
|
| 250 |
+
}
|
| 251 |
+
if (case_sense){
|
| 252 |
+
free_singarr(refCC, TEXT);
|
| 253 |
+
}
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
if (hyp != (TEXT *)0){
|
| 257 |
+
TEXT *hypCC = (case_sense ? TEXT_strdup(TEXT_str_to_master(hyp, 1)) : hyp);
|
| 258 |
+
if ((hypnet = Network_create_from_TEXT(hyp,"Hypothesis Net",
|
| 259 |
+
print_WORD,
|
| 260 |
+
equal_WORD2,
|
| 261 |
+
release_WORD, null_alt_WORD,
|
| 262 |
+
opt_del_WORD,
|
| 263 |
+
copy_WORD, make_empty_WORD,
|
| 264 |
+
use_count_WORD))
|
| 265 |
+
== NULL_NETWORK){
|
| 266 |
+
fprintf(stderr,"Network_create_from_TEXT failed\n");
|
| 267 |
+
exit(1);
|
| 268 |
+
}
|
| 269 |
+
if (case_sense){
|
| 270 |
+
free_singarr(hypCC, TEXT);
|
| 271 |
+
}
|
| 272 |
+
} else
|
| 273 |
+
hypnet = hnet;
|
| 274 |
+
|
| 275 |
+
if (opt_del){
|
| 276 |
+
Network_traverse(hypnet,NULL,0,decode_opt_del,0,0);
|
| 277 |
+
Network_traverse(refnet,NULL,0,decode_opt_del,0,0);
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
if (fcorr){
|
| 281 |
+
Network_traverse(hypnet,NULL,0,decode_fragment,0,0);
|
| 282 |
+
Network_traverse(refnet,NULL,0,decode_fragment,0,0);
|
| 283 |
+
}
|
| 284 |
+
|
| 285 |
+
Network_traverse(refnet,NULL,0,expand_words_to_chars,&char_align,0);
|
| 286 |
+
|
| 287 |
+
Network_fully_connect_cond(refnet, max_word_len, append_WORD_no_NULL,
|
| 288 |
+
WORD_in_TEXT_LIST, tl);
|
| 289 |
+
|
| 290 |
+
/* printf("-----------------\n");
|
| 291 |
+
Network_traverse(hypnet,NULL,0,print_arc,0,NT_CA_For+NT_Verbose);
|
| 292 |
+
Network_traverse(refnet,NULL,0,print_arc,0,NT_CA_For+NT_Verbose); */
|
| 293 |
+
|
| 294 |
+
Network_dpalign(refnet,hypnet,wwd_WORD,&path,FALSE);
|
| 295 |
+
PATH_add_utt_id(path,(char *)id);
|
| 296 |
+
PATH_set_sequence(path);
|
| 297 |
+
if (case_sense) BF_SET(path->attrib,PA_CASE_SENSE);
|
| 298 |
+
|
| 299 |
+
Network_destroy(refnet);
|
| 300 |
+
Network_destroy(hypnet);
|
| 301 |
+
|
| 302 |
+
/* free_TEXT_LIST (&tl); */
|
| 303 |
+
return(path);
|
| 304 |
+
}
|
| 305 |
+
|
| 306 |
+
PATH *infer_word_seg_algo1(TEXT *ref, TEXT *hyp, NETWORK *hnet, int case_sense,char *id, char *lex_fname, int fcorr, int opt_del, int flags)
|
| 307 |
+
{
|
| 308 |
+
char *proc="infer_word_seg_algo1";
|
| 309 |
+
NETWORK *refnet, *hypnet;
|
| 310 |
+
PATH *path;
|
| 311 |
+
static TEXT_LIST *tl = (TEXT_LIST *)0;
|
| 312 |
+
static int max_word_len=1;
|
| 313 |
+
int char_align = (flags == INF_ASCII_TOO) ? CALI_ON : CALI_ON+CALI_NOASCII;
|
| 314 |
+
|
| 315 |
+
if (hyp != (TEXT *)0 && hnet != (NETWORK *)0){
|
| 316 |
+
fprintf(scfp,"Error: %s passed ambiguous arguments "
|
| 317 |
+
"for 'hyp' and 'hnet'\n",proc);
|
| 318 |
+
exit(1);
|
| 319 |
+
}
|
| 320 |
+
|
| 321 |
+
if (tl == (TEXT_LIST *)0){
|
| 322 |
+
int i, s;
|
| 323 |
+
if ((tl = load_TEXT_LIST(lex_fname,0)) == (TEXT_LIST *)0) {
|
| 324 |
+
fprintf(scfp,"Error: Can't load lexicon file '%s'\n",lex_fname);
|
| 325 |
+
exit(0);
|
| 326 |
+
}
|
| 327 |
+
/* compute the largest word, (in characters) in the TEXT_LIST */
|
| 328 |
+
for (i=0; i<tl->num; i++)
|
| 329 |
+
if ((s = TEXT_chrlen(tl->elem[i])) > max_word_len)
|
| 330 |
+
max_word_len = s;
|
| 331 |
+
}
|
| 332 |
+
|
| 333 |
+
TEXT *refCC = (! case_sense ? TEXT_strdup(TEXT_str_to_master(ref, 1)) : ref);
|
| 334 |
+
//db=20;
|
| 335 |
+
if ((refnet = Network_create_from_TEXT(refCC, "Reference Net",
|
| 336 |
+
print_WORD,
|
| 337 |
+
equal_WORD2,
|
| 338 |
+
release_WORD, null_alt_WORD,
|
| 339 |
+
opt_del_WORD,
|
| 340 |
+
copy_WORD, make_empty_WORD,
|
| 341 |
+
use_count_WORD))
|
| 342 |
+
== NULL_NETWORK){
|
| 343 |
+
fprintf(stderr,"Network_create_from_TEXT failed\n");
|
| 344 |
+
exit(1);
|
| 345 |
+
}
|
| 346 |
+
|
| 347 |
+
if (! case_sense){
|
| 348 |
+
free_singarr(refCC, TEXT);
|
| 349 |
+
}
|
| 350 |
+
if (hyp != (TEXT *)0){
|
| 351 |
+
TEXT *hypCC = (! case_sense ? TEXT_strdup(TEXT_str_to_master(hyp, 1)) : hyp);
|
| 352 |
+
if ((hypnet = Network_create_from_TEXT(hypCC,"Hypothesis Net",
|
| 353 |
+
print_WORD,
|
| 354 |
+
equal_WORD2,
|
| 355 |
+
release_WORD, null_alt_WORD,
|
| 356 |
+
opt_del_WORD,
|
| 357 |
+
copy_WORD, make_empty_WORD,
|
| 358 |
+
use_count_WORD))
|
| 359 |
+
== NULL_NETWORK){
|
| 360 |
+
fprintf(stderr,"Network_create_from_TEXT failed\n");
|
| 361 |
+
exit(1);
|
| 362 |
+
}
|
| 363 |
+
if (! case_sense){
|
| 364 |
+
free_singarr(hypCC, TEXT);
|
| 365 |
+
}
|
| 366 |
+
} else
|
| 367 |
+
hypnet = hnet;
|
| 368 |
+
|
| 369 |
+
// Network_traverse(hypnet,NULL,0,print_arc,0,NT_CA_For+NT_Verbose);
|
| 370 |
+
|
| 371 |
+
if (opt_del){
|
| 372 |
+
Network_traverse(hypnet,NULL,0,decode_opt_del,0,0);
|
| 373 |
+
Network_traverse(refnet,NULL,0,decode_opt_del,0,0);
|
| 374 |
+
}
|
| 375 |
+
|
| 376 |
+
if (fcorr){
|
| 377 |
+
Network_traverse(hypnet,NULL,0,decode_fragment,0,0);
|
| 378 |
+
Network_traverse(refnet,NULL,0,decode_fragment,0,0);
|
| 379 |
+
}
|
| 380 |
+
|
| 381 |
+
// Network_traverse(hypnet,NULL,0,0c,0,NT_CA_For+NT_Verbose);
|
| 382 |
+
Network_traverse(hypnet,NULL,0,expand_words_to_chars,&char_align,0);
|
| 383 |
+
// Network_traverse(hypnet,NULL,0,print_arc,0,NT_CA_For+NT_Verbose);
|
| 384 |
+
|
| 385 |
+
Network_fully_connect_cond(hypnet, max_word_len, append_WORD_no_NULL,
|
| 386 |
+
WORD_in_TEXT_LIST, tl);
|
| 387 |
+
|
| 388 |
+
// printf("-----------------\n");
|
| 389 |
+
// Network_traverse(hypnet,NULL,0,print_arc,0,NT_CA_For+NT_Verbose);
|
| 390 |
+
// Network_traverse(refnet,NULL,0,print_arc,0,NT_CA_For+NT_Verbose);
|
| 391 |
+
|
| 392 |
+
Network_dpalign(refnet,hypnet,wwd_WORD,&path,FALSE);
|
| 393 |
+
PATH_add_utt_id(path,(char *)id);
|
| 394 |
+
PATH_set_sequence(path);
|
| 395 |
+
if (case_sense) BF_SET(path->attrib,PA_CASE_SENSE);
|
| 396 |
+
|
| 397 |
+
Network_destroy(refnet);
|
| 398 |
+
Network_destroy(hypnet);
|
| 399 |
+
|
| 400 |
+
/* free_TEXT_LIST (&tl); */
|
| 401 |
+
return(path);
|
| 402 |
+
}
|
| 403 |
+
|
| 404 |
+
PATH *network_dp_align_texts(TEXT *ref, NETWORK *rnet, TEXT *hyp, NETWORK *hnet, int char_align, int case_sense, char *id, int fcorr, int opt_del, int time_align, WWL *wwl, char *lm_file)
|
| 405 |
+
{
|
| 406 |
+
char *proc="network_dp_align_texts";
|
| 407 |
+
NETWORK *refnet, *hypnet;
|
| 408 |
+
PATH *path;
|
| 409 |
+
|
| 410 |
+
if (hyp != (TEXT *)0 && hnet != (NETWORK *)0){
|
| 411 |
+
fprintf(scfp,"Error: %s passed ambiguous arguments "
|
| 412 |
+
"for 'hyp' and 'hnet'\n",proc);
|
| 413 |
+
exit(1);
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
if (ref != (TEXT *)0 && rnet != (NETWORK *)0){
|
| 417 |
+
fprintf(scfp,"Error: %s passed ambiguous arguments "
|
| 418 |
+
"for 'ref' and 'rnet'\n",proc);
|
| 419 |
+
exit(1);
|
| 420 |
+
}
|
| 421 |
+
// printf("\nREF -> %s\n",ref);
|
| 422 |
+
// printf("HYP -> %s\n",hyp);
|
| 423 |
+
if (ref != (TEXT *)0){
|
| 424 |
+
TEXT *refCC = (! case_sense ? TEXT_strdup(TEXT_str_to_master(ref, 1)) : ref);
|
| 425 |
+
|
| 426 |
+
if ((refnet = Network_create_from_TEXT(refCC, "Reference Net",print_WORD,
|
| 427 |
+
equal_WORD2,
|
| 428 |
+
release_WORD, null_alt_WORD,
|
| 429 |
+
opt_del_WORD,
|
| 430 |
+
copy_WORD, make_empty_WORD,
|
| 431 |
+
use_count_WORD))
|
| 432 |
+
== NULL_NETWORK){
|
| 433 |
+
fprintf(stderr,"Network_create_from_TEXT failed\n");
|
| 434 |
+
exit(1);
|
| 435 |
+
}
|
| 436 |
+
if (! case_sense){
|
| 437 |
+
free_singarr(refCC, TEXT);
|
| 438 |
+
}
|
| 439 |
+
} else {
|
| 440 |
+
refnet = rnet;
|
| 441 |
+
}
|
| 442 |
+
|
| 443 |
+
if (hyp != (TEXT *)0){
|
| 444 |
+
TEXT *hypCC = (!case_sense ? TEXT_strdup(TEXT_str_to_master(hyp, 1)) : hyp);
|
| 445 |
+
|
| 446 |
+
if ((hypnet = Network_create_from_TEXT(hypCC,"Hypothesis Net",
|
| 447 |
+
print_WORD,
|
| 448 |
+
equal_WORD2,
|
| 449 |
+
release_WORD, null_alt_WORD,
|
| 450 |
+
opt_del_WORD,
|
| 451 |
+
copy_WORD, make_empty_WORD,
|
| 452 |
+
use_count_WORD))
|
| 453 |
+
== NULL_NETWORK){
|
| 454 |
+
fprintf(stderr,"Network_create_from_TEXT failed\n");
|
| 455 |
+
exit(1);
|
| 456 |
+
}
|
| 457 |
+
if (! case_sense){
|
| 458 |
+
free_singarr(hypCC, TEXT);
|
| 459 |
+
}
|
| 460 |
+
} else
|
| 461 |
+
hypnet = hnet;
|
| 462 |
+
|
| 463 |
+
if (opt_del){
|
| 464 |
+
Network_traverse(hypnet,NULL,0,decode_opt_del,0,0);
|
| 465 |
+
Network_traverse(refnet,NULL,0,decode_opt_del,0,0);
|
| 466 |
+
}
|
| 467 |
+
|
| 468 |
+
if (fcorr){
|
| 469 |
+
Network_traverse(hypnet,NULL,0,decode_fragment,0,0);
|
| 470 |
+
Network_traverse(refnet,NULL,0,decode_fragment,0,0);
|
| 471 |
+
}
|
| 472 |
+
|
| 473 |
+
if (char_align){
|
| 474 |
+
Network_traverse(hypnet,NULL,0,expand_words_to_chars,&char_align,0);
|
| 475 |
+
Network_traverse(refnet,NULL,0,expand_words_to_chars,&char_align,0);
|
| 476 |
+
}
|
| 477 |
+
|
| 478 |
+
if (wwl != (WWL *)0){
|
| 479 |
+
Network_traverse(hypnet,NULL,0,lookup_word_weight,wwl,0);
|
| 480 |
+
Network_traverse(refnet,NULL,0,lookup_word_weight,wwl,0);
|
| 481 |
+
}
|
| 482 |
+
|
| 483 |
+
if (lm_file != (char *)0){
|
| 484 |
+
Network_traverse(hypnet,NULL,0,lookup_lm_word_weight,lm_file,0);
|
| 485 |
+
Network_traverse(refnet,NULL,0,lookup_lm_word_weight,lm_file,0);
|
| 486 |
+
}
|
| 487 |
+
|
| 488 |
+
// Network_traverse(hypnet,NULL,0,print_arc,0,NT_CA_For+NT_Verbose);
|
| 489 |
+
// Network_traverse(refnet,NULL,0,print_arc,0,NT_CA_For+NT_Verbose);
|
| 490 |
+
Network_dpalign(refnet,hypnet,
|
| 491 |
+
( (time_align) ? wwd_time_WORD :
|
| 492 |
+
( ((wwl != (WWL *)0) || (lm_file != (char *)0)) ?
|
| 493 |
+
wwd_weight_WORD : wwd_WORD) ),
|
| 494 |
+
&path,FALSE);
|
| 495 |
+
PATH_add_utt_id(path,(char *)id);
|
| 496 |
+
PATH_set_sequence(path);
|
| 497 |
+
if (case_sense) BF_SET(path->attrib,PA_CASE_SENSE);
|
| 498 |
+
if (char_align) BF_SET(path->attrib,PA_CHAR_ALIGN);
|
| 499 |
+
if ((wwl != (WWL *)0) || (lm_file != (char *)0)) {
|
| 500 |
+
BF_SET(path->attrib,PA_HYP_WEIGHT);
|
| 501 |
+
BF_SET(path->attrib,PA_REF_WEIGHT);
|
| 502 |
+
}
|
| 503 |
+
|
| 504 |
+
Network_destroy(refnet);
|
| 505 |
+
Network_destroy(hypnet);
|
| 506 |
+
|
| 507 |
+
return(path);
|
| 508 |
+
}
|
| 509 |
+
|
| 510 |
+
SCORES *align_trans_mode_dp(char *ref_file, char *hyp_file, char *set_title, int keep_path, int case_sense, int feedback, int char_align, enum id_types idt, int infer_word_seg, char *lexicon, int fcorr, int opt_del, int inf_no_ascii, WWL *wwl, char *lm_file){
|
| 511 |
+
FILE *fp_hyp;
|
| 512 |
+
TEXT *hyp_buff, *hyp_id, *spkr_id;
|
| 513 |
+
int hyp_buff_len=LOAD_BUFF_LEN, hyp_id_len=LOAD_BUFF_LEN;
|
| 514 |
+
int spkr_id_len=LOAD_BUFF_LEN;
|
| 515 |
+
PATH *path;
|
| 516 |
+
SCORES *scor;
|
| 517 |
+
int spk, rind, last_spk=0;
|
| 518 |
+
TEXT **reftran, **refid, **ind;
|
| 519 |
+
int refcnt;
|
| 520 |
+
|
| 521 |
+
alloc_singZ(hyp_buff,hyp_buff_len,TEXT,'\0');
|
| 522 |
+
alloc_singZ(hyp_id,hyp_id_len,TEXT,'\0');
|
| 523 |
+
alloc_singZ(spkr_id,spkr_id_len,TEXT,'\0');
|
| 524 |
+
|
| 525 |
+
if ((hyp_file == NULL) || (*hyp_file == '\0') ||
|
| 526 |
+
((fp_hyp = fopen(hyp_file,"r")) == NULL)){
|
| 527 |
+
fprintf(stderr,"Can't open input hypothesis file %s\n",hyp_file);
|
| 528 |
+
exit(1);
|
| 529 |
+
}
|
| 530 |
+
|
| 531 |
+
scor = SCORES_init(set_title,20);
|
| 532 |
+
scor->ref_fname = (char *)TEXT_strdup((TEXT *)ref_file);
|
| 533 |
+
scor->hyp_fname = (char *)TEXT_strdup((TEXT *)hyp_file);
|
| 534 |
+
scor->creation_date = get_date();
|
| 535 |
+
scor->frag_corr = fcorr;
|
| 536 |
+
scor->opt_del = opt_del;
|
| 537 |
+
if (wwl != (WWL*)0) {
|
| 538 |
+
scor->weight_ali = 1;
|
| 539 |
+
scor->weight_file =
|
| 540 |
+
(char *)TEXT_strdup((TEXT*)rsprintf("%s Column \"%s\"",wwl->filename,
|
| 541 |
+
wwl->weight_desc[0]));
|
| 542 |
+
} else if (lm_file != (char *)0) {
|
| 543 |
+
scor->weight_ali = 1;
|
| 544 |
+
scor->weight_file = (char *)TEXT_strdup((TEXT*)lm_file);
|
| 545 |
+
} else
|
| 546 |
+
scor->weight_ali = 0;
|
| 547 |
+
|
| 548 |
+
load_refs(scor, hyp_file, ref_file, &reftran, &refid, &refcnt, case_sense);
|
| 549 |
+
|
| 550 |
+
while (!feof(fp_hyp)){
|
| 551 |
+
*hyp_buff = *(hyp_buff+1) = COMMENT_CHAR;
|
| 552 |
+
*(hyp_buff+2) = NULL_TEXT;
|
| 553 |
+
while (!feof(fp_hyp) && (parse_input_comment_line(scor,hyp_buff) ||
|
| 554 |
+
TEXT_is_comment_info(hyp_buff) ||
|
| 555 |
+
TEXT_is_empty(hyp_buff)))
|
| 556 |
+
if (TEXT_ensure_fgets(&hyp_buff,&hyp_buff_len,fp_hyp) == NULL)
|
| 557 |
+
*hyp_buff = '\0';
|
| 558 |
+
if (feof(fp_hyp))
|
| 559 |
+
break;
|
| 560 |
+
|
| 561 |
+
remove_id(hyp_buff,&hyp_id,&hyp_id_len);
|
| 562 |
+
if (!case_sense) TEXT_str_case_change_with_mem_expand(&hyp_id, &hyp_id_len, 1);
|
| 563 |
+
|
| 564 |
+
extract_speaker(hyp_id,spkr_id,idt);
|
| 565 |
+
spk = SCORES_get_grp(scor,(char *)spkr_id);
|
| 566 |
+
|
| 567 |
+
if (feedback >= 1){
|
| 568 |
+
if (spk != last_spk) { printf("\n"); last_spk = spk; }
|
| 569 |
+
printf("\r Alignment# %d for speaker %s ",
|
| 570 |
+
scor->grp[spk].nsent+1,spkr_id);
|
| 571 |
+
fflush(stdout);
|
| 572 |
+
}
|
| 573 |
+
|
| 574 |
+
if ((ind = (TEXT **)bsearch(hyp_id,refid,refcnt,sizeof(TEXT *),
|
| 575 |
+
bsearch_TEXT_strcmp)) == NULL){
|
| 576 |
+
fprintf(stderr,"Error: Unable to locate Ref transcript for '%s'\n",
|
| 577 |
+
hyp_id);
|
| 578 |
+
exit(1);
|
| 579 |
+
}
|
| 580 |
+
rind = ind - refid;
|
| 581 |
+
|
| 582 |
+
if (feedback >= 100){
|
| 583 |
+
printf("\n HYP -> %s\n",hyp_buff);
|
| 584 |
+
printf(" REF -> %s\n",reftran[rind]);
|
| 585 |
+
fflush(stdout);
|
| 586 |
+
}
|
| 587 |
+
if (infer_word_seg == 0)
|
| 588 |
+
path = network_dp_align_texts(reftran[rind], (NETWORK *)0,
|
| 589 |
+
hyp_buff, (NETWORK *)0,
|
| 590 |
+
char_align, case_sense,
|
| 591 |
+
(char *)hyp_id, fcorr, opt_del, FALSE, wwl, lm_file);
|
| 592 |
+
else if (infer_word_seg == INF_SEG_ALGO1)
|
| 593 |
+
path = infer_word_seg_algo1(reftran[rind], hyp_buff, (NETWORK *)0,
|
| 594 |
+
case_sense, (char *)hyp_id, lexicon,
|
| 595 |
+
fcorr, opt_del, inf_no_ascii);
|
| 596 |
+
else if (infer_word_seg == INF_SEG_ALGO2)
|
| 597 |
+
path = infer_word_seg_algo2(reftran[rind], hyp_buff, (NETWORK *)0,
|
| 598 |
+
case_sense, (char *)hyp_id, lexicon,
|
| 599 |
+
fcorr, opt_del, inf_no_ascii);
|
| 600 |
+
else{
|
| 601 |
+
fprintf(scfp,"Error: unknown alignment procedure\n");
|
| 602 |
+
exit(1);
|
| 603 |
+
}
|
| 604 |
+
|
| 605 |
+
if (feedback >= 2){
|
| 606 |
+
printf("\n");
|
| 607 |
+
PATH_print(path,stdout,199);
|
| 608 |
+
printf("\n");
|
| 609 |
+
}
|
| 610 |
+
|
| 611 |
+
add_PATH_score(scor,path,spk, keep_path);
|
| 612 |
+
|
| 613 |
+
if (!keep_path)
|
| 614 |
+
PATH_free(path);
|
| 615 |
+
}
|
| 616 |
+
if (feedback >= 1)
|
| 617 |
+
printf("\n\n");
|
| 618 |
+
|
| 619 |
+
free_singarr(hyp_buff,TEXT);
|
| 620 |
+
free_singarr(hyp_id,TEXT);
|
| 621 |
+
free_singarr(spkr_id,TEXT);
|
| 622 |
+
free_refs(&reftran, &refid, refcnt);
|
| 623 |
+
fclose(fp_hyp);
|
| 624 |
+
|
| 625 |
+
return(scor);
|
| 626 |
+
}
|
| 627 |
+
|
| 628 |
+
|
| 629 |
+
/* This function, called by the network travers function, will set the */
|
| 630 |
+
/* duration of the word to *(double *)ptr */
|
| 631 |
+
void set_word_duration(ARC *arc, void *ptr){
|
| 632 |
+
WORD *tw = (WORD *)(arc->data);
|
| 633 |
+
tw->T_dur = *(double *)ptr;
|
| 634 |
+
}
|
| 635 |
+
|
| 636 |
+
/* This function, called by the network traverse function, will set the */
|
| 637 |
+
/* words start to *(double *)ptr, then set T2 to be T1+dur, then */
|
| 638 |
+
/* increment *(double *)ptr by dur. */
|
| 639 |
+
void set_word_start(ARC *arc, void *ptr){
|
| 640 |
+
WORD *tw = (WORD *)(arc->data);
|
| 641 |
+
tw->T1 = *(double *)ptr;
|
| 642 |
+
tw->T2 = tw->T_dur + tw->T1;
|
| 643 |
+
*(double *)ptr += tw->T_dur;
|
| 644 |
+
}
|
| 645 |
+
|
| 646 |
+
/* This function, called by the network traverse function, will set the */
|
| 647 |
+
/* word's confidence score to *(double *)ptr */
|
| 648 |
+
void set_word_conf(ARC *arc, void *ptr){
|
| 649 |
+
WORD *tw = (WORD *)(arc->data);
|
| 650 |
+
tw->conf = *(double *)ptr;
|
| 651 |
+
}
|
| 652 |
+
|
| 653 |
+
/* This function, called by the network traverse function, will set the */
|
| 654 |
+
/* word's optionally deletable flag to *(int *)ptr */
|
| 655 |
+
void set_word_opt_del(ARC *arc, void *ptr){
|
| 656 |
+
WORD *tw = (WORD *)(arc->data);
|
| 657 |
+
TEXT *ot;
|
| 658 |
+
|
| 659 |
+
if (*(int *)ptr){
|
| 660 |
+
/* re-make the optionally deletable text */
|
| 661 |
+
ot = tw->value;
|
| 662 |
+
tw->value = TEXT_strdup((TEXT *)rsprintf(WORD_OPT_DEL_PRE_STR "%s"
|
| 663 |
+
WORD_OPT_DEL_POST_STR,ot));
|
| 664 |
+
TEXT_free(ot);
|
| 665 |
+
}
|
| 666 |
+
}
|
| 667 |
+
|
| 668 |
+
void expand_words_to_chars(ARC *arc, void *ptr){
|
| 669 |
+
char *proc = "expand_words_to_chars";
|
| 670 |
+
WORD *tw = (WORD *)(arc->data);
|
| 671 |
+
static TEXT *chars=(TEXT *)0, *charsEsc;
|
| 672 |
+
static int chars_len=100;
|
| 673 |
+
NETWORK *subnet;
|
| 674 |
+
char buf[20];
|
| 675 |
+
static int alt=1;
|
| 676 |
+
|
| 677 |
+
if (chars == (TEXT *)0) alloc_singZ(chars,chars_len,TEXT,'\0');
|
| 678 |
+
/* it the string is already a single letter, return */
|
| 679 |
+
if (TEXT_strlen(tw->value) <= 1)
|
| 680 |
+
return;
|
| 681 |
+
|
| 682 |
+
if (db >= 5) {
|
| 683 |
+
printf("%s: String length > 1\n",proc);
|
| 684 |
+
arc->net->arc_func.print(arc->data);
|
| 685 |
+
}
|
| 686 |
+
// arc->net->arc_func.print(arc->data);
|
| 687 |
+
sprintf(buf,"expand-net %d",alt);
|
| 688 |
+
TEXT_separate_chars((!tw->opt_del) ? tw->value : tw->intern_value,
|
| 689 |
+
&chars,&chars_len,*((int *)ptr));
|
| 690 |
+
|
| 691 |
+
// printf(" from /%s/ comes /%s/\n",(!tw->opt_del) ? tw->value : tw->intern_value, chars);
|
| 692 |
+
|
| 693 |
+
// Escape the semicolon
|
| 694 |
+
alloc_singZ(charsEsc, chars_len*2+1, TEXT, NULL_TEXT);
|
| 695 |
+
TEXT_strcpy_escaped(charsEsc, chars, ';');
|
| 696 |
+
// printf(" and escaped /%s/\n", charsEsc);
|
| 697 |
+
|
| 698 |
+
/* Fix, it wasn't enough check to see if the there were any spaces */
|
| 699 |
+
if (TEXT_strcmp(chars,tw->value) != 0){
|
| 700 |
+
subnet = Network_create_from_TEXT(charsEsc, buf, arc->net->arc_func.print,
|
| 701 |
+
arc->net->arc_func.equal,
|
| 702 |
+
arc->net->arc_func.destroy,
|
| 703 |
+
arc->net->arc_func.is_null_alt,
|
| 704 |
+
arc->net->arc_func.is_opt_del,
|
| 705 |
+
arc->net->arc_func.copy,
|
| 706 |
+
arc->net->arc_func.make_empty,
|
| 707 |
+
arc->net->arc_func.use_count);
|
| 708 |
+
if (subnet == NULL_NETWORK){
|
| 709 |
+
fprintf(scfp,"proc %s: Internal error. Unable to expand words"
|
| 710 |
+
" to characters\n",proc);
|
| 711 |
+
return;
|
| 712 |
+
}
|
| 713 |
+
/* traverse the network, setting the character times to equal */
|
| 714 |
+
/* durations based on the original word */
|
| 715 |
+
{
|
| 716 |
+
double dur = tw->T_dur/subnet->arc_count, t1 = tw->T1, conf = tw->conf;
|
| 717 |
+
int od = tw->opt_del;
|
| 718 |
+
Network_traverse(subnet,NULL,0,set_word_duration,&dur,0);
|
| 719 |
+
Network_traverse(subnet,NULL,0,set_word_start,&t1,0);
|
| 720 |
+
Network_traverse(subnet,NULL,0,set_word_conf,&conf,0);
|
| 721 |
+
if (od){
|
| 722 |
+
Network_traverse(subnet,NULL,0,set_word_opt_del,&od,0);
|
| 723 |
+
Network_traverse(subnet,NULL,0,decode_opt_del,0,0);
|
| 724 |
+
}
|
| 725 |
+
}
|
| 726 |
+
Network_merge_network(arc->from_node,arc->to_node,subnet);
|
| 727 |
+
Network_delete_arc(arc);
|
| 728 |
+
alt++;
|
| 729 |
+
}
|
| 730 |
+
free_singarr(charsEsc, TEXT);
|
| 731 |
+
}
|
| 732 |
+
|
| 733 |
+
|
| 734 |
+
|
| 735 |
+
void lookup_word_weight(ARC *arc, void *ptr){
|
| 736 |
+
WORD *tw = (WORD *)(arc->data);
|
| 737 |
+
WWL *wwl = (WWL *)ptr;
|
| 738 |
+
|
| 739 |
+
if (tw->value == (TEXT *)0)
|
| 740 |
+
tw->weight = 0.0;
|
| 741 |
+
else if (TEXT_strcmp(tw->value,(TEXT *)"@") == 0)
|
| 742 |
+
tw->weight = 0.0;
|
| 743 |
+
else if (tw->opt_del)
|
| 744 |
+
tw->weight = 0.0;
|
| 745 |
+
else
|
| 746 |
+
tw->weight = Weight_wwl((tw->opt_del ? tw->intern_value : tw->value), wwl);
|
| 747 |
+
|
| 748 |
+
return;
|
| 749 |
+
}
|
| 750 |
+
|
| 751 |
+
|
| 752 |
+
void decode_opt_del(ARC *arc, void *ptr){
|
| 753 |
+
WORD *tw = (WORD *)(arc->data);
|
| 754 |
+
int len;
|
| 755 |
+
|
| 756 |
+
if (tw->value == (TEXT *)0) return;
|
| 757 |
+
len = TEXT_strlen(tw->value);
|
| 758 |
+
|
| 759 |
+
if ((*(tw->value + len - 1) == WORD_OPT_DEL_POST_CHAR) &&
|
| 760 |
+
(*(tw->value) == WORD_OPT_DEL_PRE_CHAR)){
|
| 761 |
+
tw->opt_del = TRUE;
|
| 762 |
+
tw->intern_value = TEXT_strBdup(tw->value + 1,len - 2);
|
| 763 |
+
}
|
| 764 |
+
return;
|
| 765 |
+
}
|
| 766 |
+
|
| 767 |
+
void decode_fragment(ARC *arc, void *ptr){
|
| 768 |
+
WORD *tw = (WORD *)(arc->data);
|
| 769 |
+
int len;
|
| 770 |
+
|
| 771 |
+
if (tw->value == (TEXT *)0) return;
|
| 772 |
+
len = TEXT_strlen(tw->value);
|
| 773 |
+
if (((*(tw->value + len - 1) == WORD_FRAG_CHAR) ||
|
| 774 |
+
(*(tw->value ) == WORD_FRAG_CHAR)) ||
|
| 775 |
+
(tw->opt_del &&
|
| 776 |
+
(*(tw->value + len - 2) == WORD_FRAG_CHAR)))
|
| 777 |
+
tw->frag_corr = TRUE;
|
| 778 |
+
|
| 779 |
+
return;
|
| 780 |
+
}
|
| 781 |
+
|
| 782 |
+
|
| 783 |
+
/**********************************************************************/
|
| 784 |
+
/************ USE GNU-DIFF to compute the alignments *************/
|
| 785 |
+
/**********************************************************************/
|
| 786 |
+
|
| 787 |
+
void create_word_lists(SCORES *sc, TEXT **reftran, TEXT **refid, int refcnt, char *hyp_file, char *out_ref, char *out_hyp, int *num_hyp, int case_sense);
|
| 788 |
+
void process_diff_line(TEXT *diff_out, PATH *path, TEXT **firsttoken);
|
| 789 |
+
void set_temp_files(char *refwords, char *hypwords);
|
| 790 |
+
|
| 791 |
+
void create_word_lists(SCORES *sc, TEXT **reftran, TEXT **refid, int refcnt, char *hyp_file, char *out_ref, char *out_hyp, int *num_hyp, int case_sense){
|
| 792 |
+
FILE *fp_hyp, *fp_out_ref, *fp_out_hyp;
|
| 793 |
+
TEXT *hyp_buff, *hyp_id, *ctext, *tbuf;
|
| 794 |
+
int hyp_buff_len=LOAD_BUFF_LEN, hyp_id_len=LOAD_BUFF_LEN;
|
| 795 |
+
int tbuf_len=100;
|
| 796 |
+
int rind;
|
| 797 |
+
TEXT **ind;
|
| 798 |
+
|
| 799 |
+
alloc_singZ(tbuf,tbuf_len,TEXT,'\0');
|
| 800 |
+
alloc_singZ(hyp_buff,hyp_buff_len,TEXT,'\0');
|
| 801 |
+
alloc_singZ(hyp_id,hyp_id_len,TEXT,'\0');
|
| 802 |
+
|
| 803 |
+
if ((fp_hyp = fopen(hyp_file,"r")) == NULL){
|
| 804 |
+
fprintf(stderr,"Can't open input hypothesis file %s\n",hyp_file);
|
| 805 |
+
exit(1);
|
| 806 |
+
}
|
| 807 |
+
|
| 808 |
+
if ((fp_out_hyp=fopen(out_hyp,"w")) == NULL){
|
| 809 |
+
fprintf(stderr,"Error: Unable to open Hypothesis word file '%s'\n",
|
| 810 |
+
out_hyp);
|
| 811 |
+
exit(1);
|
| 812 |
+
}
|
| 813 |
+
if ((fp_out_ref=fopen(out_ref,"w")) == NULL){
|
| 814 |
+
fprintf(stderr,"Error: Unable to open Reference word file '%s'\n",
|
| 815 |
+
out_ref);
|
| 816 |
+
exit(1);
|
| 817 |
+
}
|
| 818 |
+
|
| 819 |
+
while (!feof(fp_hyp)){
|
| 820 |
+
*hyp_buff = *(hyp_buff+1) = COMMENT_CHAR;
|
| 821 |
+
*(hyp_buff+2) = NULL_TEXT;
|
| 822 |
+
|
| 823 |
+
while (!feof(fp_hyp) && (parse_input_comment_line(sc,hyp_buff) ||
|
| 824 |
+
TEXT_is_comment_info(hyp_buff) ||
|
| 825 |
+
TEXT_is_empty(hyp_buff)))
|
| 826 |
+
if (TEXT_ensure_fgets(&hyp_buff,&hyp_buff_len,fp_hyp) == NULL)
|
| 827 |
+
*hyp_buff = '\0';
|
| 828 |
+
|
| 829 |
+
if (feof(fp_hyp))
|
| 830 |
+
break;
|
| 831 |
+
|
| 832 |
+
(*num_hyp) ++;
|
| 833 |
+
|
| 834 |
+
if (!case_sense)
|
| 835 |
+
TEXT_str_case_change_with_mem_expand(&hyp_buff, &hyp_buff_len, 1);
|
| 836 |
+
|
| 837 |
+
remove_id(hyp_buff,&hyp_id,&hyp_id_len);
|
| 838 |
+
if ((ind = (TEXT **)bsearch(hyp_id,refid,refcnt,sizeof(TEXT *),
|
| 839 |
+
bsearch_TEXT_strcmp)) == NULL){
|
| 840 |
+
fprintf(stderr,"Error: Unable to locate Ref transcript for '%s'\n",
|
| 841 |
+
hyp_id);
|
| 842 |
+
exit(1);
|
| 843 |
+
}
|
| 844 |
+
rind = ind - refid;
|
| 845 |
+
|
| 846 |
+
/* Write each individual word to a file */
|
| 847 |
+
if (TEXT_strlen(reftran[rind]) > tbuf_len+1){
|
| 848 |
+
free_singarr(tbuf,TEXT);
|
| 849 |
+
tbuf = TEXT_strdup(reftran[rind]);
|
| 850 |
+
tbuf_len = TEXT_strlen(tbuf);
|
| 851 |
+
} else
|
| 852 |
+
TEXT_strcpy(tbuf,reftran[rind]);
|
| 853 |
+
|
| 854 |
+
ctext = tokenize_TEXT_first_alt(tbuf,(TEXT *)" \t\n");
|
| 855 |
+
while (ctext != NULL) {
|
| 856 |
+
fprintf(fp_out_ref,"%s\n",ctext);
|
| 857 |
+
ctext = tokenize_TEXT_first_alt(NULL,(TEXT *)" \t\n");
|
| 858 |
+
}
|
| 859 |
+
|
| 860 |
+
ctext = TEXT_strtok(hyp_buff,(TEXT *)" \t\n");
|
| 861 |
+
while (ctext != NULL) {
|
| 862 |
+
fprintf(fp_out_hyp,"%s\n",ctext);
|
| 863 |
+
ctext = TEXT_strtok(NULL,(TEXT *)" \t\n");
|
| 864 |
+
}
|
| 865 |
+
}
|
| 866 |
+
|
| 867 |
+
fclose(fp_out_ref);
|
| 868 |
+
fclose(fp_out_hyp);
|
| 869 |
+
fclose(fp_hyp);
|
| 870 |
+
free_singarr(hyp_buff,TEXT);
|
| 871 |
+
free_singarr(hyp_id,TEXT);
|
| 872 |
+
free_singarr(tbuf,TEXT);
|
| 873 |
+
}
|
| 874 |
+
|
| 875 |
+
void process_diff_line(TEXT *diff_out, PATH *path, TEXT **firsttoken){
|
| 876 |
+
static TEXT s1[100],s2[100],s3[100];
|
| 877 |
+
int iret;
|
| 878 |
+
WORD *rwd, *hwd;
|
| 879 |
+
|
| 880 |
+
check_space_in_PATH(path);
|
| 881 |
+
*s1 = *s2 = *s3 = '\0';
|
| 882 |
+
iret = sscanf((char *)diff_out,
|
| 883 |
+
"%s %s %s",(char *)s1,(char *)s2,(char *)s3);
|
| 884 |
+
*firsttoken = s1;
|
| 885 |
+
|
| 886 |
+
if (iret == 2 && TEXT_strcmp(s1,s2) == 0)
|
| 887 |
+
path->pset[path->num].eval = P_CORR;
|
| 888 |
+
else if (iret == 2 && TEXT_strcmp(s1,(TEXT *)">") == 0)
|
| 889 |
+
path->pset[path->num].eval = P_INS;
|
| 890 |
+
else if (iret == 3)
|
| 891 |
+
path->pset[path->num].eval = P_SUB;
|
| 892 |
+
else
|
| 893 |
+
path->pset[path->num].eval = P_DEL;
|
| 894 |
+
|
| 895 |
+
path->pset[path->num].b_ptr = path->pset[path->num].a_ptr = (void *)0;
|
| 896 |
+
|
| 897 |
+
switch (path->pset[path->num].eval){
|
| 898 |
+
case P_CORR:
|
| 899 |
+
case P_DEL:
|
| 900 |
+
case P_SUB:
|
| 901 |
+
rwd = new_WORD(s1, -1, 0.0, 0.0, 0.0, (TEXT *)0, (TEXT *)0, 0, 0, -1.0);
|
| 902 |
+
path->pset[path->num].a_ptr = rwd;
|
| 903 |
+
case P_INS:
|
| 904 |
+
;
|
| 905 |
+
}
|
| 906 |
+
switch (path->pset[path->num].eval){
|
| 907 |
+
case P_CORR:
|
| 908 |
+
case P_INS:
|
| 909 |
+
case P_SUB:
|
| 910 |
+
hwd = (WORD *)0;
|
| 911 |
+
switch (path->pset[path->num].eval){
|
| 912 |
+
case P_CORR:
|
| 913 |
+
case P_INS:
|
| 914 |
+
hwd = new_WORD(s2, -1, 0.0, 0.0, 0.0,(TEXT *)0, (TEXT *)0, 0, 0, -1.0); break;
|
| 915 |
+
case P_SUB:
|
| 916 |
+
hwd = new_WORD(s3, -1, 0.0, 0.0, 0.0,(TEXT *)0, (TEXT *)0, 0, 0, -1.0); break;
|
| 917 |
+
case P_DEL:
|
| 918 |
+
hwd = new_WORD((TEXT *)0, -1, 0.0, 0.0, 0.0,(TEXT *)0, (TEXT *)0, 0, 0, -1.0);
|
| 919 |
+
break;
|
| 920 |
+
}
|
| 921 |
+
if (hwd == (WORD *)0){
|
| 922 |
+
fprintf(stderr,"Error: Failed to alloc word in process_diff_line\n");
|
| 923 |
+
exit(1);
|
| 924 |
+
}
|
| 925 |
+
path->pset[path->num].b_ptr = hwd;
|
| 926 |
+
case P_DEL:
|
| 927 |
+
;
|
| 928 |
+
}
|
| 929 |
+
|
| 930 |
+
path->num++;
|
| 931 |
+
}
|
| 932 |
+
|
| 933 |
+
void set_temp_files(char *refwords, char *hypwords){
|
| 934 |
+
int pid = getpid();
|
| 935 |
+
int max=30, n=0, fail;
|
| 936 |
+
struct stat fileinfo;
|
| 937 |
+
|
| 938 |
+
do {
|
| 939 |
+
sprintf(refwords,"/tmp/ref.%d",pid+n);
|
| 940 |
+
sprintf(hypwords,"/tmp/hyp.%d",pid+n);
|
| 941 |
+
n++;
|
| 942 |
+
fail = (stat(refwords,&fileinfo) == 0) ||
|
| 943 |
+
(stat(hypwords,&fileinfo) == 0);
|
| 944 |
+
} while (fail && (n < max));
|
| 945 |
+
if (fail){
|
| 946 |
+
fprintf(stderr,"Can't locate temp file names. Searched /tmp/ref.[%d-%d]\n",
|
| 947 |
+
pid,pid+n);
|
| 948 |
+
exit(1);
|
| 949 |
+
}
|
| 950 |
+
}
|
| 951 |
+
|
| 952 |
+
SCORES *align_trans_mode_diff(char *ref_file, char *hyp_file, char *set_title, int keep_path, int case_sense, int feedback, enum id_types idt){
|
| 953 |
+
FILE *fp_hyp, *fp_diff;
|
| 954 |
+
TEXT *hyp_buff, *hyp_id, *spkr_id, *diff_out;
|
| 955 |
+
int hyp_buff_len=LOAD_BUFF_LEN, hyp_id_len=LOAD_BUFF_LEN;
|
| 956 |
+
int spkr_id_len=LOAD_BUFF_LEN, diff_out_len=LOAD_BUFF_LEN;
|
| 957 |
+
PATH *path;
|
| 958 |
+
SCORES *scor;
|
| 959 |
+
int spk, rind;
|
| 960 |
+
TEXT **reftran, **refid, **ind;
|
| 961 |
+
TEXT *firsttoken;
|
| 962 |
+
int refcnt, num_hyp=0;
|
| 963 |
+
TEXT *ctext = hyp_buff; /* current position is text string */
|
| 964 |
+
char refwords[100], hypwords[100];
|
| 965 |
+
|
| 966 |
+
alloc_singZ(diff_out,diff_out_len,TEXT,'\0');
|
| 967 |
+
alloc_singZ(hyp_buff,hyp_buff_len,TEXT,'\0');
|
| 968 |
+
alloc_singZ(hyp_id,hyp_id_len,TEXT,'\0');
|
| 969 |
+
alloc_singZ(spkr_id,spkr_id_len,TEXT,'\0');
|
| 970 |
+
|
| 971 |
+
set_temp_files(refwords, hypwords);
|
| 972 |
+
|
| 973 |
+
/* initialize the score structure */
|
| 974 |
+
scor = SCORES_init(set_title,20);
|
| 975 |
+
scor->ref_fname = (char *)TEXT_strdup((TEXT *)ref_file);
|
| 976 |
+
scor->hyp_fname = (char *)TEXT_strdup((TEXT *)hyp_file);
|
| 977 |
+
scor->creation_date = get_date();
|
| 978 |
+
|
| 979 |
+
/* load the required reference sentences */
|
| 980 |
+
if (feedback >= 1) printf(" Loading transcripts\n");
|
| 981 |
+
load_refs(scor, hyp_file, ref_file, &reftran, &refid, &refcnt, case_sense);
|
| 982 |
+
|
| 983 |
+
/* create a file of words for both the ref and hyp */
|
| 984 |
+
create_word_lists(scor, reftran, refid, refcnt, hyp_file,
|
| 985 |
+
refwords, hypwords, &num_hyp, case_sense);
|
| 986 |
+
|
| 987 |
+
/* use readpipe to open a process without creating a temporary file */
|
| 988 |
+
if (feedback >= 1) printf(" Executing diff\n");
|
| 989 |
+
if ((fp_diff = readpipe (DIFF_PROGRAM, "-y",refwords,
|
| 990 |
+
hypwords, NULL)) ==NULL){
|
| 991 |
+
fprintf(stderr,"Error: Execution of 'diff' failed\n");
|
| 992 |
+
exit(1);
|
| 993 |
+
}
|
| 994 |
+
|
| 995 |
+
if ((fp_hyp = fopen(hyp_file,"r")) == NULL){
|
| 996 |
+
fprintf(stderr,"Can't open input hypothesis file %s\n",hyp_file);
|
| 997 |
+
exit(1);
|
| 998 |
+
}
|
| 999 |
+
while (!feof(fp_hyp)){
|
| 1000 |
+
*hyp_buff = *(hyp_buff+1) = COMMENT_CHAR;
|
| 1001 |
+
*(hyp_buff+2) = NULL_TEXT;
|
| 1002 |
+
|
| 1003 |
+
while (!feof(fp_hyp) && (parse_input_comment_line(scor,hyp_buff) ||
|
| 1004 |
+
TEXT_is_comment_info(hyp_buff) ||
|
| 1005 |
+
TEXT_is_empty(hyp_buff)))
|
| 1006 |
+
if (TEXT_ensure_fgets(&hyp_buff,&hyp_buff_len,fp_hyp) == NULL)
|
| 1007 |
+
*hyp_buff = '\0';
|
| 1008 |
+
|
| 1009 |
+
if (feof(fp_hyp)) break;
|
| 1010 |
+
if (!case_sense) TEXT_str_case_change_with_mem_expand(&hyp_buff, &hyp_buff_len, 1);
|
| 1011 |
+
remove_id(hyp_buff,&hyp_id,&hyp_id_len);
|
| 1012 |
+
extract_speaker(hyp_id,spkr_id,idt);
|
| 1013 |
+
spk = SCORES_get_grp(scor,(char *)spkr_id);
|
| 1014 |
+
|
| 1015 |
+
if ((ind = (TEXT **)bsearch(hyp_id,refid,refcnt,sizeof(TEXT *),
|
| 1016 |
+
bsearch_TEXT_strcmp)) == NULL){
|
| 1017 |
+
fprintf(stderr,"Error: Unable to locate Ref transcript for '%s'\n",
|
| 1018 |
+
hyp_id);
|
| 1019 |
+
exit(1);
|
| 1020 |
+
}
|
| 1021 |
+
rind = ind - refid;
|
| 1022 |
+
--num_hyp;
|
| 1023 |
+
|
| 1024 |
+
if (feedback >= 3)
|
| 1025 |
+
printf("REF: %s\nHYP: %s\n",reftran[rind],hyp_buff);
|
| 1026 |
+
|
| 1027 |
+
path = PATH_alloc(100);
|
| 1028 |
+
|
| 1029 |
+
ctext = tokenize_TEXT_first_alt(reftran[rind],(TEXT *)" \t\n");
|
| 1030 |
+
while (ctext != NULL) {
|
| 1031 |
+
do {
|
| 1032 |
+
check_space_in_PATH(path);
|
| 1033 |
+
if (TEXT_ensure_fgets(&diff_out,&diff_out_len,fp_diff) ==
|
| 1034 |
+
NULL)
|
| 1035 |
+
*diff_out = '\0';
|
| 1036 |
+
if (feof(fp_diff)) break;
|
| 1037 |
+
process_diff_line(diff_out,path,&firsttoken);
|
| 1038 |
+
} while (!feof(fp_diff) &&
|
| 1039 |
+
((TEXT_strcmp(firsttoken,ctext) != 0) || num_hyp==0));
|
| 1040 |
+
ctext = tokenize_TEXT_first_alt(NULL,(TEXT *)" \t\n");
|
| 1041 |
+
}
|
| 1042 |
+
|
| 1043 |
+
PATH_add_utt_id(path,(char *)hyp_id);
|
| 1044 |
+
PATH_set_sequence(path);
|
| 1045 |
+
if (case_sense) BF_SET(path->attrib,PA_CASE_SENSE);
|
| 1046 |
+
|
| 1047 |
+
if (feedback >= 2){
|
| 1048 |
+
printf("\n");
|
| 1049 |
+
PATH_print(path,stdout,199);
|
| 1050 |
+
printf("\n");
|
| 1051 |
+
}
|
| 1052 |
+
|
| 1053 |
+
add_PATH_score(scor,path,spk, keep_path);
|
| 1054 |
+
|
| 1055 |
+
if (!keep_path) PATH_free(path);
|
| 1056 |
+
}
|
| 1057 |
+
fclose(fp_diff);
|
| 1058 |
+
fclose(fp_hyp);
|
| 1059 |
+
|
| 1060 |
+
if (num_hyp != 0){
|
| 1061 |
+
fprintf(stderr,"Error: Unexpected number of output utts. Missing %d\n",num_hyp);
|
| 1062 |
+
exit(1);
|
| 1063 |
+
}
|
| 1064 |
+
|
| 1065 |
+
free_singarr(diff_out,TEXT);
|
| 1066 |
+
free_singarr(hyp_buff,TEXT);
|
| 1067 |
+
free_singarr(hyp_id,TEXT);
|
| 1068 |
+
free_singarr(spkr_id,TEXT);
|
| 1069 |
+
free_refs(&reftran, &refid, refcnt);
|
| 1070 |
+
|
| 1071 |
+
unlink(refwords);
|
| 1072 |
+
unlink(hypwords);
|
| 1073 |
+
return(scor);
|
| 1074 |
+
}
|
| 1075 |
+
|
| 1076 |
+
SCORES *align_ctm_to_stm_diff(char *ref_file, char *hyp_file, char *set_title, int keep_path, int case_sense, int feedback, enum id_types idt){
|
| 1077 |
+
char *proc="align_ctm_to_stm";
|
| 1078 |
+
FILE *fp_ref, *fp_hyp;
|
| 1079 |
+
WTOKE_STR1 *hyp_segs;
|
| 1080 |
+
int ref_eof, ref_err, hyp_eof, hyp_err;
|
| 1081 |
+
int hyp_end_chan1, ref_end_chan1;
|
| 1082 |
+
int hyp_end_chan2, ref_end_chan2;
|
| 1083 |
+
int just_read, hyp_file_end, ref_file_end;
|
| 1084 |
+
int number_of_channels;
|
| 1085 |
+
int i;
|
| 1086 |
+
PATH *path;
|
| 1087 |
+
STM *stm;
|
| 1088 |
+
SCORES *scor;
|
| 1089 |
+
int spkr, r;
|
| 1090 |
+
char refwords[100], hypwords[100];
|
| 1091 |
+
TEXT *diff_out, *firsttoken, *ctext;
|
| 1092 |
+
static int diff_out_len=100;
|
| 1093 |
+
FILE *fp_diff;
|
| 1094 |
+
int pdb = 0;
|
| 1095 |
+
|
| 1096 |
+
/* allocate memory */
|
| 1097 |
+
hyp_segs = WTOKE_STR1_init(hyp_file);
|
| 1098 |
+
scor = SCORES_init(set_title,20);
|
| 1099 |
+
scor->ref_fname = (char *)TEXT_strdup((TEXT *)ref_file);
|
| 1100 |
+
scor->hyp_fname = (char *)TEXT_strdup((TEXT *)hyp_file);
|
| 1101 |
+
scor->creation_date = get_date();
|
| 1102 |
+
|
| 1103 |
+
alloc_singZ(diff_out,diff_out_len,TEXT,'\0');
|
| 1104 |
+
|
| 1105 |
+
set_temp_files(refwords, hypwords);
|
| 1106 |
+
|
| 1107 |
+
if ((fp_hyp = fopen(hyp_file,"r")) == NULL){
|
| 1108 |
+
fprintf(stderr,"Can't open input hypothesis file %s\n",hyp_file);
|
| 1109 |
+
exit(1);
|
| 1110 |
+
}
|
| 1111 |
+
if ((fp_ref = fopen(ref_file,"r")) == NULL){
|
| 1112 |
+
fprintf(stderr,"Can't open input reference file %s\n",ref_file);
|
| 1113 |
+
exit(1);
|
| 1114 |
+
}
|
| 1115 |
+
|
| 1116 |
+
if ((stm = alloc_STM(200)) == (STM *)0) {
|
| 1117 |
+
fprintf(stderr,"%s: Failed to alloc STM struct\n",proc);
|
| 1118 |
+
exit(1);
|
| 1119 |
+
}
|
| 1120 |
+
hyp_eof = ref_eof = 0;
|
| 1121 |
+
do {
|
| 1122 |
+
do {
|
| 1123 |
+
locate_WTOKE_boundary(hyp_segs, hyp_segs->s, 1, 0, &hyp_file_end);
|
| 1124 |
+
just_read = 0;
|
| 1125 |
+
if ((hyp_file_end == hyp_segs->n) && !hyp_eof){
|
| 1126 |
+
fill_mark_struct(fp_hyp,hyp_segs,hyp_file,&hyp_eof,&hyp_err,
|
| 1127 |
+
case_sense);
|
| 1128 |
+
if (hyp_err != 0){
|
| 1129 |
+
fprintf(stdout,"; *Err: Error detected in hyp file '%s'\n",
|
| 1130 |
+
hyp_file);
|
| 1131 |
+
exit(1);
|
| 1132 |
+
}
|
| 1133 |
+
just_read = 1;
|
| 1134 |
+
}
|
| 1135 |
+
} while (just_read);
|
| 1136 |
+
just_read = 0;
|
| 1137 |
+
do {
|
| 1138 |
+
locate_STM_boundary(stm, stm->s, 1, 0, &ref_file_end);
|
| 1139 |
+
if ((ref_file_end == stm->num) && !ref_eof){
|
| 1140 |
+
if (just_read == 1){
|
| 1141 |
+
just_read = 0;
|
| 1142 |
+
expand_STM(stm);
|
| 1143 |
+
}
|
| 1144 |
+
fill_STM(fp_ref, stm, ref_file, &ref_eof, case_sense,&ref_err);
|
| 1145 |
+
if (hyp_err != 0){
|
| 1146 |
+
fprintf(stdout,"; *Err: Error detected in hyp file '%s'\n",
|
| 1147 |
+
hyp_file);
|
| 1148 |
+
exit(1);
|
| 1149 |
+
}
|
| 1150 |
+
just_read = 1;
|
| 1151 |
+
} else
|
| 1152 |
+
just_read = 0;
|
| 1153 |
+
} while (just_read);
|
| 1154 |
+
|
| 1155 |
+
/* find the end of the second channel for the hyp file */
|
| 1156 |
+
locate_WTOKE_boundary(hyp_segs, hyp_segs->s, 1, 1, &hyp_end_chan1);
|
| 1157 |
+
if (hyp_end_chan1+1 < hyp_segs->n &&
|
| 1158 |
+
strcmp(hyp_segs->word[hyp_segs->s].conv,
|
| 1159 |
+
hyp_segs->word[hyp_end_chan1+1].conv)==0){
|
| 1160 |
+
locate_WTOKE_boundary(hyp_segs,hyp_end_chan1+1,1,1,&hyp_end_chan2);
|
| 1161 |
+
number_of_channels = 2;
|
| 1162 |
+
} else {
|
| 1163 |
+
/* There was no second channel */
|
| 1164 |
+
hyp_end_chan2 = hyp_end_chan1;
|
| 1165 |
+
number_of_channels = 1;
|
| 1166 |
+
}
|
| 1167 |
+
|
| 1168 |
+
/* find the end of the second channel for the ref file */
|
| 1169 |
+
locate_STM_boundary(stm, stm->s, 1, 1, &ref_end_chan1);
|
| 1170 |
+
if (ref_end_chan1+1 < stm->num &&
|
| 1171 |
+
TEXT_strcmp(stm->seg[stm->s].file,
|
| 1172 |
+
stm->seg[ref_end_chan1+1].file)==0){
|
| 1173 |
+
if (number_of_channels != 2){
|
| 1174 |
+
fprintf(stderr,"%s: Channel Mis-match, 1 in Hyp, 2 in Ref\n",
|
| 1175 |
+
proc);
|
| 1176 |
+
return((SCORES *)0);
|
| 1177 |
+
}
|
| 1178 |
+
locate_STM_boundary(stm, ref_end_chan1+1, 1, 1, &ref_end_chan2);
|
| 1179 |
+
} else {
|
| 1180 |
+
/* There was no second channel */
|
| 1181 |
+
if (number_of_channels != 1){
|
| 1182 |
+
fprintf(stderr,"%s: Channel Mis-match, 2 in Hyp, 1 in Ref\n",
|
| 1183 |
+
proc);
|
| 1184 |
+
return((SCORES *)0);
|
| 1185 |
+
}
|
| 1186 |
+
ref_end_chan2 = ref_end_chan1;
|
| 1187 |
+
}
|
| 1188 |
+
|
| 1189 |
+
/* give some user feedback */
|
| 1190 |
+
if (feedback >= 1)
|
| 1191 |
+
printf(" Performing alignments for file '%s'.\n",
|
| 1192 |
+
stm->seg[stm->s].file);
|
| 1193 |
+
if (db+pdb >= 5){
|
| 1194 |
+
printf("%s: hyp CTM File Range [%d,%d]",
|
| 1195 |
+
proc,hyp_segs->s,hyp_file_end);
|
| 1196 |
+
printf(" Chan1 Range[%d,%d] ",hyp_segs->s,hyp_end_chan1);
|
| 1197 |
+
printf(" Chan2 Range[%d,%d]\n",hyp_end_chan1+1,hyp_end_chan2);
|
| 1198 |
+
if (db+pdb >= 10){
|
| 1199 |
+
dump_word_tokens2(hyp_segs, hyp_segs->s, hyp_file_end);
|
| 1200 |
+
printf("\n");
|
| 1201 |
+
}
|
| 1202 |
+
printf("%s: ref STM File Range [%d,%d]",proc,stm->s,ref_file_end);
|
| 1203 |
+
printf(" Chan1 Range[%d,%d] ",stm->s, ref_end_chan1);
|
| 1204 |
+
printf(" Chan2 Range[%d,%d]\n",ref_end_chan1+1,ref_end_chan2);
|
| 1205 |
+
if (db+pdb >= 10) dump_STM(stm, stm->s, ref_file_end);
|
| 1206 |
+
printf("\n");
|
| 1207 |
+
}
|
| 1208 |
+
/* Align each channel using diff */
|
| 1209 |
+
for (i=0; i<number_of_channels; i++){
|
| 1210 |
+
int h_st, h_end, r_st, r_end;
|
| 1211 |
+
|
| 1212 |
+
if (db+pdb >= 5) printf("\n%s: Starting Channel %d\n",proc,i);
|
| 1213 |
+
if (i==0){
|
| 1214 |
+
h_st = hyp_segs->s; h_end = hyp_end_chan1;
|
| 1215 |
+
r_st = stm->s; r_end = ref_end_chan1;
|
| 1216 |
+
} else {
|
| 1217 |
+
h_st = hyp_end_chan1+1; h_end = hyp_end_chan2;
|
| 1218 |
+
r_st = ref_end_chan1+1; r_end = ref_end_chan2;
|
| 1219 |
+
}
|
| 1220 |
+
|
| 1221 |
+
if (strcmp(hyp_segs->word[h_st].conv,
|
| 1222 |
+
(char *)stm->seg[r_st].file) != 0){
|
| 1223 |
+
fprintf(stderr,"%s: File identifiers do not match,\nhyp ",proc);
|
| 1224 |
+
fprintf(stderr,"file '%s' and ref file '%s' not synchronized\n",
|
| 1225 |
+
hyp_segs->word[h_st].conv,stm->seg[r_st].file);
|
| 1226 |
+
return((SCORES *)0);
|
| 1227 |
+
}
|
| 1228 |
+
if (strcmp(hyp_segs->word[h_st].turn,
|
| 1229 |
+
(char *)stm->seg[r_st].chan) != 0){
|
| 1230 |
+
fprintf(stderr,"%s: channel identifiers do not match, ",proc);
|
| 1231 |
+
fprintf(stderr,"hyp file '%s' and ref file '%s' not",
|
| 1232 |
+
hyp_segs->word[h_st].conv,stm->seg[r_st].file);
|
| 1233 |
+
fprintf(stderr," synchronized\n");
|
| 1234 |
+
return((SCORES *)0);
|
| 1235 |
+
}
|
| 1236 |
+
|
| 1237 |
+
/* write out the words in the STM file */
|
| 1238 |
+
dump_STM_words(stm,r_st,r_end+((r_end==stm->num)?-1:0),refwords);
|
| 1239 |
+
dump_WTOKE_words(hyp_segs, h_st, h_end, hypwords);
|
| 1240 |
+
|
| 1241 |
+
if ((fp_diff = readpipe (DIFF_PROGRAM, "-y",refwords, hypwords, NULL)) == NULL){
|
| 1242 |
+
fprintf(stderr,"Error: Execution of 'diff' failed\n");
|
| 1243 |
+
exit(1);
|
| 1244 |
+
}
|
| 1245 |
+
|
| 1246 |
+
for (r=r_st; r<=r_end + ((r_end==stm->num)?-1:0); r++){
|
| 1247 |
+
path = PATH_alloc(100);
|
| 1248 |
+
path->num = 0;
|
| 1249 |
+
|
| 1250 |
+
/* for each reference word, located it's matching diff output*/
|
| 1251 |
+
ctext = tokenize_TEXT_first_alt(stm->seg[r].text,
|
| 1252 |
+
(TEXT*)" \t\n");
|
| 1253 |
+
while (ctext != NULL){
|
| 1254 |
+
do {
|
| 1255 |
+
if (TEXT_ensure_fgets(&diff_out,&diff_out_len,fp_diff)
|
| 1256 |
+
== NULL)
|
| 1257 |
+
*diff_out = '\0';
|
| 1258 |
+
if (feof(fp_diff)) break;
|
| 1259 |
+
process_diff_line(diff_out,path,&firsttoken);
|
| 1260 |
+
} while (!feof(fp_diff) &&
|
| 1261 |
+
((TEXT_strcmp(firsttoken,ctext) != 0) ||
|
| 1262 |
+
r== r_end + (r_end==stm->num)?-1:0));
|
| 1263 |
+
ctext = tokenize_TEXT_first_alt(NULL,(TEXT *)" \t\n");
|
| 1264 |
+
}
|
| 1265 |
+
spkr = SCORES_get_grp(scor,(char *)stm->seg[r].spkr);
|
| 1266 |
+
PATH_add_utt_id(path,rsprintf("(%s-%03d)",stm->seg[r].spkr,
|
| 1267 |
+
scor->grp[spkr].nsent));
|
| 1268 |
+
PATH_set_sequence(path);
|
| 1269 |
+
PATH_add_label(path,(char *)stm->seg[r].labels);
|
| 1270 |
+
PATH_add_file(path,(char *)stm->seg[r].chan);
|
| 1271 |
+
PATH_add_channel(path,(char *)stm->seg[r].chan);
|
| 1272 |
+
if (case_sense) BF_SET(path->attrib,PA_CASE_SENSE);
|
| 1273 |
+
add_PATH_score(scor,path,spkr, keep_path);
|
| 1274 |
+
|
| 1275 |
+
if (feedback >= 2){
|
| 1276 |
+
printf("\n");
|
| 1277 |
+
PATH_print(path,stdout,199);
|
| 1278 |
+
printf("\n");
|
| 1279 |
+
}
|
| 1280 |
+
if (!keep_path) PATH_free(path);
|
| 1281 |
+
}
|
| 1282 |
+
fclose(fp_diff);
|
| 1283 |
+
|
| 1284 |
+
|
| 1285 |
+
stm->s = r_end+1;
|
| 1286 |
+
} /* for each channel */
|
| 1287 |
+
|
| 1288 |
+
/* increment the start pointers */
|
| 1289 |
+
hyp_segs->s = hyp_end_chan2+1;
|
| 1290 |
+
stm->s = ref_end_chan2+1;
|
| 1291 |
+
} while (hyp_segs->s <= hyp_segs->n);
|
| 1292 |
+
|
| 1293 |
+
fclose(fp_hyp);
|
| 1294 |
+
fclose(fp_ref);
|
| 1295 |
+
|
| 1296 |
+
unlink(refwords);
|
| 1297 |
+
unlink(hypwords);
|
| 1298 |
+
free_singarr(diff_out,TEXT);
|
| 1299 |
+
|
| 1300 |
+
free_mark_file(hyp_segs);
|
| 1301 |
+
free_STM(stm);
|
| 1302 |
+
|
| 1303 |
+
return(scor);
|
| 1304 |
+
}
|
| 1305 |
+
|
| 1306 |
+
void convert_text_to_word_list(char *file, char *words,int case_sense){
|
| 1307 |
+
FILE *fp, *fp_out;
|
| 1308 |
+
TEXT *buf, *ctext;
|
| 1309 |
+
int buf_len=100;
|
| 1310 |
+
|
| 1311 |
+
if ((fp=fopen(file,"r")) == NULL){
|
| 1312 |
+
fprintf(stderr,"Error: Unable to open input STM file '%s'\n",file);
|
| 1313 |
+
exit(1);
|
| 1314 |
+
}
|
| 1315 |
+
|
| 1316 |
+
if ((fp_out=fopen(words,"w")) == NULL){
|
| 1317 |
+
fprintf(stderr,"Error: Unable to open STM word file '%s'\n",words);
|
| 1318 |
+
exit(1);
|
| 1319 |
+
}
|
| 1320 |
+
|
| 1321 |
+
alloc_singZ(buf,buf_len,TEXT,'\0');
|
| 1322 |
+
|
| 1323 |
+
/* for each stm, load the aligned text and create a path as before */
|
| 1324 |
+
while (!feof(fp)){
|
| 1325 |
+
/* read the next ref line */
|
| 1326 |
+
*buf = '\0';
|
| 1327 |
+
while (!feof(fp) && (TEXT_is_comment(buf) ||
|
| 1328 |
+
TEXT_is_comment_info(buf) ||
|
| 1329 |
+
TEXT_is_empty(buf)))
|
| 1330 |
+
if (TEXT_ensure_fgets(&buf,&buf_len,fp) == NULL)
|
| 1331 |
+
*buf = '\0';
|
| 1332 |
+
if (*buf == '\0' && feof(fp)) break;
|
| 1333 |
+
if (!case_sense) TEXT_str_case_change_with_mem_expand(&buf, &buf_len, 1);
|
| 1334 |
+
|
| 1335 |
+
/* for each reference word, located it's matching diff output */
|
| 1336 |
+
ctext = TEXT_strtok(buf,(TEXT *)" \t\n");
|
| 1337 |
+
while (ctext != NULL){
|
| 1338 |
+
fprintf(fp_out,"%s\n",ctext);
|
| 1339 |
+
ctext = TEXT_strtok(NULL,(TEXT *)" \t\n");
|
| 1340 |
+
}
|
| 1341 |
+
}
|
| 1342 |
+
fclose(fp);
|
| 1343 |
+
fclose(fp_out);
|
| 1344 |
+
free_singarr(buf,TEXT);
|
| 1345 |
+
}
|
| 1346 |
+
|
| 1347 |
+
SCORES *align_text_to_stm(char *ref_file, char *hyp_file, char *set_title, int keep_path, int case_sense, int feedback, enum id_types idt){
|
| 1348 |
+
/* char *proc="align_text_to_stm"; */
|
| 1349 |
+
FILE *fp_ref;
|
| 1350 |
+
PATH *path;
|
| 1351 |
+
SCORES *scor;
|
| 1352 |
+
int spkr, num_ref;
|
| 1353 |
+
char refwords[100], hypwords[100];
|
| 1354 |
+
TEXT *diff_out, *ref_buf, *firsttoken, *ctext;
|
| 1355 |
+
int diff_out_len=100, ref_buf_len=100;
|
| 1356 |
+
FILE *fp_diff;
|
| 1357 |
+
STM_SEG ref_seg;
|
| 1358 |
+
|
| 1359 |
+
/* allocate memory */
|
| 1360 |
+
scor = SCORES_init(set_title,20);
|
| 1361 |
+
scor->ref_fname = (char *)TEXT_strdup((TEXT *)ref_file);
|
| 1362 |
+
scor->hyp_fname = (char *)TEXT_strdup((TEXT *)hyp_file);
|
| 1363 |
+
scor->creation_date = get_date();
|
| 1364 |
+
|
| 1365 |
+
alloc_singZ(diff_out,diff_out_len,TEXT,'\0');
|
| 1366 |
+
alloc_singZ(ref_buf,ref_buf_len,TEXT,'\0');
|
| 1367 |
+
|
| 1368 |
+
set_temp_files(refwords, hypwords);
|
| 1369 |
+
|
| 1370 |
+
/* stm to word texts */
|
| 1371 |
+
convert_stm_to_word_list(ref_file,refwords,case_sense,&num_ref);
|
| 1372 |
+
|
| 1373 |
+
/* text to word separeted texts */
|
| 1374 |
+
convert_text_to_word_list(hyp_file,hypwords,case_sense);
|
| 1375 |
+
|
| 1376 |
+
/* start up diff */
|
| 1377 |
+
if ((fp_diff = readpipe (DIFF_PROGRAM,"-y",refwords, hypwords, NULL)) ==
|
| 1378 |
+
NULL){
|
| 1379 |
+
fprintf(stderr,"Error: Execution of 'diff' failed\n");
|
| 1380 |
+
exit(1);
|
| 1381 |
+
}
|
| 1382 |
+
|
| 1383 |
+
/* again, open the input reference file */
|
| 1384 |
+
if ((fp_ref = fopen(ref_file,"r")) == NULL){
|
| 1385 |
+
fprintf(stderr,"Can't open input reference file %s\n",ref_file);
|
| 1386 |
+
exit(1);
|
| 1387 |
+
}
|
| 1388 |
+
|
| 1389 |
+
/* for each stm, load the aligned text and create a path as before */
|
| 1390 |
+
while (!feof(fp_ref)){
|
| 1391 |
+
/* read the next ref line */
|
| 1392 |
+
read_stm_line(&ref_buf,&ref_buf_len,fp_ref);
|
| 1393 |
+
if (feof(fp_ref)) break;
|
| 1394 |
+
|
| 1395 |
+
/* parse the reference transcript */
|
| 1396 |
+
parse_stm_line(&ref_seg, &ref_buf, &ref_buf_len, case_sense, 0);
|
| 1397 |
+
num_ref --;
|
| 1398 |
+
|
| 1399 |
+
/* allocate a path structure */
|
| 1400 |
+
path = PATH_alloc(100); path->num = 0;
|
| 1401 |
+
|
| 1402 |
+
/* for each reference word, located it's matching diff output */
|
| 1403 |
+
ctext = tokenize_TEXT_first_alt(ref_seg.text,(TEXT *)" \t\n");
|
| 1404 |
+
while (ctext != NULL){
|
| 1405 |
+
do {
|
| 1406 |
+
if (TEXT_ensure_fgets(&diff_out,&diff_out_len,fp_diff) == NULL)
|
| 1407 |
+
*diff_out = '\0';
|
| 1408 |
+
if (feof(fp_diff)) break;
|
| 1409 |
+
process_diff_line(diff_out,path,&firsttoken);
|
| 1410 |
+
} while (!feof(fp_diff) &&
|
| 1411 |
+
((TEXT_strcmp(firsttoken,ctext) != 0) || num_ref==0));
|
| 1412 |
+
ctext = tokenize_TEXT_first_alt(NULL,(TEXT *)" \t\n");
|
| 1413 |
+
}
|
| 1414 |
+
|
| 1415 |
+
spkr = SCORES_get_grp(scor,(char *)ref_seg.spkr);
|
| 1416 |
+
PATH_add_utt_id(path,rsprintf("(%s-%03d)",ref_seg.spkr,
|
| 1417 |
+
scor->grp[spkr].num_path));
|
| 1418 |
+
PATH_set_sequence(path);
|
| 1419 |
+
PATH_add_label(path,(char *)ref_seg.labels);
|
| 1420 |
+
PATH_add_file(path,(char *)ref_seg.file);
|
| 1421 |
+
PATH_add_channel(path,(char *)ref_seg.chan);
|
| 1422 |
+
if (case_sense) BF_SET(path->attrib,PA_CASE_SENSE);
|
| 1423 |
+
add_PATH_score(scor,path,spkr, keep_path);
|
| 1424 |
+
|
| 1425 |
+
if (feedback >= 2){
|
| 1426 |
+
printf("\n");
|
| 1427 |
+
PATH_print(path,stdout,199);
|
| 1428 |
+
printf("\n");
|
| 1429 |
+
}
|
| 1430 |
+
if (!keep_path) PATH_free(path);
|
| 1431 |
+
free_STM_SEG(&ref_seg);
|
| 1432 |
+
}
|
| 1433 |
+
fclose(fp_diff);
|
| 1434 |
+
fclose(fp_ref);
|
| 1435 |
+
|
| 1436 |
+
free_singarr(diff_out,TEXT);
|
| 1437 |
+
free_singarr(ref_buf,TEXT);
|
| 1438 |
+
|
| 1439 |
+
unlink(refwords);
|
| 1440 |
+
unlink(hypwords);
|
| 1441 |
+
|
| 1442 |
+
return(scor);
|
| 1443 |
+
}
|
SCTK/src/sclite/align.o
ADDED
|
Binary file (48.7 kB). View file
|
|
|
SCTK/src/sclite/anovar.c
ADDED
|
@@ -0,0 +1,485 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**********************************************************************/
|
| 2 |
+
/* */
|
| 3 |
+
/* FILE: anovar.c */
|
| 4 |
+
/* WRITTEN BY: Jonathan G. Fiscus */
|
| 5 |
+
/* DATE: April 14 1989 */
|
| 6 |
+
/* NATIONAL INSTITUTE OF STANDARDS AND TECHNOLOGY */
|
| 7 |
+
/* SPEECH RECOGNITION GROUP */
|
| 8 |
+
/* */
|
| 9 |
+
/* USAGE: This uses the rank structure to perform */
|
| 10 |
+
/* a Friedman two-way analysis of variance */
|
| 11 |
+
/* by ranks and generates a report. */
|
| 12 |
+
/* */
|
| 13 |
+
/* SOURCE:Applied Non Parametric Statistics by Daniel */
|
| 14 |
+
/* */
|
| 15 |
+
/**********************************************************************/
|
| 16 |
+
|
| 17 |
+
#include "sctk.h"
|
| 18 |
+
|
| 19 |
+
#define FRI_TITLE "Friedman Two-way Analysis of Variance by Ranks"
|
| 20 |
+
#define RANK_TITLEA "COMPARISON MATRIX: Comparing All Systems"
|
| 21 |
+
#define RANK_TITLEB "COMPARISON MATRIX: Comparing All Speakers"
|
| 22 |
+
#define RANK_TITLE_1 "Using a Multiple Comparison Test"
|
| 23 |
+
#define ADJUST_THRESH 0.50000
|
| 24 |
+
#define MULTI_COMP_ALPHA 0.05
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
static int analyze_rank_sum(RANK *, int, int, double *, int, int, FILE *);
|
| 28 |
+
static void print_result_of_analyze_rank_sum(int, double, double, char *,FILE *);
|
| 29 |
+
static double dsum_sqr(double *, int);
|
| 30 |
+
static double calc_adjust_for_trt(RANK *);
|
| 31 |
+
static double calc_adjust_for_blks(RANK *);
|
| 32 |
+
static void do_multi_comp_for_anovar(int, int, char **, double *, double *, char *, int *, int **, int, FILE *);
|
| 33 |
+
static void calc_stat_ranks(int, int, int **, double*);
|
| 34 |
+
static double calc_comp_value(int, int);
|
| 35 |
+
static void print_ANOVAR_comp_matrix(int, int **, char **, char *, int *, FILE *);
|
| 36 |
+
|
| 37 |
+
/****************************************************************/
|
| 38 |
+
/* main procedure to perform a two-way analysis of variance by*/
|
| 39 |
+
/* ranks. first the sum of the treatment and block ranks */
|
| 40 |
+
/* are summed then if there is a difference between at least */
|
| 41 |
+
/* one of the blocks or treatments, then a multiple comparison*/
|
| 42 |
+
/* is performed */
|
| 43 |
+
/****************************************************************/
|
| 44 |
+
void compute_anovar(RANK *rank, int verbose, int report, int ***out_sys_winner, char *outroot, int feedback, double ***out_conf)
|
| 45 |
+
{
|
| 46 |
+
double *sum_trt_rank, *sum_blk_rank;
|
| 47 |
+
char pad[FULL_SCREEN];
|
| 48 |
+
int i,j, **trt_winner, **blk_winner;
|
| 49 |
+
double **conf;
|
| 50 |
+
FILE *fp = stdout;
|
| 51 |
+
|
| 52 |
+
if (report || verbose){
|
| 53 |
+
char *f = rsprintf("%s.anovar",outroot);
|
| 54 |
+
if ((fp=(strcmp(outroot,"-") == 0) ? stdout : fopen(f,"w")) ==
|
| 55 |
+
(FILE *)0){
|
| 56 |
+
fprintf(stderr,"Warning: Open of %s for write failed. "
|
| 57 |
+
"Using stdout instead.\n",f);
|
| 58 |
+
fp = stdout;
|
| 59 |
+
} else
|
| 60 |
+
if (feedback >= 1) printf(" Output written to '%s'\n",f);
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
alloc_2dimZ(conf,rank->n_trt,rank->n_trt,double,0.0);
|
| 64 |
+
alloc_2dimZ(trt_winner,rank->n_trt,rank->n_trt,int,NO_DIFF);
|
| 65 |
+
alloc_2dimZ(blk_winner,rank->n_blk,rank->n_blk,int,NO_DIFF);
|
| 66 |
+
*out_sys_winner = trt_winner;
|
| 67 |
+
*out_conf = conf;
|
| 68 |
+
|
| 69 |
+
alloc_singZ(sum_trt_rank,rnk_trt(rank),double,0.0);
|
| 70 |
+
alloc_singZ(sum_blk_rank,rnk_blks(rank),double,0.0);
|
| 71 |
+
|
| 72 |
+
/* sum the ranks */
|
| 73 |
+
for (i=0;i<rnk_blks(rank);i++)
|
| 74 |
+
for (j=0;j<rnk_trt(rank);j++){
|
| 75 |
+
sum_trt_rank[j] += Vrnk_t_rank(rank,i,j);
|
| 76 |
+
sum_blk_rank[i] += Vrnk_b_rank(rank,i,j);
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
if (verbose){
|
| 80 |
+
set_pad(pad,FRI_TITLE, FULL_SCREEN);
|
| 81 |
+
fprintf(fp,"\n\n\n%s%s\n",pad,FRI_TITLE);
|
| 82 |
+
fprintf(fp,"%s----------------------------------------------\n\n",pad);
|
| 83 |
+
set_pad_cent_n(pad,SCREEN_WIDTH, FULL_SCREEN);
|
| 84 |
+
fprintf(fp,"%s\tHo: Testing the hypothesis that all recognizers are the same",
|
| 85 |
+
pad);
|
| 86 |
+
}
|
| 87 |
+
/* if at least one difference, do multiple comparison */
|
| 88 |
+
if (analyze_rank_sum(rank,rnk_trt(rank),rnk_blks(rank),
|
| 89 |
+
sum_trt_rank,
|
| 90 |
+
FOR_TREATMENTS,verbose,fp) == TEST_DIFF)
|
| 91 |
+
clear_2dim(trt_winner,rank->n_trt,rank->n_trt,NO_DIFF);
|
| 92 |
+
do_multi_comp_for_anovar(rnk_trt(rank),rnk_blks(rank),
|
| 93 |
+
rnk_t_name(rank),sum_trt_rank,
|
| 94 |
+
ovr_t_rank(rank),RANK_TITLEA,
|
| 95 |
+
srt_t_rank(rank),trt_winner,verbose,fp);
|
| 96 |
+
if (verbose) form_feed(fp);
|
| 97 |
+
|
| 98 |
+
if (verbose){
|
| 99 |
+
set_pad(pad,FRI_TITLE, FULL_SCREEN);
|
| 100 |
+
fprintf(fp,"\n\n\n%s%s\n",pad,FRI_TITLE);
|
| 101 |
+
fprintf(fp,"%s----------------------------------------------\n\n",pad);
|
| 102 |
+
set_pad_cent_n(pad,SCREEN_WIDTH, FULL_SCREEN);
|
| 103 |
+
fprintf(fp,"%s\tHo: Testing the hypothesis that all speakers are the same",
|
| 104 |
+
pad);
|
| 105 |
+
}
|
| 106 |
+
/* if at least one difference, do multiple comparison */
|
| 107 |
+
if (analyze_rank_sum(rank,rnk_blks(rank),rnk_trt(rank),sum_blk_rank,
|
| 108 |
+
FOR_BLOCKS,verbose,fp) == TEST_DIFF)
|
| 109 |
+
clear_2dim(blk_winner,rank->n_blk,rank->n_blk,NO_DIFF);
|
| 110 |
+
do_multi_comp_for_anovar(rnk_blks(rank),rnk_trt(rank),
|
| 111 |
+
rnk_b_name(rank),sum_blk_rank,
|
| 112 |
+
ovr_b_rank(rank),RANK_TITLEB,
|
| 113 |
+
srt_b_rank(rank),blk_winner, verbose,fp);
|
| 114 |
+
if (verbose && (fp == stdout)) form_feed(fp);
|
| 115 |
+
free_2dimarr(blk_winner,rank->n_blk,int);
|
| 116 |
+
free_singarr(sum_trt_rank,double);
|
| 117 |
+
free_singarr(sum_blk_rank,double);
|
| 118 |
+
if (fp != stdout) fclose(fp);
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
/*****************************************************************/
|
| 122 |
+
/* X2_r formula: */
|
| 123 |
+
/* k */
|
| 124 |
+
/* 12 --. 2 */
|
| 125 |
+
/* ------- * \ R - 3b(t+1) */
|
| 126 |
+
/* bt(t+1) / j */
|
| 127 |
+
/* --' */
|
| 128 |
+
/* j = 1 */
|
| 129 |
+
/* */
|
| 130 |
+
/* b = num_blk */
|
| 131 |
+
/* t = num_trt */
|
| 132 |
+
/* R = Sum of the ranks for that column */
|
| 133 |
+
/* */
|
| 134 |
+
/* this is the initial test to see if the treatment or ranks */
|
| 135 |
+
/* are different */
|
| 136 |
+
/*****************************************************************/
|
| 137 |
+
static int analyze_rank_sum(RANK *rank, int trt_num, int blk_num, double *sum_arr, int orient, int verbose,FILE *fp)
|
| 138 |
+
{
|
| 139 |
+
int df;
|
| 140 |
+
double X2_r, adjust;
|
| 141 |
+
char *subject_blk = "speaker";
|
| 142 |
+
char *subject_trt = "recognition system";
|
| 143 |
+
|
| 144 |
+
/* calculate the test statistic */
|
| 145 |
+
df = trt_num - 2; /* #trt is one based so subtract 2 */
|
| 146 |
+
/* make sure df isn't negative */;
|
| 147 |
+
if (df < 0) df = 0;
|
| 148 |
+
/* make sure df isn't greater than MAX_DF */
|
| 149 |
+
if (df > MAX_DF) df = MAX_DF;
|
| 150 |
+
|
| 151 |
+
X2_r = (12.00000 /
|
| 152 |
+
(double)(blk_num*trt_num*(trt_num+1))) *
|
| 153 |
+
(dsum_sqr(sum_arr,trt_num)) -
|
| 154 |
+
3.00000 * (double)blk_num * (double)(trt_num+1);
|
| 155 |
+
if (orient == FOR_TREATMENTS)
|
| 156 |
+
adjust = calc_adjust_for_trt(rank);
|
| 157 |
+
else
|
| 158 |
+
adjust = calc_adjust_for_blks(rank);
|
| 159 |
+
|
| 160 |
+
/* if two identical systems are entered, adjust will be 0.0 and core*/
|
| 161 |
+
/* dump. this avoids this */
|
| 162 |
+
if (adjust == 0.0)
|
| 163 |
+
X2_r = 0.0;
|
| 164 |
+
else
|
| 165 |
+
X2_r /= adjust;
|
| 166 |
+
|
| 167 |
+
if (verbose) {
|
| 168 |
+
if (orient == FOR_TREATMENTS)
|
| 169 |
+
print_result_of_analyze_rank_sum(df, X2_r, adjust, subject_trt,fp);
|
| 170 |
+
else
|
| 171 |
+
print_result_of_analyze_rank_sum(df, X2_r, adjust, subject_blk,fp);
|
| 172 |
+
}
|
| 173 |
+
/* return the result */
|
| 174 |
+
if (X2_r > X2.df[df].level[GEN_X2_PER])
|
| 175 |
+
return(TEST_DIFF);
|
| 176 |
+
else
|
| 177 |
+
return(NO_DIFF);
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
/*****************************************************************/
|
| 181 |
+
/* print to stdout the results of the rank_sum test */
|
| 182 |
+
/*****************************************************************/
|
| 183 |
+
static void print_result_of_analyze_rank_sum(int df, double X2_r, double adjust, char *subject, FILE *fp)
|
| 184 |
+
{
|
| 185 |
+
char pad[FULL_SCREEN];
|
| 186 |
+
int i;
|
| 187 |
+
|
| 188 |
+
set_pad_cent_n(pad,SCREEN_WIDTH, FULL_SCREEN);
|
| 189 |
+
fprintf(fp,"\n\n\n%s%35sReject if\n",pad,"");
|
| 190 |
+
fprintf(fp,"%s%26sX2_r > X2 of %s %s (%2.3f)\n", pad, "",
|
| 191 |
+
X2_pct_str(GEN_X2_PER),
|
| 192 |
+
X2_df_str(df),
|
| 193 |
+
X2_score(df,GEN_X2_PER));
|
| 194 |
+
fprintf(fp,"\n");
|
| 195 |
+
fprintf(fp,"%s%26sadjustment = %2.3f\n",pad,"",adjust);
|
| 196 |
+
fprintf(fp,"%s%30s X2_r = %2.3f\n",pad,"",X2_r);
|
| 197 |
+
if (adjust < ADJUST_THRESH){
|
| 198 |
+
fprintf(fp,"\n\n%s\t\t*** Warning: ties adjustment may have severely\n",
|
| 199 |
+
pad);
|
| 200 |
+
fprintf(fp,"%s\t\t exagerated the X2_r value\n\n",pad);
|
| 201 |
+
}
|
| 202 |
+
fprintf(fp,"%sANALYSIS:\n%s--------\n",pad,pad);
|
| 203 |
+
if (X2_r > X2_score(df,GEN_X2_PER)){
|
| 204 |
+
fprintf(fp,"%s\tThe test statistic X2_r shows, with %s confidence, that at\n"
|
| 205 |
+
,pad,X2.neg_per_str[GEN_X2_PER]),
|
| 206 |
+
fprintf(fp,"%s\tleast one %s is significantly different.\n",pad,subject);
|
| 207 |
+
fprintf(fp,"\n");
|
| 208 |
+
fprintf(fp,"%s\tFurther, the probablity of there being a difference is\n",
|
| 209 |
+
pad);
|
| 210 |
+
for (i=GEN_X2_PER;i<MAX_X2_PER;i++)
|
| 211 |
+
if (X2_r < X2_score(df,i+1))
|
| 212 |
+
break;
|
| 213 |
+
if (i==MAX_X2_PER)
|
| 214 |
+
fprintf(fp,"%s\tgreater that %s.\n",pad,X2_neg_pct_str(i));
|
| 215 |
+
else
|
| 216 |
+
fprintf(fp,"%s\tbetween %s to %s.\n",pad,X2_neg_pct_str(i),
|
| 217 |
+
X2_neg_pct_str(i+1));
|
| 218 |
+
fprintf(fp,"\n\n");
|
| 219 |
+
}
|
| 220 |
+
else{
|
| 221 |
+
fprintf(fp,"%s\tThe test statistic X2_r shows that at the %s confidence\n"
|
| 222 |
+
,pad,X2_neg_pct_str(GEN_X2_PER)),
|
| 223 |
+
fprintf(fp,"%s\tinterval, the %ss are not significantly\n",pad,subject);
|
| 224 |
+
fprintf(fp,"%s\tdifferent.\n\n",pad);
|
| 225 |
+
fprintf(fp,"%s\tFurther, the probablity of there being a difference is\n"
|
| 226 |
+
,pad);
|
| 227 |
+
for (i=GEN_X2_PER;i>MIN_X2_PER;i--)
|
| 228 |
+
if (X2_r > X2_score(df,i-1))
|
| 229 |
+
break;
|
| 230 |
+
if (i==MIN_X2_PER)
|
| 231 |
+
fprintf(fp,"%s\tless than %s.\n",pad,X2_neg_pct_str(i));
|
| 232 |
+
else
|
| 233 |
+
fprintf(fp,"%s\tbetween %s to %s.\n",pad,X2_neg_pct_str(i-1),
|
| 234 |
+
X2_neg_pct_str(i));
|
| 235 |
+
fprintf(fp,"\n\n");
|
| 236 |
+
}
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
/********************************************************************/
|
| 240 |
+
/* return the doubleing point value of the sum of the squares */
|
| 241 |
+
/********************************************************************/
|
| 242 |
+
static double dsum_sqr(double *arr, int len)
|
| 243 |
+
{
|
| 244 |
+
int i;
|
| 245 |
+
double tot=0.000000;
|
| 246 |
+
|
| 247 |
+
for (i=0;i<len;i++)
|
| 248 |
+
tot += (arr[i]*arr[i]);
|
| 249 |
+
return(tot);
|
| 250 |
+
}
|
| 251 |
+
|
| 252 |
+
/********************************************************************/
|
| 253 |
+
/* Ties adjustments */
|
| 254 |
+
/* b */
|
| 255 |
+
/* --. */
|
| 256 |
+
/* 1 - \ T */
|
| 257 |
+
/* / i */
|
| 258 |
+
/* --' */
|
| 259 |
+
/* ----------- */
|
| 260 |
+
/* 2 */
|
| 261 |
+
/* bt(t -1) */
|
| 262 |
+
/* */
|
| 263 |
+
/* 3 */
|
| 264 |
+
/* T = Sum t - Sum t where t = num ties in ith block */
|
| 265 |
+
/* i i i */
|
| 266 |
+
/* */
|
| 267 |
+
/* to adjust for ties, the test statistic must be taken down */
|
| 268 |
+
/* by a certain factor, this function returns it */
|
| 269 |
+
/********************************************************************/
|
| 270 |
+
static double calc_adjust_for_trt(RANK *rank)
|
| 271 |
+
{
|
| 272 |
+
double *sort_arr;
|
| 273 |
+
int sort_num, *sort_count, i, j, sum_T=0;
|
| 274 |
+
|
| 275 |
+
alloc_singarr(sort_arr,rnk_trt(rank),double);
|
| 276 |
+
alloc_singarr(sort_count,rnk_trt(rank),int);
|
| 277 |
+
|
| 278 |
+
/* find the ties ans sum Ti */
|
| 279 |
+
for (i=0;i<rnk_blks(rank);i++){
|
| 280 |
+
for (j=0;j<rnk_trt(rank); j++){
|
| 281 |
+
sort_arr[j]=0.0;
|
| 282 |
+
sort_count[j]=0;
|
| 283 |
+
}
|
| 284 |
+
for (j=0;j<rnk_trt(rank); j++){
|
| 285 |
+
sort_num = 0;
|
| 286 |
+
while ((sort_arr[sort_num] != 0.0) &&
|
| 287 |
+
(Vrnk_t_rank(rank,i,j) != sort_arr[sort_num]))
|
| 288 |
+
sort_num++;
|
| 289 |
+
sort_arr[sort_num] = Vrnk_t_rank(rank,i,j);
|
| 290 |
+
sort_count[sort_num]++;
|
| 291 |
+
}
|
| 292 |
+
for (j=0;j<rnk_trt(rank); j++)
|
| 293 |
+
if (sort_count[j] > 0)
|
| 294 |
+
sum_T += (sort_count[j] * sort_count[j] * sort_count[j])
|
| 295 |
+
- sort_count[j];
|
| 296 |
+
}
|
| 297 |
+
free_singarr(sort_arr,double);
|
| 298 |
+
free_singarr(sort_count,int);
|
| 299 |
+
|
| 300 |
+
/* return the adjustment number */
|
| 301 |
+
return( 1.000000 - (sum_T/
|
| 302 |
+
(double)(rnk_blks(rank)*
|
| 303 |
+
rnk_trt(rank)*
|
| 304 |
+
((rnk_trt(rank) * rnk_trt(rank)) - 1))));
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
/********************************************************************/
|
| 308 |
+
/* see calc_adjust_for_trt but substitute B for t */
|
| 309 |
+
/********************************************************************/
|
| 310 |
+
static double calc_adjust_for_blks(RANK *rank)
|
| 311 |
+
{
|
| 312 |
+
double *sort_arr;
|
| 313 |
+
int sort_num, *sort_count, i, j, sum_T=0;
|
| 314 |
+
|
| 315 |
+
alloc_singarr(sort_arr,rnk_blks(rank),double);
|
| 316 |
+
alloc_singarr(sort_count,rnk_blks(rank),int);
|
| 317 |
+
|
| 318 |
+
/* find the ties ans sum Ti */
|
| 319 |
+
for (i=0;i<rnk_trt(rank);i++){
|
| 320 |
+
for (j=0;j<rnk_blks(rank); j++){
|
| 321 |
+
sort_arr[j]=0.0;
|
| 322 |
+
sort_count[j]=0;
|
| 323 |
+
}
|
| 324 |
+
for (j=0;j<rnk_blks(rank); j++){
|
| 325 |
+
sort_num = 0;
|
| 326 |
+
while ((sort_arr[sort_num] != 0.0) &&
|
| 327 |
+
(Vrnk_b_rank(rank,j,i) != sort_arr[sort_num]))
|
| 328 |
+
sort_num++;
|
| 329 |
+
sort_arr[sort_num] = Vrnk_b_rank(rank,j,i);
|
| 330 |
+
sort_count[sort_num]++;
|
| 331 |
+
}
|
| 332 |
+
for (j=0;j<rnk_trt(rank); j++)
|
| 333 |
+
if (sort_count[j] > 0)
|
| 334 |
+
sum_T += (sort_count[j] * sort_count[j] * sort_count[j])
|
| 335 |
+
- sort_count[j];
|
| 336 |
+
}
|
| 337 |
+
free_singarr(sort_arr,double);
|
| 338 |
+
free_singarr(sort_count,int);
|
| 339 |
+
/* return the adjustment number */
|
| 340 |
+
return( 1.000000 - (sum_T/
|
| 341 |
+
(double)(rnk_trt(rank)*
|
| 342 |
+
rnk_blks(rank)*
|
| 343 |
+
((rnk_blks(rank) * rnk_blks(rank)) - 1))));
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
/********************************************************************/
|
| 347 |
+
/* for the treatments, calculate and do the MULTIPLE comparison */
|
| 348 |
+
/* print everything out if requested */
|
| 349 |
+
/********************************************************************/
|
| 350 |
+
static void do_multi_comp_for_anovar(int trt_num, int blk_num, char **trt_names, double *sum_arr, double *ovr_rank_arr, char *title, int *srt_ptr, int **stat_sum, int verbose, FILE *fp)
|
| 351 |
+
{
|
| 352 |
+
calc_stat_ranks(trt_num,blk_num,stat_sum,sum_arr);
|
| 353 |
+
|
| 354 |
+
if (verbose)
|
| 355 |
+
print_ANOVAR_comp_matrix(trt_num,stat_sum,trt_names,title,srt_ptr,fp);
|
| 356 |
+
}
|
| 357 |
+
|
| 358 |
+
/*********************************************************************/
|
| 359 |
+
/* Multiple comparison test to rank the systems */
|
| 360 |
+
/* ________ */
|
| 361 |
+
/* / bt(t+1) */
|
| 362 |
+
/* | R - R | >= z / -------- */
|
| 363 |
+
/* j i V 6 */
|
| 364 |
+
/* */
|
| 365 |
+
/* R = the Sum of the nth column ranks */
|
| 366 |
+
/* z = Z score the alpha = 0.05 */
|
| 367 |
+
/* ---- */
|
| 368 |
+
/* t(t-1) */
|
| 369 |
+
/* */
|
| 370 |
+
/* go through all possible comparisons and rank the treatments for */
|
| 371 |
+
/* according to the number of treatments beaten or beaten by */
|
| 372 |
+
/* */
|
| 373 |
+
/*********************************************************************/
|
| 374 |
+
static void calc_stat_ranks(int trt_num, int blk_num, int **stat_sum, double *sum_arr)
|
| 375 |
+
{
|
| 376 |
+
int comp1, comp2, result;
|
| 377 |
+
double Zcomp_value, compare_value;
|
| 378 |
+
double sqr_root;
|
| 379 |
+
|
| 380 |
+
/* calculate the comparison value for the confidence interval */
|
| 381 |
+
Zcomp_value = calc_comp_value(trt_num,blk_num);
|
| 382 |
+
sqr_root = sqrt(blk_num * trt_num * (trt_num - 1) / 6.000000);
|
| 383 |
+
compare_value = (double)Zcomp_value * (double)sqr_root;
|
| 384 |
+
|
| 385 |
+
/* go through the comparison and build an array to rank */
|
| 386 |
+
for (comp1=0; comp1 <(trt_num-1); comp1++)
|
| 387 |
+
for (comp2=comp1+1; comp2<(trt_num); comp2++){
|
| 388 |
+
if (fabs(sum_arr[comp1] - sum_arr[comp2]) >= compare_value)
|
| 389 |
+
if (sum_arr[comp1] > sum_arr[comp2])
|
| 390 |
+
result = 1;
|
| 391 |
+
else
|
| 392 |
+
result = -1;
|
| 393 |
+
else
|
| 394 |
+
result = 0;
|
| 395 |
+
stat_sum[comp1][comp2] += result;
|
| 396 |
+
stat_sum[comp2][comp1] += result * (-1);
|
| 397 |
+
}
|
| 398 |
+
}
|
| 399 |
+
|
| 400 |
+
/*********************************************************************/
|
| 401 |
+
/* Given the alpha, find the closest approximate Z index to that */
|
| 402 |
+
/* percentage */
|
| 403 |
+
/*********************************************************************/
|
| 404 |
+
static double calc_comp_value(int trt_num, int blk_num)
|
| 405 |
+
{
|
| 406 |
+
double Z_area;
|
| 407 |
+
int i;
|
| 408 |
+
|
| 409 |
+
Z_area = MULTI_COMP_ALPHA / (double)(trt_num * (trt_num-1));
|
| 410 |
+
|
| 411 |
+
if (Z_area < Z_exter(Z1tail,MAX_Z_PER))
|
| 412 |
+
return(Z_score(Z1tail,MAX_Z_PER));
|
| 413 |
+
|
| 414 |
+
for (i=MAX_Z_PER+1; i< MIN_Z_PER ; i++)
|
| 415 |
+
if (Z_area < Z_exter(Z1tail,i))
|
| 416 |
+
return(Z_score(Z1tail,i));
|
| 417 |
+
|
| 418 |
+
return(Z_score(Z1tail,MIN_Z_PER));
|
| 419 |
+
}
|
| 420 |
+
|
| 421 |
+
|
| 422 |
+
static void print_ANOVAR_comp_matrix(int trt_num, int **stat_sum, char **trt_names, char *title, int *srt_ptr, FILE *fp)
|
| 423 |
+
{
|
| 424 |
+
char pad[FULL_SCREEN],name_format[50],*hyphens="--------------------";
|
| 425 |
+
char *spaces=" ";
|
| 426 |
+
int t, t2;
|
| 427 |
+
int max_trt_name_len=4, hy_l=20;
|
| 428 |
+
|
| 429 |
+
set_pad(pad,title, FULL_SCREEN);
|
| 430 |
+
fprintf(fp,"\n\n%s%s\n",pad,title);
|
| 431 |
+
set_pad(pad,RANK_TITLE_1, FULL_SCREEN);
|
| 432 |
+
fprintf(fp,"%s%s\n\n\n\n",pad,RANK_TITLE_1);
|
| 433 |
+
|
| 434 |
+
for (t=0; t<trt_num; t++)
|
| 435 |
+
if (max_trt_name_len < strlen(trt_names[t]))
|
| 436 |
+
max_trt_name_len = strlen(trt_names[t]);
|
| 437 |
+
set_pad_cent_n(pad,(trt_num+1) * (max_trt_name_len+2+1), FULL_SCREEN);
|
| 438 |
+
sprintf(name_format,"| %%-%ds ",max_trt_name_len);
|
| 439 |
+
|
| 440 |
+
/* first line */
|
| 441 |
+
fprintf(fp,"%s|%s",pad,(hyphens+(hy_l-(max_trt_name_len+2))));
|
| 442 |
+
for (t=0; t<trt_num; t++)
|
| 443 |
+
fprintf(fp,"%s",(hyphens+(hy_l-(max_trt_name_len+3))));
|
| 444 |
+
fprintf(fp,"|\n");
|
| 445 |
+
|
| 446 |
+
/* systems on top */
|
| 447 |
+
fprintf(fp,"%s|%s",pad,(spaces+(hy_l-(max_trt_name_len+2))));
|
| 448 |
+
for (t=0; t<trt_num; t++)
|
| 449 |
+
fprintf(fp,name_format,trt_names[srt_ptr[t]]);
|
| 450 |
+
fprintf(fp,"|\n");
|
| 451 |
+
|
| 452 |
+
/* separation line */
|
| 453 |
+
fprintf(fp,"%s|%s+",pad,(hyphens+(hy_l-(max_trt_name_len+2))));
|
| 454 |
+
for (t=0; t<trt_num-1; t++)
|
| 455 |
+
fprintf(fp,"%s",(hyphens+(hy_l-(max_trt_name_len+3))));
|
| 456 |
+
fprintf(fp,"%s|\n",(hyphens+(hy_l-(max_trt_name_len+2))));
|
| 457 |
+
|
| 458 |
+
/* systems */
|
| 459 |
+
for (t=0; t<trt_num; t++){
|
| 460 |
+
fprintf(fp,"%s",pad);
|
| 461 |
+
fprintf(fp,name_format,trt_names[srt_ptr[t]]);
|
| 462 |
+
for (t2=0; t2<trt_num; t2++){
|
| 463 |
+
if (t < t2)
|
| 464 |
+
switch (stat_sum[srt_ptr[t]][srt_ptr[t2]]) {
|
| 465 |
+
case -1: fprintf(fp,name_format,trt_names[srt_ptr[t]]);
|
| 466 |
+
break;
|
| 467 |
+
case 1: fprintf(fp,name_format,trt_names[srt_ptr[t2]]);
|
| 468 |
+
break;
|
| 469 |
+
default: fprintf(fp,name_format,"same");
|
| 470 |
+
break;
|
| 471 |
+
}
|
| 472 |
+
else
|
| 473 |
+
fprintf(fp,name_format,"");
|
| 474 |
+
}
|
| 475 |
+
fprintf(fp,"|\n");
|
| 476 |
+
}
|
| 477 |
+
|
| 478 |
+
/* last line */
|
| 479 |
+
fprintf(fp,"%s|%s",pad,(hyphens+(hy_l-(max_trt_name_len+2))));
|
| 480 |
+
for (t=0; t<trt_num; t++)
|
| 481 |
+
fprintf(fp,"%s",(hyphens+(hy_l-(max_trt_name_len+3))));
|
| 482 |
+
fprintf(fp,"|\n");
|
| 483 |
+
}
|
| 484 |
+
|
| 485 |
+
|
SCTK/src/sclite/arcseq1.c
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* file arcseq1.c */
|
| 2 |
+
|
| 3 |
+
#include "sctk.h"
|
| 4 |
+
|
| 5 |
+
boolean arcs_equal(ARC *arc1, ARC *arc2)
|
| 6 |
+
/***************************************************/
|
| 7 |
+
/* Determines if two arcs of a network are equal. */
|
| 8 |
+
/***************************************************/
|
| 9 |
+
{if ((arc1->from_node == arc2->from_node) &&
|
| 10 |
+
/* (streq(arc1->symbol,arc2->symbol)) && */
|
| 11 |
+
(arc1->to_node == arc2->to_node)) return T;
|
| 12 |
+
else return F;
|
| 13 |
+
}
|
SCTK/src/sclite/arcseq1.o
ADDED
|
Binary file (1.24 kB). View file
|
|
|
SCTK/src/sclite/config.in
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
dnl Process this file with autoconf to produce a configure script.
|
| 2 |
+
AC_INIT(sclite.c)
|
| 3 |
+
|
| 4 |
+
dnl Checks for programs.
|
| 5 |
+
AC_PROG_CC
|
| 6 |
+
dnl AC_PROG_INSTALL
|
| 7 |
+
AC_PROG_MAKE_SET
|
| 8 |
+
|
| 9 |
+
dnl Checks for libraries.
|
| 10 |
+
dnl Replace `main' with a function in -lm:
|
| 11 |
+
AC_CHECK_LIB(m, main)
|
| 12 |
+
|
| 13 |
+
dnl Checks for header files.
|
| 14 |
+
AC_HEADER_STDC
|
| 15 |
+
AC_CHECK_HEADERS(unistd.h)
|
| 16 |
+
|
| 17 |
+
dnl If gcc is used, check the system. If it's any of the below,
|
| 18 |
+
dnl add OPTIONS to CFLAGS
|
| 19 |
+
if test "$CC" = "cc" ; then
|
| 20 |
+
echo "Setting default CFLAGS for Native cc"
|
| 21 |
+
case "`uname -s`" in
|
| 22 |
+
OSF1) CFLAGS="$CFLAGS -std1"; export CFLAGS;;
|
| 23 |
+
HP-UX) CFLAGS="$CFLAGS -Ae"; export CFLAGS;;
|
| 24 |
+
esac
|
| 25 |
+
fi
|
| 26 |
+
|
| 27 |
+
dnl Checks for typedefs, structures, and compiler characteristics.
|
| 28 |
+
AC_C_CONST
|
| 29 |
+
AC_TYPE_SIZE_T
|
| 30 |
+
|
| 31 |
+
dnl Checks for library functions.
|
| 32 |
+
dnl AC_FUNC_VPRINTF
|
| 33 |
+
dnl AC_CHECK_FUNCS(strdup)
|
| 34 |
+
dnl AC_CHECK_FUNC(readpipe)
|
| 35 |
+
|
| 36 |
+
AC_PATH_PROGS(INSTALL, install cp copy)
|
| 37 |
+
|
| 38 |
+
echo ""
|
| 39 |
+
echo "!!!!!!!!!!!!! USER INFORMATION NEEDED !!!!!!!!!!!!!"
|
| 40 |
+
echo ""
|
| 41 |
+
echo "Sclite has the ability to use GNU's 'diff' program as means to"
|
| 42 |
+
echo "align reference and hypothesis strings. Currently, no evaluations"
|
| 43 |
+
echo "have used GNU-DIFF for alignments, so it may be unnecessary for"
|
| 44 |
+
echo "you to enable its use. Also, some versions of GNU's diff, V2.8.1,"
|
| 45 |
+
echo "will not work with GB encoded Mandarin characters and test6 of the"
|
| 46 |
+
echo "test suite will fail."
|
| 47 |
+
echo ""
|
| 48 |
+
echo " Do you want to enable alignments via GNU's 'diff'? yes or no"
|
| 49 |
+
echo ""
|
| 50 |
+
ans=""
|
| 51 |
+
while test "$ans" = "" ; do
|
| 52 |
+
read ans
|
| 53 |
+
ans=`echo $ans | tr 'A-Z' 'a-z'`
|
| 54 |
+
if test "$ans" = "no" ; then
|
| 55 |
+
echo "Disabling GNU-DIFF alignments"
|
| 56 |
+
elif test "$ans" = "yes" ; then
|
| 57 |
+
echo "Enabling GNU-DIFF alignments"
|
| 58 |
+
else
|
| 59 |
+
echo "Error: You must respond either yes or no"
|
| 60 |
+
ans=""
|
| 61 |
+
fi
|
| 62 |
+
done
|
| 63 |
+
|
| 64 |
+
CFLAGS_BEFORE_DIFF=$CFLAGS
|
| 65 |
+
if test "$ans" = "yes" ; then
|
| 66 |
+
AC_PATH_PROGS(DIFF, gnudiff diffgnu gdiff diff)
|
| 67 |
+
case "$DIFF" in
|
| 68 |
+
*gdiff)
|
| 69 |
+
# Carefully avoid gdiff for X as found on SGI systems.
|
| 70 |
+
DISPLAY= gdiff /dev/null /dev/null > /dev/null 2>&1 || DIFF=""
|
| 71 |
+
if test -z "$DIFF" ; then
|
| 72 |
+
echo " Not using $DIFF, it's an X window executable"
|
| 73 |
+
AC_PATH_PROGS(NDIFF, diff)
|
| 74 |
+
DIFF=$NDIFF
|
| 75 |
+
fi
|
| 76 |
+
;;
|
| 77 |
+
esac
|
| 78 |
+
if test -z "$DIFF" ; then
|
| 79 |
+
echo "Error: Unable to locate 'diff'"
|
| 80 |
+
exit 1
|
| 81 |
+
fi
|
| 82 |
+
echo " Making sure diff supports '-y'"
|
| 83 |
+
if test ! -z "`$DIFF -y /dev/null /dev/null 2>&1`" ; then
|
| 84 |
+
echo "Error: $DIFF does not support '-y'. Install GNU's diff"
|
| 85 |
+
exit 1
|
| 86 |
+
fi
|
| 87 |
+
CFLAGS="$CFLAGS -DDIFF_EXE=\\\"\$(GNUDIFF)\\\""
|
| 88 |
+
else
|
| 89 |
+
DIFF=""
|
| 90 |
+
fi
|
| 91 |
+
|
| 92 |
+
echo ""
|
| 93 |
+
echo "!!!!!!!!!!!!! USER INFORMATION NEEDED !!!!!!!!!!!!!"
|
| 94 |
+
echo ""
|
| 95 |
+
echo "In support of the LVCSR/HUB-5 evaluations, a newly defined DP"
|
| 96 |
+
echo "alignment cost function has been incorporated into SCTK. The cost"
|
| 97 |
+
echo "function is defined to be a function of language model probabilities."
|
| 98 |
+
echo "In order to compute the LM probabilities, the CMU-Cambridge SLM"
|
| 99 |
+
echo "Toolkit - V2 has been included in SCTK. The compilation including"
|
| 100 |
+
echo "the SLM toolkit is optional, depending on your needs."
|
| 101 |
+
echo ""
|
| 102 |
+
echo " Do you want to compile in the CMU-Cambridge SLM toolkit? yes or no"
|
| 103 |
+
echo ""
|
| 104 |
+
ans=""
|
| 105 |
+
SLM_DEFS=""
|
| 106 |
+
while test "$ans" = "" ; do
|
| 107 |
+
read ans
|
| 108 |
+
ans=`echo $ans | tr 'A-Z' 'a-z'`
|
| 109 |
+
if test "$ans" = "no" ; then
|
| 110 |
+
echo "Disabling Compilation of CMU-Cambridge SLM "
|
| 111 |
+
SLM_TARGETS=""
|
| 112 |
+
elif test "$ans" = "yes" ; then
|
| 113 |
+
echo "Enabling Compilation of CMU-Cambridge SLM "
|
| 114 |
+
echo " Checking for Un-expanded tar archive of SLM"
|
| 115 |
+
if test -f slm_v2.tar ; then
|
| 116 |
+
echo " Expanding tar file"
|
| 117 |
+
tar xf slm_v2.tar
|
| 118 |
+
rm slm_v2.tar
|
| 119 |
+
fi
|
| 120 |
+
echo " Checking Endian-ness for SLM toolkit"
|
| 121 |
+
echo 'main(){short s=1; char *b=(char *)&s; printf("%s",(*b==0)?"Big":"Little");}' > x.c
|
| 122 |
+
$CC $CFLAGS_BEFORE_DIFF x.c -o a.out
|
| 123 |
+
endian=`./a.out`
|
| 124 |
+
rm -f a.out x.c
|
| 125 |
+
|
| 126 |
+
if test "$endian" = "Little" ; then
|
| 127 |
+
SLM_DEFS="-DSLM_SWAP_BYTES"
|
| 128 |
+
echo " Little-endian machine"
|
| 129 |
+
else
|
| 130 |
+
echo " Big-endian machine"
|
| 131 |
+
fi
|
| 132 |
+
CFLAGS="$CFLAGS -DWITH_SLM"
|
| 133 |
+
SLM_TARGETS="slm_v2/lib/SLM2.a"
|
| 134 |
+
cat slm_v2/src/makefile.in | \
|
| 135 |
+
sed "s/@CC@/$CC/" | \
|
| 136 |
+
sed "s/@SCTK_FLAGS@/$CFLAGS_BEFORE_DIFF/" | \
|
| 137 |
+
sed "s/@SLM_DEFS@/$SLM_DEFS/" > slm_v2/src/makefile
|
| 138 |
+
else
|
| 139 |
+
echo "Error: You must respond either yes or no"
|
| 140 |
+
ans=""
|
| 141 |
+
fi
|
| 142 |
+
done
|
| 143 |
+
|
| 144 |
+
AC_SUBST(SLM_DEFS)
|
| 145 |
+
AC_SUBST(SLM_TARGETS)
|
| 146 |
+
|
| 147 |
+
dnl Check to see if nist.local exists. If it does, define AT_NIST.
|
| 148 |
+
echo "Checking installation site"
|
| 149 |
+
test -f nist.local && CFLAGS="$CFLAGS -DAT_NIST -DPEDANTIC -ansi -pedantic -pedantic-errors -Wall -Wstrict-prototypes -Wmissing-prototypes -DWARN_ZERO_MALLOC"
|
| 150 |
+
|
| 151 |
+
AC_OUTPUT(Makefile)
|
SCTK/src/sclite/ctm2ctm.c
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "sctk.h"
|
| 2 |
+
|
| 3 |
+
int chop_WTOKE_2(WTOKE_STR1 *ref, WTOKE_STR1 *hyp, int Rstart, int Hstart, int Rendconv, int Hendconv, int max_words, int *Rret_end, int *Hret_end);
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
SCORES *align_ctm_to_ctm(char *hyp_file, char *ref_file, char *set_title, int feedback, int fcorr, int opt_del, int case_sense, int time_align, int left_to_right, WWL *wwl, char *lm_file){
|
| 7 |
+
|
| 8 |
+
char *proc = "align_ctm_to_ctm";
|
| 9 |
+
WTOKE_STR1 *hyp;
|
| 10 |
+
WTOKE_STR1 *ref;
|
| 11 |
+
FILE *fp_hyp, *fp_ref;
|
| 12 |
+
int hyp_conv_end, hyp_eof;
|
| 13 |
+
int ref_conv_end, ref_eof;
|
| 14 |
+
int hyp_chop_end, ref_chop_end;
|
| 15 |
+
int i;
|
| 16 |
+
PATH *path;
|
| 17 |
+
int ref_end_chan1, hyp_end_chan1, ref_end_chan2, hyp_end_chan2;
|
| 18 |
+
int ref_end, hyp_end, ref_begin, hyp_begin;
|
| 19 |
+
int ref_opp_end, hyp_opp_end, ref_opp_begin, hyp_opp_begin;
|
| 20 |
+
int dbg = TRUE;
|
| 21 |
+
int chunk;
|
| 22 |
+
char uttid[100];
|
| 23 |
+
int spkr;
|
| 24 |
+
int number_of_channels;
|
| 25 |
+
SCORES *scor;
|
| 26 |
+
NETWORK *hnet, *rnet;
|
| 27 |
+
int keep_path = 1;
|
| 28 |
+
|
| 29 |
+
hyp = WTOKE_STR1_init(hyp_file);
|
| 30 |
+
ref = WTOKE_STR1_init(ref_file);
|
| 31 |
+
|
| 32 |
+
scor = SCORES_init(set_title,20);
|
| 33 |
+
scor->ref_fname = (char *)TEXT_strdup((TEXT *)ref_file);
|
| 34 |
+
scor->hyp_fname = (char *)TEXT_strdup((TEXT *)hyp_file);
|
| 35 |
+
scor->creation_date = get_date();
|
| 36 |
+
scor->frag_corr = fcorr;
|
| 37 |
+
scor->opt_del = opt_del;
|
| 38 |
+
if (wwl != (WWL*)0) {
|
| 39 |
+
scor->weight_ali = 1;
|
| 40 |
+
scor->weight_file =
|
| 41 |
+
(char *)TEXT_strdup((TEXT*)rsprintf("%s Column \"%s\"",wwl->filename,
|
| 42 |
+
wwl->weight_desc[0]));
|
| 43 |
+
} else if (lm_file != (char *)0) {
|
| 44 |
+
scor->weight_ali = 1;
|
| 45 |
+
scor->weight_file = (char *)TEXT_strdup((TEXT*)lm_file);
|
| 46 |
+
} else
|
| 47 |
+
scor->weight_ali = 0;
|
| 48 |
+
|
| 49 |
+
dbg=0;
|
| 50 |
+
|
| 51 |
+
if ((fp_hyp = fopen(hyp_file,"r")) == NULL){
|
| 52 |
+
fprintf(stderr,"Can't open input hypothesis file %s\n",hyp_file);
|
| 53 |
+
exit(1);
|
| 54 |
+
}
|
| 55 |
+
if ((fp_ref = fopen(ref_file,"r")) == NULL){
|
| 56 |
+
fprintf(stderr,"Can't open input reference file %s\n",ref_file);
|
| 57 |
+
exit(1);
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
hyp_eof = ref_eof = FALSE;
|
| 61 |
+
do {
|
| 62 |
+
if (dbg > 5) printf("Starting do-while loop on conversations"
|
| 63 |
+
"--------------------------\n");
|
| 64 |
+
fill_WTOKE_structure(hyp, fp_hyp, hyp_file, &hyp_eof, case_sense);
|
| 65 |
+
fill_WTOKE_structure(ref, fp_ref, ref_file, &ref_eof, case_sense);
|
| 66 |
+
|
| 67 |
+
if ((hyp->n < hyp->s) && (ref->n > ref->s)) {
|
| 68 |
+
fprintf(stderr,"Error: premature EOF in hyp file '%s' at conv"
|
| 69 |
+
"ersation '%s' of ref file '%s'\n",hyp_file,
|
| 70 |
+
ref->word[ref->s].conv,ref_file);
|
| 71 |
+
exit(1);
|
| 72 |
+
}
|
| 73 |
+
if ((hyp->n > hyp->s) && (ref->n < ref->s)) {
|
| 74 |
+
fprintf(stderr,"Error: premature EOF in ref file '%s' at conv"
|
| 75 |
+
"ersation '%s' of hyp file '%s'\n",ref_file,
|
| 76 |
+
hyp->word[hyp->s].conv,hyp_file);
|
| 77 |
+
exit(1);
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
locate_boundary(ref, ref->s, TRUE, FALSE, &ref_conv_end);
|
| 81 |
+
locate_boundary(hyp, hyp->s, TRUE, FALSE, &hyp_conv_end);
|
| 82 |
+
|
| 83 |
+
/* let's do some checking !!!!!! */
|
| 84 |
+
/* Are the conversations in sync */
|
| 85 |
+
if (strcmp(ref->word[ref->s].conv,hyp->word[hyp->s].conv)!=0){
|
| 86 |
+
fprintf(stderr,"Error: in ref file '%s' and hyp file '%s'\n",
|
| 87 |
+
ref_file, hyp_file);
|
| 88 |
+
fprintf(stderr," file strings out of "
|
| 89 |
+
"synchronization around ref-file='%s' hyp-file='%s'\n",
|
| 90 |
+
ref->word[ref->s].conv,hyp->word[hyp->s].conv);
|
| 91 |
+
exit(1);
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
locate_boundary(ref, ref->s, TRUE, TRUE, &ref_end_chan1);
|
| 95 |
+
locate_boundary(hyp, hyp->s, TRUE, TRUE, &hyp_end_chan1);
|
| 96 |
+
|
| 97 |
+
number_of_channels = 1;
|
| 98 |
+
hyp_end_chan2 = ref_end_chan2 = -1;
|
| 99 |
+
if (ref_end_chan1+1 < ref->n &&
|
| 100 |
+
strcmp(ref->word[ref->s].conv,ref->word[ref_end_chan1+1].conv)==0){
|
| 101 |
+
locate_boundary(ref, ref_end_chan1+1, TRUE, TRUE, &ref_end_chan2);
|
| 102 |
+
number_of_channels = 2;
|
| 103 |
+
}
|
| 104 |
+
if (hyp_end_chan1+1 < hyp->n &&
|
| 105 |
+
strcmp(hyp->word[hyp->s].conv,hyp->word[hyp_end_chan1+1].conv)==0){
|
| 106 |
+
locate_boundary(hyp, hyp_end_chan1+1, TRUE, TRUE, &hyp_end_chan2);
|
| 107 |
+
number_of_channels = 2;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
if (number_of_channels == 2){
|
| 111 |
+
/* either the ref, hyp or both had two channels. make sure there */
|
| 112 |
+
/* are two channels in both */
|
| 113 |
+
if (hyp_end_chan2 == -1){
|
| 114 |
+
fprintf(stderr,"Error: in ref file '%s' and hyp file '%s'\n ",
|
| 115 |
+
ref_file, hyp_file);
|
| 116 |
+
fprintf(stderr," Hyp is missing second channel of file '%s'\n",
|
| 117 |
+
ref->word[ref->s].conv);
|
| 118 |
+
exit(1);
|
| 119 |
+
}
|
| 120 |
+
if (ref_end_chan2 == -1){
|
| 121 |
+
fprintf(stderr,"Error: in ref file '%s' and hyp file '%s'\n ",
|
| 122 |
+
ref_file, hyp_file);
|
| 123 |
+
fprintf(stderr," ref is missing second channel of file '%s'\n",
|
| 124 |
+
hyp->word[hyp->s].conv);
|
| 125 |
+
exit(1);
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
} else {
|
| 130 |
+
/* There was no second channel */
|
| 131 |
+
ref_end_chan2 = ref_end_chan1;
|
| 132 |
+
hyp_end_chan2 = hyp_end_chan1;
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
if (feedback >= 1)
|
| 136 |
+
printf(" Performing %s alignments for file '%s'.\n",
|
| 137 |
+
(time_align?"Time-mediated":"Word"),
|
| 138 |
+
ref->word[ref->s].conv);
|
| 139 |
+
|
| 140 |
+
if (dbg > 5){
|
| 141 |
+
printf("Located REF boundary: for %s %s -> %d,%d\n",
|
| 142 |
+
ref->word[ref->s].conv,
|
| 143 |
+
ref->word[ref->s].turn,ref->s,ref_conv_end);
|
| 144 |
+
printf("Located HYP boundary: for %s %s -> %d,%d\n",
|
| 145 |
+
hyp->word[hyp->s].conv,
|
| 146 |
+
hyp->word[hyp->s].turn,hyp->s,hyp_conv_end);
|
| 147 |
+
|
| 148 |
+
printf("Located REF Channel 1 boundary: for %d - %d\n",
|
| 149 |
+
ref->s,ref_end_chan1);
|
| 150 |
+
printf("Located HYP Channel 1 boundary: for %d - %d\n",
|
| 151 |
+
hyp->s,hyp_end_chan1);
|
| 152 |
+
printf("Located REF Channel 2 boundary: for %d - %d\n",
|
| 153 |
+
ref_end_chan1+1,ref_end_chan2);
|
| 154 |
+
printf("Located HYP Channel 2 boundary: for %d - %d\n",
|
| 155 |
+
hyp_end_chan1+1,hyp_end_chan2);
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
/* Start the alignment */
|
| 160 |
+
/* Side A */
|
| 161 |
+
for (i=0; i<number_of_channels; i++){
|
| 162 |
+
int base_len;
|
| 163 |
+
chunk = 0;
|
| 164 |
+
if (i==0){
|
| 165 |
+
ref_end = ref_end_chan1;
|
| 166 |
+
hyp_end = hyp_end_chan1;
|
| 167 |
+
ref_begin = ref->s;
|
| 168 |
+
hyp_begin = hyp->s;
|
| 169 |
+
|
| 170 |
+
ref_opp_end = ref_end_chan2;
|
| 171 |
+
hyp_opp_end = hyp_end_chan2;
|
| 172 |
+
ref_opp_begin = ref_end_chan1 + 1;
|
| 173 |
+
hyp_opp_begin = hyp_end_chan1 + 1;
|
| 174 |
+
} else {
|
| 175 |
+
ref_end = ref_end_chan2;
|
| 176 |
+
hyp_end = hyp_end_chan2;
|
| 177 |
+
ref_begin = ref_end_chan1 + 1;
|
| 178 |
+
hyp_begin = hyp_end_chan1 + 1;
|
| 179 |
+
|
| 180 |
+
ref_opp_end = ref_end_chan1;
|
| 181 |
+
hyp_opp_end = hyp_end_chan1;
|
| 182 |
+
ref_opp_begin = ref->s;
|
| 183 |
+
hyp_opp_begin = hyp->s;
|
| 184 |
+
}
|
| 185 |
+
if (dbg > 5){
|
| 186 |
+
printf("Starting channel %d\n",i);
|
| 187 |
+
printf("Ref Range: %d - %d\n",ref_begin,ref_end);
|
| 188 |
+
printf("Hyp Range: %d - %d\n",hyp_begin,hyp_end);
|
| 189 |
+
}
|
| 190 |
+
while (ref_begin<=ref_end || hyp_begin<=hyp_end){
|
| 191 |
+
int removals;
|
| 192 |
+
|
| 193 |
+
base_len = 50;
|
| 194 |
+
while (! chop_WTOKE_2(ref, hyp, ref_begin, hyp_begin,
|
| 195 |
+
ref_end, hyp_end, base_len,
|
| 196 |
+
&ref_chop_end,&hyp_chop_end)){
|
| 197 |
+
/* printf("Expanding len from %d to %d\n",base_len,
|
| 198 |
+
base_len*2); */
|
| 199 |
+
base_len *= 2;
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
removals = 0;
|
| 203 |
+
|
| 204 |
+
/* create the utterance ID */
|
| 205 |
+
sprintf(uttid,"(%s-%s-%04d)",ref->word[ref_begin].conv,
|
| 206 |
+
ref->word[ref_begin].turn,chunk);
|
| 207 |
+
|
| 208 |
+
spkr = SCORES_get_grp(scor,
|
| 209 |
+
rsprintf("%s-%s",
|
| 210 |
+
ref->word[ref_begin].conv,
|
| 211 |
+
ref->word[ref_begin].turn));
|
| 212 |
+
|
| 213 |
+
if (dbg > 5){
|
| 214 |
+
printf("Chunk %d: Starting for channel %d id=%s",
|
| 215 |
+
chunk,i,uttid);
|
| 216 |
+
printf(" Ref Range: %d - %d",ref_begin,ref_chop_end);
|
| 217 |
+
printf(" Hyp Range: %d - %d\n",hyp_begin,hyp_chop_end);
|
| 218 |
+
}
|
| 219 |
+
|
| 220 |
+
|
| 221 |
+
/* create the networks to be aligned */
|
| 222 |
+
if ((hnet=Network_create_from_WTOKE(hyp,hyp_begin,
|
| 223 |
+
hyp_chop_end,"Hypothesis net",
|
| 224 |
+
print_WORD_wt,
|
| 225 |
+
equal_WORD2,
|
| 226 |
+
release_WORD, null_alt_WORD,
|
| 227 |
+
opt_del_WORD,
|
| 228 |
+
copy_WORD,make_empty_WORD,
|
| 229 |
+
use_count_WORD,
|
| 230 |
+
left_to_right))
|
| 231 |
+
== NULL_NETWORK){
|
| 232 |
+
fprintf(stderr,"%s: Network_create_from_WTOKE failed\n",
|
| 233 |
+
proc);
|
| 234 |
+
return(0);
|
| 235 |
+
}
|
| 236 |
+
if ((rnet=Network_create_from_WTOKE(ref,ref_begin,
|
| 237 |
+
ref_chop_end,"Reference net",
|
| 238 |
+
print_WORD_wt,
|
| 239 |
+
equal_WORD2,
|
| 240 |
+
release_WORD, null_alt_WORD,
|
| 241 |
+
opt_del_WORD,
|
| 242 |
+
copy_WORD,make_empty_WORD,
|
| 243 |
+
use_count_WORD,
|
| 244 |
+
left_to_right))
|
| 245 |
+
== NULL_NETWORK){
|
| 246 |
+
fprintf(stderr,"%s: Network_create_from_WTOKE failed\n",
|
| 247 |
+
proc);
|
| 248 |
+
return(0);
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
path = network_dp_align_texts((TEXT *)0, rnet,
|
| 252 |
+
(TEXT *)0, hnet,
|
| 253 |
+
FALSE, case_sense,
|
| 254 |
+
(char *)uttid, fcorr,
|
| 255 |
+
opt_del, time_align, wwl, lm_file);
|
| 256 |
+
BF_SET(path->attrib,PA_HYP_WTIMES);
|
| 257 |
+
BF_SET(path->attrib,PA_REF_WTIMES);
|
| 258 |
+
if (ref->has_conf) BF_SET(path->attrib,PA_REF_CONF);
|
| 259 |
+
if (hyp->has_conf) BF_SET(path->attrib,PA_HYP_CONF);
|
| 260 |
+
|
| 261 |
+
sort_PATH_time_marks(path);
|
| 262 |
+
|
| 263 |
+
if (dbg > 10){
|
| 264 |
+
printf("After Sorting\n");
|
| 265 |
+
PATH_print_wt(path, stdout);
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
+
add_PATH_score(scor,path,spkr, keep_path);
|
| 269 |
+
PATH_add_file(path,ref->word[ref_begin].conv);
|
| 270 |
+
PATH_add_channel(path,ref->word[ref_begin].turn);
|
| 271 |
+
/* PATH_add_label(path,(char *)stm->seg[rs].labels); */
|
| 272 |
+
|
| 273 |
+
ref_begin = ref_chop_end+1;
|
| 274 |
+
hyp_begin = hyp_chop_end+1;
|
| 275 |
+
|
| 276 |
+
chunk++;
|
| 277 |
+
}
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
|
| 281 |
+
hyp->s = hyp_conv_end+1;
|
| 282 |
+
ref->s = ref_conv_end+1;
|
| 283 |
+
|
| 284 |
+
} while (hyp->s <= hyp->n || ref->s <= ref->n);
|
| 285 |
+
|
| 286 |
+
free_mark_file(ref);
|
| 287 |
+
free_mark_file(hyp);
|
| 288 |
+
|
| 289 |
+
fclose(fp_hyp);
|
| 290 |
+
fclose(fp_ref);
|
| 291 |
+
|
| 292 |
+
return (scor);
|
| 293 |
+
}
|
| 294 |
+
|
| 295 |
+
/*******************************************************************/
|
| 296 |
+
/* Compute the overlap of two segments in time and return that */
|
| 297 |
+
/* time. Negative times indicate no overlap. There are 6 cases */
|
| 298 |
+
/* Case 1: S1 t1 t2 */
|
| 299 |
+
/* S2 t1 t2 */
|
| 300 |
+
/* */
|
| 301 |
+
/* Case 2: S1 t1 t2 */
|
| 302 |
+
/* S2 t1 t2 */
|
| 303 |
+
/* */
|
| 304 |
+
/* Case 3a: S1 t1 t2 */
|
| 305 |
+
/* S2 t1 t2 */
|
| 306 |
+
/* */
|
| 307 |
+
/* Case 3b: S1 t1 t2 */
|
| 308 |
+
/* S2 t1 t2 */
|
| 309 |
+
/* */
|
| 310 |
+
/* Case 4a: S1 t1 t2 */
|
| 311 |
+
/* S2 t1 t2 */
|
| 312 |
+
/* */
|
| 313 |
+
/* Case 4b: S1 t1 t2 */
|
| 314 |
+
/* S2 t1 t2 */
|
| 315 |
+
/* */
|
| 316 |
+
double overlap(double s1_t1, double s1_t2, double s2_t1, double s2_t2)
|
| 317 |
+
{
|
| 318 |
+
double rval;
|
| 319 |
+
char *rule;
|
| 320 |
+
int dbg=0;
|
| 321 |
+
/* Case 1: */
|
| 322 |
+
if (s1_t2 < s2_t1)
|
| 323 |
+
rule="Case 1", rval=(s1_t2 - s2_t1);
|
| 324 |
+
/* Case 2: */
|
| 325 |
+
if (s1_t1 > s2_t2)
|
| 326 |
+
rule="Case 2", rval=(s2_t2 - s1_t1);
|
| 327 |
+
/* Case 3: */
|
| 328 |
+
if (s1_t1 < s2_t1){
|
| 329 |
+
/* Case 3a: */
|
| 330 |
+
if (s1_t2 < s2_t2)
|
| 331 |
+
rule="Case 3a", rval=(s1_t2 - s2_t1);
|
| 332 |
+
else /* Case 3b: */
|
| 333 |
+
rule="Case 3b", rval=(s2_t2 - s2_t1);
|
| 334 |
+
} else { /* Case 4: */
|
| 335 |
+
/* Case 4a: */
|
| 336 |
+
if (s1_t2 < s2_t2)
|
| 337 |
+
rule="Case 4a", rval=(s1_t2 - s1_t1);
|
| 338 |
+
else /* Case 4b: */
|
| 339 |
+
rule="Case 4b", rval=(s2_t2 - s1_t1);
|
| 340 |
+
}
|
| 341 |
+
if (dbg){
|
| 342 |
+
printf("Overlap: s1_t1=%2.2f s1_t2=%2.2f",s1_t1,s1_t2);
|
| 343 |
+
printf(" s2_t1=%2.2f s2_t2=%2.2f Rule:%s Rval=%2.2f\n",
|
| 344 |
+
s2_t1,s2_t2,rule,rval);
|
| 345 |
+
}
|
| 346 |
+
return(rval);
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
|
| 350 |
+
int chop_WTOKE_2(WTOKE_STR1 *ref, WTOKE_STR1 *hyp, int Rstart, int Hstart, int Rendconv, int Hendconv, int max_words, int *Rret_end, int *Hret_end)
|
| 351 |
+
{
|
| 352 |
+
int Rend, Hend, Rend_sync, Hend_sync;
|
| 353 |
+
char *proc="chop_WTOKE_2";
|
| 354 |
+
int dbg=0, skipped_alt;
|
| 355 |
+
double Rgap_t1, Rgap_t2, Hgap_t1, Hgap_t2;
|
| 356 |
+
|
| 357 |
+
if (dbg)
|
| 358 |
+
printf("%s: Start Ref=%d Start Hyp=%d Max_words=%d\n",
|
| 359 |
+
proc,Rstart,Hstart,max_words);
|
| 360 |
+
|
| 361 |
+
/* Find the end of this segment */
|
| 362 |
+
/* locate_boundary(ref, Rstart, TRUE, TRUE, &Rendconv);
|
| 363 |
+
locate_boundary(hyp, Hstart, TRUE, TRUE, &Hendconv); */
|
| 364 |
+
|
| 365 |
+
if (dbg) printf("%s: Conversation Rendconv=%d Hendconv=%d\n",
|
| 366 |
+
proc,Rendconv,Hendconv);
|
| 367 |
+
|
| 368 |
+
if ((Rstart > Rendconv) && (Hstart > Hendconv))
|
| 369 |
+
return(0);
|
| 370 |
+
|
| 371 |
+
/* if we've hit the end of the conversation, send everything */
|
| 372 |
+
if (((Rendconv - Rstart) <max_words) && ((Hendconv - Hstart) < max_words)){
|
| 373 |
+
*Rret_end = Rendconv;
|
| 374 |
+
*Hret_end = Hendconv;
|
| 375 |
+
if (dbg) printf("%s: R1 Success Chop Ref (%d-%d) Hyp (%d-%d)\n",
|
| 376 |
+
proc,Rstart,*Rret_end,Hstart,*Hret_end);
|
| 377 |
+
return(1);
|
| 378 |
+
}
|
| 379 |
+
|
| 380 |
+
/* set the indexes to maximum length */
|
| 381 |
+
Rend = MIN(Rstart + max_words, Rendconv);
|
| 382 |
+
Hend = MIN(Hstart + max_words, Hendconv);
|
| 383 |
+
|
| 384 |
+
if (dbg) printf("%s: Limited Rend=%d Hend=%d\n",proc,Rend,Hend);
|
| 385 |
+
|
| 386 |
+
/* synchronize the ends to permit searching */
|
| 387 |
+
while (Rend >= Rstart && ref->word[Rend].alternate)
|
| 388 |
+
Rend--;
|
| 389 |
+
skipped_alt = TRUE;
|
| 390 |
+
while (skipped_alt){
|
| 391 |
+
skipped_alt = FALSE;
|
| 392 |
+
if (ref->word[Rend].t1 > hyp->word[Hend].t1)
|
| 393 |
+
while (!skipped_alt &&
|
| 394 |
+
Rend >= Rstart &&
|
| 395 |
+
ref->word[Rend].t1 > hyp->word[Hend].t1 &&
|
| 396 |
+
overlap(ref->word[Rend].t1,
|
| 397 |
+
ref->word[Rend].t1+ref->word[Rend].dur,
|
| 398 |
+
hyp->word[Hend].t1,
|
| 399 |
+
hyp->word[Hend].t1+hyp->word[Hend].dur) < 0.0)
|
| 400 |
+
for (Rend--; Rend >= Rstart && ref->word[Rend].alternate; ) {
|
| 401 |
+
Rend--;
|
| 402 |
+
skipped_alt = TRUE;
|
| 403 |
+
}
|
| 404 |
+
else if (ref->word[Rend].t1 < hyp->word[Hend].t1)
|
| 405 |
+
while (Hend >= Hstart &&
|
| 406 |
+
ref->word[Rend].t1 < hyp->word[Hend].t1 &&
|
| 407 |
+
overlap(ref->word[Rend].t1,
|
| 408 |
+
ref->word[Rend].t1+ref->word[Rend].dur,
|
| 409 |
+
hyp->word[Hend].t1,
|
| 410 |
+
hyp->word[Hend].t1+hyp->word[Hend].dur) < 0.0)
|
| 411 |
+
Hend --;
|
| 412 |
+
}
|
| 413 |
+
if (dbg) {
|
| 414 |
+
printf("%s: Synchronized Rend=%d Hend=%d ",proc,Rend,Hend);
|
| 415 |
+
printf("Times: %2.2f,%2.2f %2.2f,%2.2f\n",
|
| 416 |
+
ref->word[Rend].t1, ref->word[Rend].t1+ref->word[Rend].dur,
|
| 417 |
+
hyp->word[Hend].t1, hyp->word[Hend].t1+hyp->word[Hend].dur);
|
| 418 |
+
}
|
| 419 |
+
Rend_sync = Rend;
|
| 420 |
+
Hend_sync = Hend;
|
| 421 |
+
|
| 422 |
+
/* begin the backward search */
|
| 423 |
+
while (Rend > Rstart && Hend > Hstart){
|
| 424 |
+
/* first compute t1 and t2 for the gap in each segment */
|
| 425 |
+
if (Rend >= Rstart){
|
| 426 |
+
Rgap_t1 = ref->word[Rend].t1 + ref->word[Rend].dur;
|
| 427 |
+
Rgap_t2 = (Rend == Rendconv) ? 999999.99 : ref->word[Rend+1].t1;
|
| 428 |
+
} else {
|
| 429 |
+
Rgap_t1 = 0.0;
|
| 430 |
+
Rgap_t2 = ref->word[Rstart].t1;
|
| 431 |
+
}
|
| 432 |
+
if (Hend >= Hstart) {
|
| 433 |
+
Hgap_t1 = hyp->word[Hend].t1 + hyp->word[Hend].dur;
|
| 434 |
+
Hgap_t2 = (Hend == Hendconv) ? 999999.99 : hyp->word[Hend+1].t1;
|
| 435 |
+
} else {
|
| 436 |
+
Hgap_t1 = 0.0;
|
| 437 |
+
Hgap_t2 = hyp->word[Hstart].t1;
|
| 438 |
+
}
|
| 439 |
+
|
| 440 |
+
if (dbg) {
|
| 441 |
+
printf("\n%s: Gaps: ref %2.2f,%2.2f hyp %2.2f,%2.2f\n",
|
| 442 |
+
proc,Rgap_t1, Rgap_t2, Hgap_t1, Hgap_t2);
|
| 443 |
+
printf("%s: **** middle word is Rend or Hend\n",proc);
|
| 444 |
+
dump_word_tokens2(ref,Rend-1,Rend+1);
|
| 445 |
+
dump_word_tokens2(hyp,Hend-1,Hend+1);
|
| 446 |
+
}
|
| 447 |
+
|
| 448 |
+
/* check to see if there is any overlap */
|
| 449 |
+
/* yes if : S1 | | # | | */
|
| 450 |
+
/* S2 | | # | | */
|
| 451 |
+
|
| 452 |
+
if (overlap(Rgap_t1,Rgap_t2,Hgap_t1,Hgap_t2) < 0.0){
|
| 453 |
+
/* no overlap decide which to move */
|
| 454 |
+
|
| 455 |
+
if (dbg) printf("%s: Shifting down\n",proc);
|
| 456 |
+
|
| 457 |
+
skipped_alt = TRUE;
|
| 458 |
+
while (skipped_alt){
|
| 459 |
+
skipped_alt = FALSE;
|
| 460 |
+
if (ref->word[Rend].t1 > hyp->word[Hend].t1){
|
| 461 |
+
if (Rend > Rstart) {
|
| 462 |
+
Rend --;
|
| 463 |
+
while (Rend >= Rstart && ref->word[Rend].alternate) {
|
| 464 |
+
Rend--;
|
| 465 |
+
skipped_alt = TRUE;
|
| 466 |
+
}
|
| 467 |
+
}
|
| 468 |
+
if (dbg) printf("%s: Moving Ref\n",proc);
|
| 469 |
+
while (!skipped_alt &&
|
| 470 |
+
Hend >= Hstart &&
|
| 471 |
+
ref->word[Rend].t1 < hyp->word[Hend].t1 &&
|
| 472 |
+
overlap(ref->word[Rend].t1,
|
| 473 |
+
ref->word[Rend].t1+ref->word[Rend].dur,
|
| 474 |
+
hyp->word[Hend].t1,
|
| 475 |
+
hyp->word[Hend].t1+hyp->word[Hend].dur)< 0.0){
|
| 476 |
+
Hend --;
|
| 477 |
+
if (dbg) printf("%s: Adjusting Hyp\n",proc);
|
| 478 |
+
}
|
| 479 |
+
} else if (ref->word[Rend].t1 <= hyp->word[Hend].t1) {
|
| 480 |
+
if (Hend > Hstart)
|
| 481 |
+
Hend --;
|
| 482 |
+
if (dbg) printf("%s: Moving Hyp\n",proc);
|
| 483 |
+
while (!skipped_alt &&
|
| 484 |
+
Rend >= Rstart &&
|
| 485 |
+
ref->word[Rend].t1 > hyp->word[Hend].t1 &&
|
| 486 |
+
overlap(ref->word[Rend].t1,
|
| 487 |
+
ref->word[Rend].t1+ref->word[Rend].dur,
|
| 488 |
+
hyp->word[Hend].t1,
|
| 489 |
+
hyp->word[Hend].t1+hyp->word[Hend].dur)<0.0){
|
| 490 |
+
for (Rend--;
|
| 491 |
+
Rend >= Rstart && ref->word[Rend].alternate; ) {
|
| 492 |
+
Rend--;
|
| 493 |
+
skipped_alt = TRUE;
|
| 494 |
+
}
|
| 495 |
+
if (dbg) printf("%s: Adjusting Ref\n",proc);
|
| 496 |
+
}
|
| 497 |
+
}
|
| 498 |
+
}
|
| 499 |
+
} else { /* Overlap exists !!!!! Return the values */
|
| 500 |
+
*Rret_end = Rend;
|
| 501 |
+
*Hret_end = Hend;
|
| 502 |
+
if (dbg) printf("%s: R2 Success Chop Ref (%d-%d) Hyp (%d-%d)\n",
|
| 503 |
+
proc,Rstart,*Rret_end,Hstart,*Hret_end);
|
| 504 |
+
return(1);
|
| 505 |
+
}
|
| 506 |
+
}
|
| 507 |
+
|
| 508 |
+
if (Rend > Rstart || Hend > Hstart){
|
| 509 |
+
*Rret_end = Rend;
|
| 510 |
+
*Hret_end = Hend;
|
| 511 |
+
if (dbg) printf("%s: R3 Success Chop Ref (%d-%d) Hyp (%d-%d)\n",
|
| 512 |
+
proc,Rstart,*Rret_end,Hstart,*Hret_end);
|
| 513 |
+
return(1);
|
| 514 |
+
}
|
| 515 |
+
/* fprintf(stdout,"%s: Failure to find chop'd segment, returning 0\n",proc); */
|
| 516 |
+
return(0);
|
| 517 |
+
|
| 518 |
+
}
|
SCTK/src/sclite/killarc1.o
ADDED
|
Binary file (2.11 kB). View file
|
|
|
SCTK/src/sclite/llist.c
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/** Mark Przybocki
|
| 2 |
+
** Filename: LLIST.C
|
| 3 |
+
** Module 1 used to build liblist.a (library).
|
| 4 |
+
**
|
| 5 |
+
**/
|
| 6 |
+
|
| 7 |
+
#include "sctk.h"
|
| 8 |
+
|
| 9 |
+
static LList *getLList(void *);
|
| 10 |
+
static void freeLList(LList **);
|
| 11 |
+
void recur(LList **t, LList *f);
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
/*
|
| 15 |
+
* Function GETLNODE returns a pointer to a lnode which will
|
| 16 |
+
* contain the data element taken as input.
|
| 17 |
+
*/
|
| 18 |
+
static LList *getLList (void *pdata)
|
| 19 |
+
{
|
| 20 |
+
LList *ptemp; /* temporary lnode being set with data element */
|
| 21 |
+
|
| 22 |
+
/* ALLOCATE MEMORY for our TEMP LNODE */
|
| 23 |
+
ptemp = malloc(sizeof(LList));
|
| 24 |
+
|
| 25 |
+
if (ptemp != NULL) {
|
| 26 |
+
/* we have successfully allocated memory so set the LList */
|
| 27 |
+
ptemp -> data = pdata; /** DATA ELEMENT **/
|
| 28 |
+
ptemp -> next = NULL; /** NEXT LLIST NOT ASSIGNED YET **/
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
return ptemp; /** RETURNS either a Null LList or a set LList **/
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
/*
|
| 37 |
+
* Function FREELLIST deallocates space occupied by a LList and
|
| 38 |
+
* clears the LList from the list.
|
| 39 |
+
*/
|
| 40 |
+
static void freeLList (LList **p)
|
| 41 |
+
{
|
| 42 |
+
free(*p); /** DEALLOCATE SPACE **/
|
| 43 |
+
*p=NULL; /** Clear value of *p **/
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
/*
|
| 49 |
+
* Function INIT_LIST sets the starting point of a list NULL,
|
| 50 |
+
* which infact gives existence to a list.
|
| 51 |
+
*/
|
| 52 |
+
void LL_init (LList **s)
|
| 53 |
+
{
|
| 54 |
+
*s=NULL; /** creates a NULL list **/
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
void recur(LList **t, LList *f){
|
| 58 |
+
if (! LL_empty(f)){
|
| 59 |
+
recur(t,f->next);
|
| 60 |
+
LL_put_front(t,f->data);
|
| 61 |
+
}
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
void LL_copy (LList **t, LList **f)
|
| 65 |
+
{
|
| 66 |
+
LL_init(t);
|
| 67 |
+
recur(t,*f);
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
/*
|
| 73 |
+
* Function EMPTY test whether or not LLIST is empty.
|
| 74 |
+
*/
|
| 75 |
+
int LL_empty (LList *s)
|
| 76 |
+
{
|
| 77 |
+
return ( s==NULL ); /** Test for existing list **/
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
/*
|
| 83 |
+
* Function PUSH places one LList at the head (top) of the list.
|
| 84 |
+
*/
|
| 85 |
+
int LL_put_front (LList **s, void *pdata)
|
| 86 |
+
{
|
| 87 |
+
LList *ptemp; /** Temporary LList holder **/
|
| 88 |
+
|
| 89 |
+
/* Get space and set a LList */
|
| 90 |
+
ptemp = getLList(pdata);
|
| 91 |
+
|
| 92 |
+
/* Check for error */
|
| 93 |
+
if (ptemp == NULL)
|
| 94 |
+
return 0; /** FAILURE: Couldn't allocate space **/
|
| 95 |
+
|
| 96 |
+
/* Add to list */
|
| 97 |
+
ptemp -> next = *s;
|
| 98 |
+
|
| 99 |
+
/** Set the begining of the list **/
|
| 100 |
+
*s = ptemp;
|
| 101 |
+
|
| 102 |
+
return 1; /** SUCCESS **/
|
| 103 |
+
}
|
| 104 |
+
|
| 105 |
+
/*
|
| 106 |
+
* Function LL_put_tail places one LList at the tail (bottom) of the list.
|
| 107 |
+
*/
|
| 108 |
+
int LL_put_tail (LList **s, void *pdata)
|
| 109 |
+
{
|
| 110 |
+
LList *ptemp, *pt1 = *s; /** Temporary LList holder **/
|
| 111 |
+
|
| 112 |
+
if (*s == (LList *)0)
|
| 113 |
+
return LL_put_front(s,pdata);
|
| 114 |
+
|
| 115 |
+
/* Get space and set a LList */
|
| 116 |
+
ptemp = getLList(pdata);
|
| 117 |
+
|
| 118 |
+
/* Check for error */
|
| 119 |
+
if (ptemp == NULL)
|
| 120 |
+
return 0; /** FAILURE: Couldn't allocate space **/
|
| 121 |
+
|
| 122 |
+
/* traverse to the end of the list */
|
| 123 |
+
while (pt1->next != NULL)
|
| 124 |
+
pt1 = pt1->next;
|
| 125 |
+
|
| 126 |
+
/* Add to list */
|
| 127 |
+
pt1 -> next = ptemp;
|
| 128 |
+
ptemp->next = (LList *)NULL;
|
| 129 |
+
|
| 130 |
+
return 1; /** SUCCESS **/
|
| 131 |
+
}
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
/*
|
| 136 |
+
* Function LL_get_first removes a LList for the head (top) of list.
|
| 137 |
+
*/
|
| 138 |
+
int LL_get_first (LList **s, void **apdata)
|
| 139 |
+
{
|
| 140 |
+
LList *ptemp; /* Temporary LList holder */
|
| 141 |
+
|
| 142 |
+
if (LL_empty(*s) == 1)
|
| 143 |
+
return 0; /** list already empty nothing to pop **/
|
| 144 |
+
|
| 145 |
+
/* Set ptemp to the first LList */
|
| 146 |
+
ptemp = *s;
|
| 147 |
+
|
| 148 |
+
/* Reset to point to the following LList*/
|
| 149 |
+
*s = ptemp -> next;
|
| 150 |
+
|
| 151 |
+
/* Grab the data element */
|
| 152 |
+
*apdata = ptemp -> data;
|
| 153 |
+
|
| 154 |
+
/* Free the space of the popped LList */
|
| 155 |
+
freeLList (&ptemp);
|
| 156 |
+
|
| 157 |
+
return 1; /** Success **/
|
| 158 |
+
}
|
| 159 |
+
|
SCTK/src/sclite/llist.h
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
** Mark Przybocki
|
| 3 |
+
** 598 Unix/c
|
| 4 |
+
**
|
| 5 |
+
** Project #7: PART I (creating a library)
|
| 6 |
+
**
|
| 7 |
+
** Filename: LLIST.H
|
| 8 |
+
** header file for the liblist.a library
|
| 9 |
+
** and other linked list functions.
|
| 10 |
+
**
|
| 11 |
+
**/
|
| 12 |
+
|
| 13 |
+
/** DEFINE THE BASIC NODE STRUCTURE **/
|
| 14 |
+
|
| 15 |
+
typedef struct lnode LList;
|
| 16 |
+
struct lnode
|
| 17 |
+
{
|
| 18 |
+
void *data; /* data element */
|
| 19 |
+
void *next; /* pointer to next element */
|
| 20 |
+
};
|
| 21 |
+
|
| 22 |
+
/** FUNCTION PROTO-TYPING **/
|
| 23 |
+
|
| 24 |
+
/* file: llist.c */
|
| 25 |
+
|
| 26 |
+
int LL_put_tail(LList **, void *);
|
| 27 |
+
int LL_put_front(LList **, void *);
|
| 28 |
+
int LL_get_first(LList **, void **);
|
| 29 |
+
void LL_init(LList **);
|
| 30 |
+
void LL_copy(LList **, LList **);
|
| 31 |
+
int LL_empty(LList *);
|
| 32 |
+
|
SCTK/src/sclite/makefile.in
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# makefile for SCLITE
|
| 2 |
+
|
| 3 |
+
#### Start of system configuration section. ####
|
| 4 |
+
|
| 5 |
+
srcdir = @srcdir@
|
| 6 |
+
VPATH = @srcdir@
|
| 7 |
+
|
| 8 |
+
CC = @CC@
|
| 9 |
+
INSTALL = @INSTALL@
|
| 10 |
+
|
| 11 |
+
GNUDIFF = @DIFF@
|
| 12 |
+
CPPFLAGS = @CPPFLAGS@
|
| 13 |
+
DEFS = @DEFS@
|
| 14 |
+
CFLAGS = @CFLAGS@
|
| 15 |
+
LDFLAGS = @LDFLAGS@
|
| 16 |
+
SLM_TARGETS = @SLM_TARGETS@
|
| 17 |
+
LIBS = @LIBS@ $(SLM_TARGETS)
|
| 18 |
+
|
| 19 |
+
# Some System V machines do not come with libPW.
|
| 20 |
+
# If this is true for you, use the GNU alloca.o here.
|
| 21 |
+
|
| 22 |
+
prefix = @prefix@
|
| 23 |
+
exec_prefix = @exec_prefix@
|
| 24 |
+
edit_program_name = sed '@program_transform_name@'
|
| 25 |
+
|
| 26 |
+
bindir = $(exec_prefix)/bin
|
| 27 |
+
mandir =$(prefix)/man
|
| 28 |
+
man1dir =$(mandir)/man1
|
| 29 |
+
man5dir = $(mandir)/man5
|
| 30 |
+
|
| 31 |
+
infodir = $(prefix)/info
|
| 32 |
+
|
| 33 |
+
DEFAULT_EDITOR_PROGRAM = ed
|
| 34 |
+
NULL_DEVICE = /dev/null
|
| 35 |
+
PR_PROGRAM = /bin/pr
|
| 36 |
+
|
| 37 |
+
#### End of system configuration section. ####
|
| 38 |
+
|
| 39 |
+
SHELL = /bin/sh
|
| 40 |
+
|
| 41 |
+
######################################################################
|
| 42 |
+
# The source files for all of the programs.
|
| 43 |
+
glib_c = order.c rsprintf.c path.c text.c scores.c word.c rpg.c statdist.c \
|
| 44 |
+
pad.c sgml.c readpipe.c alex.c sc_dtl.c det.c wwscr_f.c corresp.c \
|
| 45 |
+
slm_intf.c
|
| 46 |
+
|
| 47 |
+
statlib_c = rank.c range.c anovar.c signtest.c wilcoxon.c sentmcn.c mtchprs.c
|
| 48 |
+
|
| 49 |
+
netlib_c = addarc1.c delarc1.c llist.c marc1.c arcseq1.c \
|
| 50 |
+
mnode1.c boolpr1.c killarc1.c net_adt.c knode2.c net_dp.c
|
| 51 |
+
|
| 52 |
+
align_c = stm.c align.c dwtoke2.c fillmrks.c wtokeini.c lur.c stm2ctm.c \
|
| 53 |
+
ctm2ctm.c mfa.c cores.c
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
######################################################################
|
| 57 |
+
# The Object files for all of the library code.
|
| 58 |
+
glib_o = order.o rsprintf.o path.o text.o scores.o word.o rpg.o statdist.o \
|
| 59 |
+
pad.o sgml.o readpipe.o alex.o sc_dtl.o det.o wwscr_f.o corresp.o \
|
| 60 |
+
slm_intf.o
|
| 61 |
+
|
| 62 |
+
statlib_o = rank.o range.o anovar.o signtest.o wilcoxon.o sentmcn.o mtchprs.o
|
| 63 |
+
|
| 64 |
+
netlib_o = addarc1.o delarc1.o llist.o marc1.o arcseq1.o \
|
| 65 |
+
mnode1.o boolpr1.o killarc1.o net_adt.o knode2.o net_dp.o
|
| 66 |
+
|
| 67 |
+
align_o = stm.o align.o dwtoke2.o fillmrks.o wtokeini.o lur.o stm2ctm.o \
|
| 68 |
+
ctm2ctm.o mfa.o cores.o
|
| 69 |
+
|
| 70 |
+
######################################################################
|
| 71 |
+
# Group the libraries into their seperate forms either standalone or
|
| 72 |
+
# in the tool kit
|
| 73 |
+
|
| 74 |
+
sclib_c = $(glib_c) $(netlib_c) $(align_c)
|
| 75 |
+
tklib_c = $(sclib_c) $(statlib_c)
|
| 76 |
+
|
| 77 |
+
sclib_o = $(glib_o) $(netlib_o) $(align_o)
|
| 78 |
+
tklib_o = $(sclib_o) $(statlib_o)
|
| 79 |
+
|
| 80 |
+
SC_PROGRAMS = sclite
|
| 81 |
+
TK_PROGRAMS = $(SC_PROGRAMS) sc_stats rover sctkUnit
|
| 82 |
+
|
| 83 |
+
TEST_PROGRAMS = test test2 sc_conf mtchpath rover_v2 sc_quick mprint
|
| 84 |
+
|
| 85 |
+
PURIFY_PROGRAMS = $(PROGRAMS:%=%_pure) $(TEST_PROGRAMS:%=%_pure)
|
| 86 |
+
|
| 87 |
+
PURECOV_PROGRAMS = $(PROGRAMS:%=%_purecov)
|
| 88 |
+
|
| 89 |
+
DOCS = ../install.txt ../readme.txt ../disclaim.txt ../revision.txt \
|
| 90 |
+
../makefile ../doc
|
| 91 |
+
CONFIG = makefile.in config.sh config.in config.txt
|
| 92 |
+
|
| 93 |
+
tk_distfiles = $(tklib_c) $(TK_PROGRAMS:%=%.c) *.h $(CONFIG) testdata
|
| 94 |
+
|
| 95 |
+
######################################################################
|
| 96 |
+
############### Defines the installation type #####################
|
| 97 |
+
lib_o = $(tklib_o)
|
| 98 |
+
lib_c = $(tklib_c)
|
| 99 |
+
PROGRAMS = $(TK_PROGRAMS)
|
| 100 |
+
distribution = tk_dist
|
| 101 |
+
|
| 102 |
+
#lib_o = $(sclib_o)
|
| 103 |
+
#lib_c = $(sclib_c)
|
| 104 |
+
#PROGRAMS = $(SC_PROGRAMS)
|
| 105 |
+
#distribution = sc_dist
|
| 106 |
+
|
| 107 |
+
######################################################################
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
all: makefile $(SLM_TARGETS) $(PROGRAMS)
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
.c.o:
|
| 114 |
+
$(CC) -c $(OFLAGS) $(DEFS) -I. $(CFLAGS) $(CPPFLAGS) -o $@ $<
|
| 115 |
+
|
| 116 |
+
sclite: $(lib_o) sclite.o
|
| 117 |
+
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS)
|
| 118 |
+
sc_stats: $(lib_o) sc_stats.o
|
| 119 |
+
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS)
|
| 120 |
+
rover: $(lib_o) rover.o
|
| 121 |
+
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS)
|
| 122 |
+
mcnemar: $(lib_o) mcnemar.o
|
| 123 |
+
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS)
|
| 124 |
+
sctkUnit: $(lib_o) sctkUnit.o
|
| 125 |
+
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS)
|
| 126 |
+
sign: $(lib_o) sign.o
|
| 127 |
+
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS)
|
| 128 |
+
sclite_tolower: $(lib_o) sclite_tolower.o
|
| 129 |
+
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS)
|
| 130 |
+
$(TEST_PROGRAMS): $(lib_o) $$@.o
|
| 131 |
+
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS)
|
| 132 |
+
$(PURIFY_PROGRAMS): $(lib_o)
|
| 133 |
+
purify $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ `echo $@.c|sed 's/_pure//'` $(LIBS)
|
| 134 |
+
$(PURECOV_PROGRAMS): $(lib_o)
|
| 135 |
+
purecov $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ `echo $@.c|sed 's/_purecov//'` $(LIBS)
|
| 136 |
+
|
| 137 |
+
### make a rule to compile the SLM toolkit
|
| 138 |
+
slm_v2/lib/SLM2.a:
|
| 139 |
+
(cd slm_v2/src && make SLM2.a install-lib)
|
| 140 |
+
|
| 141 |
+
#arpg: rpg.o arpg.o pad.o
|
| 142 |
+
# $(CC) -o $@ $(CFLAGS) $(LDFLAGS) rpg.o arpg.o pad.o $(LIBS)
|
| 143 |
+
clean:
|
| 144 |
+
rm -f *.o $(PROGRAMS) core
|
| 145 |
+
if test -f slm_v2/src/makefile ; then \
|
| 146 |
+
(cd slm_v2/src && make spotless) \
|
| 147 |
+
fi
|
| 148 |
+
|
| 149 |
+
mostlyclean: clean
|
| 150 |
+
|
| 151 |
+
distclean: clean
|
| 152 |
+
rm -rf *~ config.status config.log config.cache config.h makefile
|
| 153 |
+
|
| 154 |
+
realclean: distclean
|
| 155 |
+
rm -f TAGS *.info*
|
| 156 |
+
|
| 157 |
+
install: all testinstalldirs
|
| 158 |
+
set -e; for p in $(PROGRAMS); do \
|
| 159 |
+
$(INSTALL) $$p $(DESTDIR)$(bindir)/$$p; \
|
| 160 |
+
done
|
| 161 |
+
#REenable this later
|
| 162 |
+
# set -e; for p in `(cd ../doc ; ls *.1)`; do \
|
| 163 |
+
# $(INSTALL) ../doc/$$p $(DESTDIR)$(man1dir)/$$p; \
|
| 164 |
+
# done
|
| 165 |
+
# @echo "!!!! If 'man sclite' does not work, run 'catman -M $(mandir)'"
|
| 166 |
+
# @echo "!!!! to make manual pages accessible."
|
| 167 |
+
|
| 168 |
+
testinstalldirs:
|
| 169 |
+
@-set -e; for p in $(DESTDIR)$(bindir) $(DESTDIR)$(man1dir) $(DESTDIR)$(man5dir); do \
|
| 170 |
+
if test ! -d $$p ; then \
|
| 171 |
+
echo "Error: directory $$p doesn't exist"; \
|
| 172 |
+
fi ; \
|
| 173 |
+
done
|
| 174 |
+
#REenable this later
|
| 175 |
+
# if test ! -w $$p ; then \
|
| 176 |
+
# echo "Error: directory $$p is not writeable by you"; \
|
| 177 |
+
# fi \
|
| 178 |
+
|
| 179 |
+
# We need more tests.
|
| 180 |
+
check: sctkUnit
|
| 181 |
+
./sctkUnit
|
| 182 |
+
cd testdata && ./tsclite.sh
|
| 183 |
+
cd testdata && ./tsc_stats.sh
|
| 184 |
+
|
| 185 |
+
uninstall:
|
| 186 |
+
set -e; for p in $(PROGRAMS); do \
|
| 187 |
+
rm -f $(bindir)/`echo $$p | $(edit_program_name)`; \
|
| 188 |
+
done
|
| 189 |
+
set -e; for p in `(cd ../doc ; ls *.1)`; do \
|
| 190 |
+
rm -f $(man1dir)/$$p; \
|
| 191 |
+
done
|
| 192 |
+
|
| 193 |
+
config.sh: config.in
|
| 194 |
+
cd $(srcdir) && /usr/local/bin/autoconf config.in | sed 's/Makefile/makefile/g' > config.sh
|
| 195 |
+
|
| 196 |
+
# autoheader might not change config.hin.
|
| 197 |
+
config.hin: stamp-h.in
|
| 198 |
+
stamp-h.in: config.in
|
| 199 |
+
cd $(srcdir) && autoheader
|
| 200 |
+
date > $(srcdir)/stamp-h.in
|
| 201 |
+
|
| 202 |
+
config.status: config.sh
|
| 203 |
+
./config.status --recheck
|
| 204 |
+
|
| 205 |
+
# config.status might not change config.h, but it changes stamp-h.
|
| 206 |
+
makefile: makefile.in config.status
|
| 207 |
+
./config.status
|
| 208 |
+
|
| 209 |
+
dist: $(distribution)
|
| 210 |
+
|
| 211 |
+
tk_dist: $(tk_distfiles)
|
| 212 |
+
echo sctk-`grep define\ TK_VERSION sctk.h | sed -e 's/^[^"]*"//' -e 's/"[^"]*//'` > .fname
|
| 213 |
+
echo "Distribution file '../`cat .fname`.tar.Z'"
|
| 214 |
+
(cd ../doc && ./export.sh $(PROGRAMS))
|
| 215 |
+
rm -rf ../`cat .fname`
|
| 216 |
+
mkdir ../`cat .fname`
|
| 217 |
+
(cd ./testdata && tsclite.sh -clean) ;
|
| 218 |
+
set -e; for file in $(DOCS); do \
|
| 219 |
+
ln -s $$file ../`cat .fname`; \
|
| 220 |
+
done
|
| 221 |
+
mkdir ../`cat .fname`/src
|
| 222 |
+
set -e; for file in $(tk_distfiles); do \
|
| 223 |
+
ln -s ../../src/$$file ../`cat .fname`/src/$$file; \
|
| 224 |
+
done
|
| 225 |
+
echo "Installing SLM links"
|
| 226 |
+
mkdir ../`cat .fname`/src/slm_v2
|
| 227 |
+
mkdir ../`cat .fname`/src/slm_v2/lib
|
| 228 |
+
mkdir ../`cat .fname`/src/slm_v2/bin
|
| 229 |
+
mkdir ../`cat .fname`/src/slm_v2/src
|
| 230 |
+
set -e; for file in readme.txt endian.sh include doc; do \
|
| 231 |
+
ln -s ../../../src/slm_v2/$$file ../`cat .fname`/src/slm_v2/$$file; \
|
| 232 |
+
done
|
| 233 |
+
echo " Copying SLM source"
|
| 234 |
+
tar cf - `find slm_v2/src \( -name makefile.in -o -name install-sh -o -name "*.[ch]" \) -print` | (cd ../`cat .fname`/src && tar xf -)
|
| 235 |
+
echo "Tar-ing SLM to make it ISO-compatable"
|
| 236 |
+
(cd ../`cat .fname`/src && tar chf slm_v2.tar ./slm_v2 && rm -r slm_v2)
|
| 237 |
+
(cd .. && tar -chf - --exclude=CVS `cat src/.fname` | compress > `cat src/.fname`.tar.Z)
|
| 238 |
+
rm -rf ../`cat .fname`
|
| 239 |
+
echo "Decompressing the release file"
|
| 240 |
+
(cd .. && zcat `cat src/.fname`.tar.Z | tar xf -)
|
| 241 |
+
echo "ISO_checking. . . . Only the top-level makefile should fail"
|
| 242 |
+
(cd .. && iso_check `cat src/.fname`)
|
| 243 |
+
rm -rf ../`cat .fname` .fname
|
| 244 |
+
|
| 245 |
+
# Prevent GNU make v3 from overflowing arg limit on SysV.
|
| 246 |
+
.NOEXPORT:
|
SCTK/src/sclite/marc1.c
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* file marc1.c */
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
#include "sctk.h"
|
| 5 |
+
|
| 6 |
+
ARC *make_arc(void *dat, NODE *from_node, NODE *to_node, int *perr)
|
| 7 |
+
|
| 8 |
+
/*********************************************************/
|
| 9 |
+
/* Makes an arc <from_node/symbol/to_node>, returning a */
|
| 10 |
+
/* pointer to it. */
|
| 11 |
+
/*********************************************************/
|
| 12 |
+
{char *proc = "make_arc";
|
| 13 |
+
ARC *p;
|
| 14 |
+
/* code */
|
| 15 |
+
db_enter_msg(proc,1); /* debug only */
|
| 16 |
+
p = (ARC *)malloc_safe(sizeof(ARC),proc);
|
| 17 |
+
*perr = 0;
|
| 18 |
+
p->data = dat;
|
| 19 |
+
p->weight = 0;
|
| 20 |
+
p->net = NULL_NETWORK;
|
| 21 |
+
p->from_node = from_node;
|
| 22 |
+
p->to_node = to_node;
|
| 23 |
+
db_leave_msg(proc,1); /* debug only */
|
| 24 |
+
return p;
|
| 25 |
+
} /* end make_arc() */
|
SCTK/src/sclite/mcnemar.c
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#define MAIN
|
| 2 |
+
#include "sctk.h"
|
| 3 |
+
|
| 4 |
+
int main(int argc, char **argv){
|
| 5 |
+
int **table;
|
| 6 |
+
|
| 7 |
+
alloc_2dimarr(table, 2, 2, int);
|
| 8 |
+
table[0][0] = 100;
|
| 9 |
+
table[0][1] = 200;
|
| 10 |
+
table[1][0] = 300;
|
| 11 |
+
table[1][1] = 400;
|
| 12 |
+
|
| 13 |
+
double conf;
|
| 14 |
+
do_McNemar(table, "Sys1", "Sys2", TRUE, stdout, &conf);
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
}
|
SCTK/src/sclite/mfa.c
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include <sctk.h>
|
| 2 |
+
|
| 3 |
+
void locate_next_file_channel(WTOKE_STR1 **ctms, int nctms, FILE **files, char **hypname, int *eofs, int *conv_end, int case_sense, int feedback);
|
| 4 |
+
void print_linear(NODE *node, void *p);
|
| 5 |
+
int gap_at_times(WTOKE_STR1 *ctm, int end, double *mgap_beg, double *mgap_end, int *mgap_s);
|
| 6 |
+
NETWORK *perform_mfalign(WTOKE_STR1 **ctms, int nctm, int *sil_end, int time_align);
|
| 7 |
+
void populate_tag1(NODE *node, void *p);
|
| 8 |
+
|
| 9 |
+
int mfdb = 0;
|
| 10 |
+
int glob_ties = 0;
|
| 11 |
+
|
| 12 |
+
void mfalign_ctm_files(char **hypname, int nhyps, int time_align, int case_sense, int feedback, void (*callback)(NETWORK *, char *, char *), double silence_dur){
|
| 13 |
+
char *proc = "mfalign_ctm_files";
|
| 14 |
+
WTOKE_STR1 **ctms;
|
| 15 |
+
NETWORK *mfnet;
|
| 16 |
+
FILE **files;
|
| 17 |
+
int *eofs, *conv_end, *sil_end;
|
| 18 |
+
int in;
|
| 19 |
+
int done;
|
| 20 |
+
NETWORK *cor;
|
| 21 |
+
char *file, *chan;
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
{if (getenv("MFALIGN_DBG") != NULL) {
|
| 25 |
+
mfdb=(int)atof(getenv("MFALIGN_DBG")); }}
|
| 26 |
+
|
| 27 |
+
if (feedback > 1) printf("Beginning: %s\n",proc);
|
| 28 |
+
/* ALLOCATE MEMORY */
|
| 29 |
+
alloc_singZ(ctms,nhyps,WTOKE_STR1 *,(WTOKE_STR1 *)0);
|
| 30 |
+
alloc_singZ(files,nhyps,FILE *,(FILE *)0);
|
| 31 |
+
alloc_singZ(eofs,nhyps,int,0);
|
| 32 |
+
alloc_singZ(conv_end,nhyps,int,0);
|
| 33 |
+
alloc_singZ(sil_end,nhyps,int,0);
|
| 34 |
+
|
| 35 |
+
/* OPEN FILES, INIT WTOKE'S, FILE WTOKE'S */
|
| 36 |
+
for (in=0; in < nhyps; in++){
|
| 37 |
+
if ((files[in] = fopen(hypname[in],"r")) == NULL){
|
| 38 |
+
fprintf(stderr,"Can't open input hypothesis file %s\n",hypname[in]);
|
| 39 |
+
exit(1);
|
| 40 |
+
}
|
| 41 |
+
ctms[in] = WTOKE_STR1_init(hypname[in]);
|
| 42 |
+
}
|
| 43 |
+
done = 0;
|
| 44 |
+
while (!done){
|
| 45 |
+
locate_next_file_channel(ctms, nhyps, files, hypname, eofs, conv_end,
|
| 46 |
+
case_sense, feedback);
|
| 47 |
+
|
| 48 |
+
file = ctms[0]->word[ctms[0]->s].conv;
|
| 49 |
+
chan = ctms[0]->word[ctms[0]->s].turn;
|
| 50 |
+
|
| 51 |
+
/* loop though the file/channel section, looking for time breaks */
|
| 52 |
+
while(find_common_silence(ctms, nhyps, conv_end,
|
| 53 |
+
sil_end, silence_dur) == 1){
|
| 54 |
+
if (mfdb >= 5){
|
| 55 |
+
printf("--------- Aligning this chunk -----------\n");
|
| 56 |
+
|
| 57 |
+
for (in=0; in<nhyps; in++){
|
| 58 |
+
double beg, end;
|
| 59 |
+
beg = (ctms[in]->s > conv_end[in]) ? -1.0 :
|
| 60 |
+
ctms[in]->word[sil_end[in]].t1 +
|
| 61 |
+
ctms[in]->word[sil_end[in]].dur;
|
| 62 |
+
end = (sil_end[in] < conv_end[in]) ?
|
| 63 |
+
ctms[in]->word[sil_end[in]+1].t1 : 9999999.9;
|
| 64 |
+
printf(" CTM %d: start: %d end_word: %d start: %.2f"
|
| 65 |
+
" end: %.2f\n",in,ctms[in]->s,sil_end[in],beg,end);
|
| 66 |
+
}
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
mfnet = perform_mfalign(ctms,nhyps,sil_end,time_align);
|
| 70 |
+
Network_traverse(mfnet,populate_tag1,(void *)hypname,0,0,0);
|
| 71 |
+
cor = Network_WORD_to_CORES(mfnet);
|
| 72 |
+
|
| 73 |
+
callback(cor, file, chan);
|
| 74 |
+
|
| 75 |
+
Network_destroy(cor);
|
| 76 |
+
Network_destroy(mfnet);
|
| 77 |
+
|
| 78 |
+
/* skip over this chunk because we're done with it. */
|
| 79 |
+
done = 1;
|
| 80 |
+
for (in=0; in < nhyps; in++){
|
| 81 |
+
ctms[in]->s = sil_end[in] +
|
| 82 |
+
((sil_end[in] <= conv_end[in]) ? 1 : 0);
|
| 83 |
+
if (!eofs[in] || (ctms[in]->s < ctms[in]->n)) done = 0;
|
| 84 |
+
}
|
| 85 |
+
}
|
| 86 |
+
}
|
| 87 |
+
if (glob_ties > 0)
|
| 88 |
+
fprintf(stderr,"Warning: %d ties were arbitrarily broken\n",glob_ties);
|
| 89 |
+
|
| 90 |
+
/* FREE THE MEMORY */
|
| 91 |
+
free_singarr(eofs, int);
|
| 92 |
+
free_singarr(conv_end, int);
|
| 93 |
+
free_singarr(sil_end, int);
|
| 94 |
+
for (in=0; in<nhyps; in++) {
|
| 95 |
+
free_mark_file(ctms[in]);
|
| 96 |
+
fclose(files[in]);
|
| 97 |
+
}
|
| 98 |
+
free_singarr(files, FILE *);
|
| 99 |
+
free_singarr(ctms,WTOKE_STR1 *);
|
| 100 |
+
cleanup_NET_ALIGN();
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
NETWORK *perform_mfalign(WTOKE_STR1 **ctms, int nctm, int *end, int time_align){
|
| 104 |
+
char *proc = "perform_mfalign";
|
| 105 |
+
NETWORK **nets, *out_net;
|
| 106 |
+
WORD *null_alt;
|
| 107 |
+
int in;
|
| 108 |
+
|
| 109 |
+
alloc_singZ(nets,nctm,NETWORK *,(NETWORK *)0);
|
| 110 |
+
null_alt = new_WORD((TEXT *)"@",-1,0.0,0.0,0.0,(TEXT *)0,(TEXT *)0,0,0,-1.0);
|
| 111 |
+
|
| 112 |
+
/* create the networks */
|
| 113 |
+
for (in=0; in < nctm; in++){
|
| 114 |
+
if ((nets[in]=
|
| 115 |
+
Network_create_from_WTOKE(ctms[in],ctms[in]->s,end[in],
|
| 116 |
+
rsprintf("mfalign net %d",in),
|
| 117 |
+
print_WORD_wt,
|
| 118 |
+
equal_WORD2,
|
| 119 |
+
release_WORD, null_alt_WORD,
|
| 120 |
+
opt_del_WORD,
|
| 121 |
+
copy_WORD, make_empty_WORD,
|
| 122 |
+
use_count_WORD,
|
| 123 |
+
1))
|
| 124 |
+
== NULL_NETWORK){
|
| 125 |
+
fprintf(stderr,"%s: Network_create_from_WTOKE failed\n",proc);
|
| 126 |
+
exit(1);
|
| 127 |
+
}
|
| 128 |
+
/* Network_traverse(nets[in],0,0,set_tag1,(void *)ctms[in]->id,0); */
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
/* align the networks */
|
| 132 |
+
Network_dpalign_n_networks(nets,nctm,(!time_align)?wwd_WORD_rover:wwd_time_WORD,
|
| 133 |
+
&out_net,(void *)null_alt);
|
| 134 |
+
|
| 135 |
+
/* delete the networks */
|
| 136 |
+
for (in=0; in < nctm; in++)
|
| 137 |
+
Network_destroy(nets[in]);
|
| 138 |
+
|
| 139 |
+
free_singarr(nets,NETWORK *);
|
| 140 |
+
release_WORD(null_alt);
|
| 141 |
+
|
| 142 |
+
return(out_net);
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
void locate_next_file_channel(WTOKE_STR1 **ctms, int nctm, FILE **files, char **hypname, int *eofs, int *conv_end, int case_sense, int feedback){
|
| 147 |
+
int in;
|
| 148 |
+
|
| 149 |
+
/* locate the file boundaries */
|
| 150 |
+
for (in=0; in < nctm; in++){
|
| 151 |
+
fill_WTOKE_structure(ctms[in], files[in], hypname[in],
|
| 152 |
+
&(eofs[in]), case_sense);
|
| 153 |
+
locate_boundary(ctms[in], ctms[in]->s, TRUE,TRUE,&(conv_end[in]));
|
| 154 |
+
if (in >= 1 && ctms[in]->s <= ctms[in]->n)
|
| 155 |
+
if (strcmp(ctms[0]->word[ctms[0]->s].conv,
|
| 156 |
+
ctms[in]->word[ctms[in]->s].conv) != 0){
|
| 157 |
+
fprintf(scfp,"Error: Conversation mismatches in %s and %s, "
|
| 158 |
+
"%s and %s respectively",hypname[0],hypname[in],
|
| 159 |
+
ctms[0]->word[ctms[0]->s].conv,
|
| 160 |
+
ctms[in]->word[ctms[in]->s].conv);
|
| 161 |
+
exit(1);
|
| 162 |
+
}
|
| 163 |
+
}
|
| 164 |
+
if (feedback >= 1) {
|
| 165 |
+
printf("Working on conversation: %s channel: %s\n",
|
| 166 |
+
ctms[0]->word[ctms[0]->s].conv,
|
| 167 |
+
ctms[0]->word[ctms[0]->s].turn);
|
| 168 |
+
for (in=0; in < nctm; in++)
|
| 169 |
+
printf(" File: %s range %d-%d\n",hypname[in],ctms[in]->s,
|
| 170 |
+
conv_end[in]);
|
| 171 |
+
}
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
/* This function looks for common periods of silence to all the WTOKE
|
| 175 |
+
* structures
|
| 176 |
+
*/
|
| 177 |
+
int find_common_silence(WTOKE_STR1 **ctms, int nctm, int *ctm_end, int *sil_end, double silence_dur){
|
| 178 |
+
double mgap_beg, mgap_end;
|
| 179 |
+
int nc, failed, more_data;
|
| 180 |
+
int dbg = 0;
|
| 181 |
+
|
| 182 |
+
{if (getenv("MFALIGN_COMMON_SIL_DBG") != NULL) {
|
| 183 |
+
dbg=(int)atof(getenv("MFALIGN_COMMON_SIL_DBG")); }}
|
| 184 |
+
|
| 185 |
+
/* locate a gap in the master, ctms[0] */
|
| 186 |
+
sil_end[0] = ctms[0]->s;
|
| 187 |
+
while (sil_end[0] <= ctm_end[0]){
|
| 188 |
+
/* set the gap betwen this word and the next */
|
| 189 |
+
mgap_beg = ctms[0]->word[sil_end[0]].t1 +ctms[0]->word[sil_end[0]].dur;
|
| 190 |
+
/* if there is no next word, make it the end of time */
|
| 191 |
+
mgap_end = (sil_end[0] < ctm_end[0]) ? ctms[0]->word[sil_end[0]+ 1].t1:
|
| 192 |
+
9999999.9 ;
|
| 193 |
+
|
| 194 |
+
if (mgap_end > mgap_beg + silence_dur){
|
| 195 |
+
if (dbg) printf("Found a gap %d (%.2f-%.2f) = %.2f\n",
|
| 196 |
+
sil_end[0],mgap_beg,mgap_end,mgap_end-mgap_beg);
|
| 197 |
+
for (nc=1, failed=0; nc<nctm && !failed; nc++){
|
| 198 |
+
if (gap_at_times(ctms[nc],ctm_end[nc],
|
| 199 |
+
&mgap_beg,&mgap_end,&sil_end[nc]) == 1){
|
| 200 |
+
if (dbg) printf(" Gap in %d\n",nc);
|
| 201 |
+
} else {
|
| 202 |
+
failed = 1;
|
| 203 |
+
}
|
| 204 |
+
}
|
| 205 |
+
if (failed != 1){
|
| 206 |
+
if (dbg) printf("Segment defined at:\n");
|
| 207 |
+
return(1);
|
| 208 |
+
}
|
| 209 |
+
}
|
| 210 |
+
sil_end[0] ++;
|
| 211 |
+
}
|
| 212 |
+
/* ctm[0] is at the end of the road, move all the other ctms to the
|
| 213 |
+
* end as well. If there is data left in them, return 1
|
| 214 |
+
*/
|
| 215 |
+
if (dbg) printf("*** ctm[0] has ran out of data\n");
|
| 216 |
+
more_data = 0;
|
| 217 |
+
for (nc=0; nc<nctm; nc++){
|
| 218 |
+
sil_end[nc] = ctm_end[nc];
|
| 219 |
+
if (ctms[nc]->s <= ctm_end[nc]) more_data=1;
|
| 220 |
+
}
|
| 221 |
+
return (more_data);
|
| 222 |
+
}
|
| 223 |
+
|
| 224 |
+
void populate_tag1(NODE *node, void *p){
|
| 225 |
+
char **tags = (char **)p;
|
| 226 |
+
int Narc, f, *use, arc;
|
| 227 |
+
ARC_LIST_ATOM *parc;
|
| 228 |
+
|
| 229 |
+
if (node != NULL && strcmp(node->name,"STOP") != 0){
|
| 230 |
+
/* count the arcs */
|
| 231 |
+
for (Narc=0, parc=node->out_arcs; parc != (ARC_LIST_ATOM *)0;
|
| 232 |
+
parc = parc->next)
|
| 233 |
+
Narc++;
|
| 234 |
+
alloc_singZ(use,Narc,int,-1);
|
| 235 |
+
/* map the usage */
|
| 236 |
+
for (arc = 0, parc=node->out_arcs; parc != (ARC_LIST_ATOM *)0;
|
| 237 |
+
parc = parc->next, arc++){
|
| 238 |
+
/* Eprintf(" %s\n",((WORD*)(parc->arc->data))->value); */
|
| 239 |
+
if (TEXT_strcmp(((WORD*)(parc->arc->data))->value,(TEXT *)"@") != 0){
|
| 240 |
+
/* reset that systems use pointer */
|
| 241 |
+
for (f=0; f<Narc; f++){
|
| 242 |
+
if (TEXT_strcmp(((WORD*)(parc->arc->data))->tag1,(TEXT*)tags[f]) == 0)
|
| 243 |
+
use[arc] = f;
|
| 244 |
+
}
|
| 245 |
+
}
|
| 246 |
+
}
|
| 247 |
+
/* dump_singarr(use,Narc," %d",stdout); */
|
| 248 |
+
for (arc = 0, parc=node->out_arcs; parc != (ARC_LIST_ATOM *)0;
|
| 249 |
+
parc = parc->next, arc++)
|
| 250 |
+
if (use[arc] < 0){
|
| 251 |
+
int hit = -1, y;
|
| 252 |
+
/* printf(" Arc %d not tagged\n",arc); */
|
| 253 |
+
for (f=0; f<Narc && hit < 0; f++){
|
| 254 |
+
hit = f;
|
| 255 |
+
/* printf(" is %d used? \n",f); */
|
| 256 |
+
/* does any of the use elements == f */
|
| 257 |
+
for (y=0; y<Narc; y++)
|
| 258 |
+
if (use[y] == f)
|
| 259 |
+
hit = -1;
|
| 260 |
+
/* printf(" %d\n",hit); */
|
| 261 |
+
}
|
| 262 |
+
if (hit >= 0){
|
| 263 |
+
((WORD*)(parc->arc->data))->tag1 = TEXT_strdup((TEXT*)tags[hit]);
|
| 264 |
+
use[arc] = hit;
|
| 265 |
+
}
|
| 266 |
+
}
|
| 267 |
+
/* printf(" "); dump_singarr(use,Narc," %d",stdout); */
|
| 268 |
+
|
| 269 |
+
free_singarr(use,int);
|
| 270 |
+
}
|
| 271 |
+
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
int gap_at_times(WTOKE_STR1 *ctm, int end, double *mgap_beg, double *mgap_end, int *mgap_s){
|
| 275 |
+
int i;
|
| 276 |
+
double gap_end, gap_beg;
|
| 277 |
+
|
| 278 |
+
/* if there is no more data in this ctm, that answer is YES */
|
| 279 |
+
if (ctm->s > end) {
|
| 280 |
+
*mgap_s = ctm->s;
|
| 281 |
+
return(1);
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
for (i=ctm->s; i<=end; i++){
|
| 285 |
+
gap_beg = ctm->word[i].t1 + ctm->word[i].dur;
|
| 286 |
+
gap_end = (i < end) ? ctm->word[i+1].t1 : 9999999.9;
|
| 287 |
+
if (overlap(*mgap_beg,*mgap_end,gap_beg,gap_end) > 0.0){
|
| 288 |
+
*mgap_s = i;
|
| 289 |
+
/* printf(" Gap@ %d times %.2f to %.2f\n",
|
| 290 |
+
i,gap_beg,gap_end); */
|
| 291 |
+
*mgap_beg = MAX(*mgap_beg,gap_beg);
|
| 292 |
+
*mgap_end = MIN(*mgap_end,gap_end);
|
| 293 |
+
/* printf(" Reset gap times to %.2f-%.2f\n",
|
| 294 |
+
*mgap_beg,*mgap_end); */
|
| 295 |
+
return (1);
|
| 296 |
+
}
|
| 297 |
+
}
|
| 298 |
+
return(0);
|
| 299 |
+
}
|
SCTK/src/sclite/mnode1.c
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* file mnode1.c */
|
| 2 |
+
|
| 3 |
+
#include "sctk.h"
|
| 4 |
+
|
| 5 |
+
NODE *make_node(char *name, NETWORK *net, ARC *from_arc, ARC *to_arc, int *highest_nnode_name, int *perr)
|
| 6 |
+
|
| 7 |
+
/************************************************************/
|
| 8 |
+
/* Makes a new node, returns a pointer to it. */
|
| 9 |
+
/* The new node is initialized with name, from_arc, to_arc. */
|
| 10 |
+
/* Set to be neither start not stop state. */
|
| 11 |
+
/* All boolean flags are initialized to F. */
|
| 12 |
+
/* If name is NULL, uses a char string version of bumped */
|
| 13 |
+
/* *highest_nnode_name for the new node name. */
|
| 14 |
+
/************************************************************/
|
| 15 |
+
{char *proc = "make_node";
|
| 16 |
+
char sxx[LINE_LENGTH], *sx = &sxx[0];
|
| 17 |
+
NODE *p;
|
| 18 |
+
/* code */
|
| 19 |
+
db_enter_msg(proc,1); /* debug only */
|
| 20 |
+
p = (NODE *)malloc_safe(sizeof(NODE),proc);
|
| 21 |
+
*perr = 0;
|
| 22 |
+
if (name != NULL)
|
| 23 |
+
{p->name = strdup_safe(name,proc);
|
| 24 |
+
}
|
| 25 |
+
else
|
| 26 |
+
{/* make name from node number */
|
| 27 |
+
*highest_nnode_name += 1;
|
| 28 |
+
sprintf(sx,"%d",*highest_nnode_name);
|
| 29 |
+
p->name = strdup_safe(sx,proc);
|
| 30 |
+
}
|
| 31 |
+
p->net = net ;
|
| 32 |
+
p->in_arcs = NULL;
|
| 33 |
+
p->out_arcs = NULL;
|
| 34 |
+
p->start_state = F;
|
| 35 |
+
p->stop_state = F;
|
| 36 |
+
p->flag1 = F;
|
| 37 |
+
p->flag2 = F;
|
| 38 |
+
if (from_arc != NULL){
|
| 39 |
+
p->in_arcs = add_to_arc_list(p->in_arcs,from_arc,perr);
|
| 40 |
+
if (*perr > 0) {
|
| 41 |
+
printf("%s:*ERR: add_to_arc_list() returns %d\n",proc,*perr);
|
| 42 |
+
return((NODE *)0);
|
| 43 |
+
}
|
| 44 |
+
}
|
| 45 |
+
if (to_arc != NULL) {
|
| 46 |
+
p->out_arcs = add_to_arc_list(p->out_arcs,to_arc,perr);
|
| 47 |
+
if (*perr > 0) {
|
| 48 |
+
printf("%s:*ERR: add_to_arc_list() returns %d\n",proc,*perr);
|
| 49 |
+
return((NODE *)0);
|
| 50 |
+
}
|
| 51 |
+
}
|
| 52 |
+
db_leave_msg(proc,1); /* debug only */
|
| 53 |
+
return p;
|
| 54 |
+
} /* end make_node() */
|
| 55 |
+
|
SCTK/src/sclite/mtchprs.c
ADDED
|
@@ -0,0 +1,833 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**********************************************************************/
|
| 2 |
+
/* */
|
| 3 |
+
/* FILENAME: matched_pairs.c */
|
| 4 |
+
/* BY: Jonathan G. Fiscus */
|
| 5 |
+
/* DATE: April 14 1989 */
|
| 6 |
+
/* NATIONAL INSTITUTE OF STANDARDS AND TECHNOLOGY */
|
| 7 |
+
/* SPEECH RECOGNITION GROUP */
|
| 8 |
+
/* */
|
| 9 |
+
/* DESCRIPTION: These programs perform the Matched Pairs */
|
| 10 |
+
/* tests. which include: */
|
| 11 |
+
/* SEGMENTATION ANALYSIS */
|
| 12 |
+
/* MATCHED PAIRS TEST FOR SYSTEMS */
|
| 13 |
+
/* */
|
| 14 |
+
/**********************************************************************/
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
#include "sctk.h"
|
| 18 |
+
|
| 19 |
+
/**********************************************************************/
|
| 20 |
+
/* structures and defines for the sentence segment list */
|
| 21 |
+
#define MIN_NUM_GOOD 2
|
| 22 |
+
#define MAX_SEG_ANAL 10
|
| 23 |
+
|
| 24 |
+
#ifdef __cplusplus
|
| 25 |
+
extern "C" {
|
| 26 |
+
#endif
|
| 27 |
+
|
| 28 |
+
typedef struct segment_count_struct{
|
| 29 |
+
int number_ref;
|
| 30 |
+
int number_errors_for_hyp1;
|
| 31 |
+
int number_errors_for_hyp2;
|
| 32 |
+
} SEG;
|
| 33 |
+
|
| 34 |
+
#ifdef __cplusplus
|
| 35 |
+
}
|
| 36 |
+
#endif
|
| 37 |
+
|
| 38 |
+
/* alloc a segment list */
|
| 39 |
+
#define alloc_SEG_LIST(_seg,_num) \
|
| 40 |
+
alloc_2dimarr(_seg,_num,1,SEG);
|
| 41 |
+
|
| 42 |
+
#define expand_SEG_LIST(_seg_l,_num,_max) \
|
| 43 |
+
{ int _l;\
|
| 44 |
+
expand_1dim(_seg_l,_num,_max,2.0,SEG *,1); \
|
| 45 |
+
for (_l=_num; _l < _max; _l++) \
|
| 46 |
+
alloc_singarr((_seg_l)[_l],1,SEG); \
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
#define free_SEG_LIST(_seg,_num) free_2dimarr(_seg,_num,SEG)
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
/* macros to access the segment list */
|
| 53 |
+
#define seg_n(_sg,_s) _sg[_s]
|
| 54 |
+
#define seg_ref(_sg,_s) _sg[_s]->number_ref
|
| 55 |
+
#define seg_hyp1(_sg,_s) _sg[_s]->number_errors_for_hyp1
|
| 56 |
+
#define seg_hyp2(_sg,_s) _sg[_s]->number_errors_for_hyp2
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
void evaluate_SEG(char *sys1_str, char *sys2_str, SEG **seg_l, int *num_seg, int sent_cnt, int min_good, double *s1_pct, double *s2_pct, double *seg_per_sent, int verbose, FILE *fp);
|
| 60 |
+
int analyze_Z_score(SCORES *sys1, SCORES *sys2, double mean, double variance, double std_dev, double Z_stat, int verbose);
|
| 61 |
+
void test_comp_sents(PATH *snt1, PATH *snt2, SEG ***seg_l, int *num_seg, int *max_seg, int min_good);
|
| 62 |
+
void count_seg(PATH *snt1, PATH *snt2, int beg1, int beg2, int end1, int end2, SEG ***seg_l, int *num_seg, int *max_seg, int dbg);
|
| 63 |
+
void seg_count(PATH *snt, int from, int to, int *err, int *ref);
|
| 64 |
+
void print_sent_seg_averaged_analysis(SCORES *scor[], int nscor, double ***seg_per_sent, char *tname);
|
| 65 |
+
void print_sent_seg_long_analysis(SCORES *scor[], int nscor, double ***seg_per_sent, char *tname);
|
| 66 |
+
void print_compare_matrix_for_sys(SCORES *scor[], int nscor, int **winner, char *matrix_name, char *tname, char *v_desc, double **sys1_pct_arr, double **sys2_pct_arr, int **num_seg, double **Z_stat, int min_num_good, FILE *fp);
|
| 67 |
+
|
| 68 |
+
/**********************************************************************/
|
| 69 |
+
/* this procedure is written to analyze the segmentation for */
|
| 70 |
+
/* varying numbers on the minimum number of good words to bound */
|
| 71 |
+
/* the beginning and the ends of the segments */
|
| 72 |
+
/**********************************************************************/
|
| 73 |
+
void do_mtch_pairs_seg_analysis(SCORES *scor[], int nscor, char *t_name, int seg_ave, int seg_long)
|
| 74 |
+
{
|
| 75 |
+
int sys1, sys2, min_g;
|
| 76 |
+
int result;
|
| 77 |
+
double conf;
|
| 78 |
+
int **num_seg, **max_seg;
|
| 79 |
+
double **sys1_pct_arr, **sys2_pct_arr, **Z_stat_arr, ***seg_per_sent;
|
| 80 |
+
|
| 81 |
+
/* do all allocations */
|
| 82 |
+
fprintf(stderr,"Doing segmentation analysis. This is slow so . . . \n\n");
|
| 83 |
+
alloc_2dimarr(num_seg,nscor,nscor,int);
|
| 84 |
+
alloc_2dimZ(max_seg,nscor,nscor,int,100);
|
| 85 |
+
alloc_2dimarr(sys1_pct_arr,nscor,nscor,double);
|
| 86 |
+
alloc_2dimarr(sys2_pct_arr,nscor,nscor,double);
|
| 87 |
+
alloc_2dimarr(Z_stat_arr,nscor,nscor,double);
|
| 88 |
+
alloc_3dimZ(seg_per_sent,MAX_SEG_ANAL,nscor,nscor,double,0.0);
|
| 89 |
+
|
| 90 |
+
/* loop for min_good, and compared systems */
|
| 91 |
+
for (min_g=0; min_g < MAX_SEG_ANAL; min_g++){
|
| 92 |
+
fprintf(stderr," calculating buffer of %d\n",min_g);
|
| 93 |
+
for (sys1=0; sys1 <(nscor-1); sys1++)
|
| 94 |
+
for (sys2=sys1+1; sys2<(nscor); sys2++){
|
| 95 |
+
result = do_mtch_pairs_on_sys(scor, nscor,sys1,sys2,
|
| 96 |
+
&(sys1_pct_arr[sys1][sys2]),
|
| 97 |
+
&(sys2_pct_arr[sys1][sys2]),
|
| 98 |
+
&(num_seg[sys1][sys2]),
|
| 99 |
+
&(max_seg[sys1][sys2]),
|
| 100 |
+
&(Z_stat_arr[sys1][sys2]),
|
| 101 |
+
&(seg_per_sent[min_g][sys1][sys2]),
|
| 102 |
+
min_g+1,FALSE,stdout,&conf);
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
/* if the flag, print the requested analysis */
|
| 107 |
+
if (seg_long)
|
| 108 |
+
print_sent_seg_long_analysis(scor,nscor,seg_per_sent,t_name);
|
| 109 |
+
if (seg_ave)
|
| 110 |
+
print_sent_seg_averaged_analysis(scor,nscor,seg_per_sent,t_name);
|
| 111 |
+
|
| 112 |
+
free_2dimarr(num_seg,nscor,int);
|
| 113 |
+
free_2dimarr(max_seg,nscor,int);
|
| 114 |
+
free_2dimarr(sys1_pct_arr,nscor,double);
|
| 115 |
+
free_2dimarr(sys2_pct_arr,nscor,double);
|
| 116 |
+
free_2dimarr(Z_stat_arr,nscor,double);
|
| 117 |
+
free_3dimarr(seg_per_sent,MAX_SEG_ANAL,nscor,double);
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
/**********************************************************************/
|
| 122 |
+
/* this procedure performs a single matched paired analysis for the */
|
| 123 |
+
/* one level of the min_good and returns the results in the winner */
|
| 124 |
+
/* array */
|
| 125 |
+
/**********************************************************************/
|
| 126 |
+
void do_mtch_pairs(SCORES *scor[], int nscor, char *min_num_good_str, char *test_name, int print_report, int verbose, int ***out_winner, char *outroot, int feedback, double ***out_conf)
|
| 127 |
+
{
|
| 128 |
+
int sys1, sys2;
|
| 129 |
+
int result, **winner;
|
| 130 |
+
double **conf;
|
| 131 |
+
int *sum_winner, **num_seg, min_num_good, **max_seg;
|
| 132 |
+
double **sys1_pct_arr, **sys2_pct_arr, **Z_stat_arr, **seg_per_sent;
|
| 133 |
+
char *matrix_name = "COMPARISON MATRIX: FOR THE MATCHED PAIRS TEST";
|
| 134 |
+
char *mean_desc = "PECENTAGES ARE MEAN PCT ERROR/SEGMENT. FIRST # IS LEFT SYSTEM";
|
| 135 |
+
FILE *fp = stdout;
|
| 136 |
+
|
| 137 |
+
if (print_report || verbose){
|
| 138 |
+
char *f = rsprintf("%s.mapsswe",outroot);
|
| 139 |
+
if ((fp=(strcmp(outroot,"-") == 0) ? stdout : fopen(f,"w")) ==
|
| 140 |
+
(FILE *)0){
|
| 141 |
+
fprintf(stderr,"Warning: Open of %s for write failed. "
|
| 142 |
+
"Using stdout instead.\n",f);
|
| 143 |
+
fp = stdout;
|
| 144 |
+
} else
|
| 145 |
+
if (feedback >= 1) printf(" Output written to '%s'\n",f);
|
| 146 |
+
}
|
| 147 |
+
if ((min_num_good = atoi(min_num_good_str)) <= 0){
|
| 148 |
+
fprintf(stderr,"Warning: Minimum seperation by correct words is \n");
|
| 149 |
+
fprintf(stderr," too low, setting to %d\n",
|
| 150 |
+
DEFAULT_MIN_NUM_GOOD);
|
| 151 |
+
min_num_good = DEFAULT_MIN_NUM_GOOD;
|
| 152 |
+
}
|
| 153 |
+
if (!print_report) verbose = FALSE;
|
| 154 |
+
|
| 155 |
+
/* all allocations */
|
| 156 |
+
alloc_2dimarr(num_seg,nscor,nscor,int);
|
| 157 |
+
alloc_2dimZ(max_seg,nscor,nscor,int,100);
|
| 158 |
+
alloc_2dimarr(sys1_pct_arr,nscor,nscor,double);
|
| 159 |
+
alloc_2dimarr(sys2_pct_arr,nscor,nscor,double);
|
| 160 |
+
alloc_2dimarr(Z_stat_arr,nscor,nscor,double);
|
| 161 |
+
alloc_2dimZ(seg_per_sent,nscor,nscor,double,0.0);
|
| 162 |
+
alloc_singZ(sum_winner,nscor,int,NO_DIFF);
|
| 163 |
+
alloc_2dimZ(winner,nscor,nscor,int,NO_DIFF);
|
| 164 |
+
*out_winner = winner;
|
| 165 |
+
alloc_2dimZ(conf,nscor,nscor,double,0.0);
|
| 166 |
+
*out_conf = conf;
|
| 167 |
+
|
| 168 |
+
/* loop each pair of compared systems */
|
| 169 |
+
for (sys1=0; sys1 <(nscor-1); sys1++)
|
| 170 |
+
for (sys2=sys1+1; sys2<(nscor); sys2++){
|
| 171 |
+
result = do_mtch_pairs_on_sys(scor,nscor,sys1,sys2,
|
| 172 |
+
&(sys1_pct_arr[sys1][sys2]),
|
| 173 |
+
&(sys2_pct_arr[sys1][sys2]),
|
| 174 |
+
&(num_seg[sys1][sys2]),
|
| 175 |
+
&(max_seg[sys1][sys2]),
|
| 176 |
+
&(Z_stat_arr[sys1][sys2]),
|
| 177 |
+
&(seg_per_sent[sys1][sys2]),
|
| 178 |
+
min_num_good,verbose,fp,
|
| 179 |
+
&(conf[sys1][sys2]));
|
| 180 |
+
winner[sys1][sys2] = result;
|
| 181 |
+
sum_winner[sys2] += result * (-1);
|
| 182 |
+
sum_winner[sys1] += result;
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
/* if print_report print the requested analysis */
|
| 186 |
+
if (print_report){
|
| 187 |
+
if (verbose) form_feed(fp);
|
| 188 |
+
print_compare_matrix_for_sys(scor,nscor,winner,matrix_name,test_name,
|
| 189 |
+
mean_desc,sys1_pct_arr,sys2_pct_arr,
|
| 190 |
+
num_seg,Z_stat_arr,min_num_good,fp);
|
| 191 |
+
if (fp == stdout) form_feed(fp);
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
free_2dimarr(sys1_pct_arr,nscor,double);
|
| 195 |
+
free_2dimarr(sys2_pct_arr,nscor,double);
|
| 196 |
+
free_2dimarr(Z_stat_arr,nscor,double);
|
| 197 |
+
free_2dimarr(seg_per_sent,nscor,double);
|
| 198 |
+
free_singarr(sum_winner,int);
|
| 199 |
+
free_2dimarr(num_seg,nscor,int);
|
| 200 |
+
free_2dimarr(max_seg,nscor,int);
|
| 201 |
+
/* Big Error free_2dimarr(conf,nscor,double); */
|
| 202 |
+
|
| 203 |
+
if (fp != stdout) fclose(fp);
|
| 204 |
+
}
|
| 205 |
+
|
| 206 |
+
/**********************************************************************/
|
| 207 |
+
/* the guts of the Matched Pairs program, this procedure compares */
|
| 208 |
+
/* 2 systems in a SYS_ALIGN_LIST with indexes sys1_ind and sys2_ind */
|
| 209 |
+
/* then goes through each matching sentence then calls another */
|
| 210 |
+
/* procedure to find the segments and store them in the segment */
|
| 211 |
+
/* list. after all sentences are compared, the segment list is */
|
| 212 |
+
/* analyzed */
|
| 213 |
+
/**********************************************************************/
|
| 214 |
+
int do_mtch_pairs_on_sys(SCORES *scor[], int nscor, int sys1_ind, int sys2_ind, double *sys1_pct, double *sys2_pct, int *num_seg, int *max_seg, double *Z_stat, double *seg_per_sent, int min_num_good, int verbose,FILE *fp, double *conf)
|
| 215 |
+
{
|
| 216 |
+
int spk1, spk2, snt1, snt2, i, sent_cnt=0, *err_diff;
|
| 217 |
+
double mean, std_dev, variance, median;
|
| 218 |
+
SCORES *sys1, *sys2;
|
| 219 |
+
SEG **seg_l;
|
| 220 |
+
|
| 221 |
+
*num_seg = 0;
|
| 222 |
+
sys1 = scor[sys1_ind];
|
| 223 |
+
sys2 = scor[sys2_ind];
|
| 224 |
+
|
| 225 |
+
alloc_SEG_LIST(seg_l,*max_seg);
|
| 226 |
+
|
| 227 |
+
for (spk1=0;spk1 < sys1->num_grp; spk1++){ /* for all speaker sys1 */
|
| 228 |
+
/**** find the matching speaker */
|
| 229 |
+
for (spk2=0;spk2 < sys2->num_grp; spk2++)
|
| 230 |
+
if (strcmp(sys1->grp[spk1].name, sys2->grp[spk2].name) == 0)
|
| 231 |
+
break;
|
| 232 |
+
/**** the the speakers match, start on the sentences */
|
| 233 |
+
if (spk2 != sys2->num_grp){
|
| 234 |
+
/**** for all sents in sys1,spkr1 */
|
| 235 |
+
for (snt1 = 0; snt1 < sys1->grp[spk1].num_path; snt1++){
|
| 236 |
+
/**** for all sents in sys2,spkr2 */
|
| 237 |
+
for (snt2 = 0; snt2 < sys2->grp[spk2].num_path; snt2++)
|
| 238 |
+
/**** if the sentences are the same, compare them */
|
| 239 |
+
if(strcmp(sys1->grp[spk1].path[snt1]->id,
|
| 240 |
+
sys2->grp[spk2].path[snt2]->id) == 0){
|
| 241 |
+
test_comp_sents(sys1->grp[spk1].path[snt1],
|
| 242 |
+
sys2->grp[spk2].path[snt2],
|
| 243 |
+
&seg_l,num_seg, max_seg, min_num_good);
|
| 244 |
+
sent_cnt++;
|
| 245 |
+
break;
|
| 246 |
+
}
|
| 247 |
+
}
|
| 248 |
+
} else {
|
| 249 |
+
fprintf(stderr,"Warning: Speaker %s is in system %s but not system %s\n",
|
| 250 |
+
sys1->grp[spk1].name,sys1->title,sys2->title);
|
| 251 |
+
}
|
| 252 |
+
}
|
| 253 |
+
/* calculate the percentages of errors for both systems and print */
|
| 254 |
+
/* a report if verbose == TRUE */
|
| 255 |
+
evaluate_SEG(sys1->title, sys2->title,seg_l,num_seg,sent_cnt,min_num_good,
|
| 256 |
+
sys1_pct,sys2_pct,seg_per_sent,verbose,fp);
|
| 257 |
+
|
| 258 |
+
alloc_singZ(err_diff,*max_seg,int,0);
|
| 259 |
+
|
| 260 |
+
/* calc an arr with the difference in the errors for each segment */
|
| 261 |
+
for (i=0;i<*num_seg;i++)
|
| 262 |
+
err_diff[i] = seg_hyp1(seg_l,i) - seg_hyp2(seg_l,i);
|
| 263 |
+
|
| 264 |
+
calc_mean_var_std_dev_Zstat(err_diff,*num_seg,
|
| 265 |
+
&mean,&variance,&std_dev,&median,Z_stat);
|
| 266 |
+
/* Special output routine */
|
| 267 |
+
if (verbose){
|
| 268 |
+
fprintf(fp,"MTCH_PR_RESULTS (systems: %s %s) (# segs: %d) "
|
| 269 |
+
"(Seg per Sent: %5.3f) ",
|
| 270 |
+
sys1->title,sys2->title,*num_seg,
|
| 271 |
+
*seg_per_sent);
|
| 272 |
+
fprintf(fp,"(%% Error: %5.2f %5.2f) (mean: %5.3f) (std dev: %5.3f) "
|
| 273 |
+
"(Z Stat: %5.3f) (Stat Diff: %s)\n",
|
| 274 |
+
*sys1_pct,*sys2_pct,mean,std_dev,*Z_stat,
|
| 275 |
+
(analyze_Z_score(sys1,sys2,mean,variance,std_dev,
|
| 276 |
+
*Z_stat,SILENT) == NO_DIFF) ? "No" : "Yes");
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
free_singarr(err_diff,int);
|
| 280 |
+
free_SEG_LIST(seg_l,*max_seg);
|
| 281 |
+
*conf = 1.0 - (2.0 * (normprob((double) (fabs(*Z_stat))) - 0.50));
|
| 282 |
+
|
| 283 |
+
return(analyze_Z_score(sys1,sys2,mean,variance,std_dev,*Z_stat,SILENT));
|
| 284 |
+
}
|
| 285 |
+
|
| 286 |
+
/**********************************************************************/
|
| 287 |
+
/* this procedure calculates the percentages of errors for each */
|
| 288 |
+
/* systems segments, if verbose == TRUE then a report is printed */
|
| 289 |
+
/* to stdout for looking at segment counts */
|
| 290 |
+
/**********************************************************************/
|
| 291 |
+
void evaluate_SEG(char *sys1_str, char *sys2_str, SEG **seg_l, int *num_seg, int sent_cnt, int min_good, double *s1_pct, double *s2_pct, double *seg_per_sent, int verbose,FILE *fp)
|
| 292 |
+
{
|
| 293 |
+
int i, tot_ref=0, tot_err_h1=0, tot_err_h2=0;
|
| 294 |
+
|
| 295 |
+
/* calc the pcts */
|
| 296 |
+
for (i=0;i<*num_seg;i++){
|
| 297 |
+
tot_ref += seg_ref(seg_l,i);
|
| 298 |
+
tot_err_h1 += seg_hyp1(seg_l,i);
|
| 299 |
+
tot_err_h2 += seg_hyp2(seg_l,i);
|
| 300 |
+
}
|
| 301 |
+
(*s1_pct) = pct(tot_err_h1,tot_ref);
|
| 302 |
+
(*s2_pct) = pct(tot_err_h2,tot_ref);
|
| 303 |
+
(*seg_per_sent) = (double)(*num_seg) / (double)sent_cnt;
|
| 304 |
+
|
| 305 |
+
/* if needed, print the systems segmentation reports */
|
| 306 |
+
if (verbose){
|
| 307 |
+
fprintf(fp," SEGMENTATION REPORT FOR SYSTEMS\n");
|
| 308 |
+
fprintf(fp," %4s and %4s\n",sys1_str, sys2_str);
|
| 309 |
+
fprintf(fp,"Minimum Number of Correct Boundary words %1d\n\n",min_good);
|
| 310 |
+
fprintf(fp," Number of Segments %2d, %5.3f per sentence\n",*num_seg,
|
| 311 |
+
(*seg_per_sent));
|
| 312 |
+
fprintf(fp," Number of Sentences %2d\n\n",sent_cnt);
|
| 313 |
+
fprintf(fp," # Ref wrds Err %4s Err %4s\n",sys1_str, sys2_str);
|
| 314 |
+
fprintf(fp,"---------------------------------------\n");
|
| 315 |
+
if (FALSE){
|
| 316 |
+
for (i=0;i<*num_seg;i++)
|
| 317 |
+
fprintf(fp," %4d %4d %4d\n",
|
| 318 |
+
seg_ref(seg_l,i),seg_hyp1(seg_l,i),seg_hyp2(seg_l,i));
|
| 319 |
+
fprintf(fp,"---------------------------------------\n");
|
| 320 |
+
}
|
| 321 |
+
fprintf(fp,"Totals %4d %4d %4d\n\n",
|
| 322 |
+
tot_ref,tot_err_h1,tot_err_h2);
|
| 323 |
+
fprintf(fp,"Pct err %5.1f%% %5.1f%%\n\n",
|
| 324 |
+
*s1_pct,*s2_pct);
|
| 325 |
+
fprintf(fp,"\n\n\n");
|
| 326 |
+
|
| 327 |
+
/* do a McNermar-style anaylsys */
|
| 328 |
+
/* first calc the matrix */
|
| 329 |
+
{
|
| 330 |
+
int **table=NULL, ans; double mcn_conf=0.0;
|
| 331 |
+
alloc_2dimZ(table,2,2,int,0);
|
| 332 |
+
for (i=0;i<*num_seg;i++){
|
| 333 |
+
if (seg_hyp1(seg_l,i) == 0 && seg_hyp2(seg_l,i) == 0 &&
|
| 334 |
+
seg_ref(seg_l,i) == 0){
|
| 335 |
+
table[0][0] ++; /* THIS WILL NEVER HAPPEN */
|
| 336 |
+
fprintf(stderr,"Warning: MPESM test identified a correct/correct segment- %d\n",i);
|
| 337 |
+
}
|
| 338 |
+
else if (seg_hyp1(seg_l,i) > 0 && seg_hyp2(seg_l,i) == 0)
|
| 339 |
+
table[1][0] ++;
|
| 340 |
+
else if (seg_hyp1(seg_l,i) == 0 && seg_hyp2(seg_l,i) > 0)
|
| 341 |
+
table[0][1] ++;
|
| 342 |
+
else
|
| 343 |
+
table[1][1] ++;
|
| 344 |
+
}
|
| 345 |
+
ans = do_McNemar(table,sys1_str,sys2_str,verbose,fp,&mcn_conf);
|
| 346 |
+
|
| 347 |
+
free_2dimarr(table,2,int);
|
| 348 |
+
}
|
| 349 |
+
}
|
| 350 |
+
if (0) { int i;
|
| 351 |
+
fprintf(fp,"Segment size Report\n");
|
| 352 |
+
for (i=0;i<*num_seg;i++){
|
| 353 |
+
fprintf(fp, " Segment: #ref=%d sys1Err=%d sys2Err=%d errDiff=%d\n",
|
| 354 |
+
seg_ref(seg_l,i), seg_hyp1(seg_l,i), seg_hyp2(seg_l,i),abs(seg_hyp1(seg_l,i) - seg_hyp2(seg_l,i)));
|
| 355 |
+
}
|
| 356 |
+
}
|
| 357 |
+
}
|
| 358 |
+
|
| 359 |
+
|
| 360 |
+
/**********************************************************************/
|
| 361 |
+
/* this function returns whether or not the Z_stat is outside the */
|
| 362 |
+
/* range of significance, if needed, a verbose report is printed */
|
| 363 |
+
/**********************************************************************/
|
| 364 |
+
int analyze_Z_score(SCORES *sys1, SCORES *sys2, double mean, double variance, double std_dev, double Z_stat, int verbose)
|
| 365 |
+
{
|
| 366 |
+
int eval;
|
| 367 |
+
char pad = '\0';
|
| 368 |
+
|
| 369 |
+
if (verbose){
|
| 370 |
+
printf("\n%s\t Analysis of matched pairs comparison\n\n",&pad);
|
| 371 |
+
printf("%s\t\t\t Comparing %s and %s\n\n",&pad,
|
| 372 |
+
sys1->title, sys2->title);
|
| 373 |
+
printf("%s\t H : means of sentence segment errors are equal.\n",&pad);
|
| 374 |
+
printf("%s\t 0\n\n",&pad);
|
| 375 |
+
eval = print_Z_analysis(Z_stat);
|
| 376 |
+
}
|
| 377 |
+
else
|
| 378 |
+
eval = Z_pass(Z_stat);
|
| 379 |
+
/* if the mean is less then we want the sys1 index to be the winner */
|
| 380 |
+
if (mean < 0.0)
|
| 381 |
+
eval *= (-1);
|
| 382 |
+
return(eval);
|
| 383 |
+
}
|
| 384 |
+
|
| 385 |
+
/**********************************************************************/
|
| 386 |
+
/* this procedure tries to break up sentences into segments and then*/
|
| 387 |
+
/* counts and stores the segment errors and size for later */
|
| 388 |
+
/* processing. The algorithm is a modified state transition graph */
|
| 389 |
+
/* that looks like this: */
|
| 390 |
+
/* */
|
| 391 |
+
/* the beginning state is b: */
|
| 392 |
+
/* corr means both sentences have the current word correct: */
|
| 393 |
+
/* error means at least one sentence had an error: */
|
| 394 |
+
/* _ */
|
| 395 |
+
/* / \ corr */
|
| 396 |
+
/* v / */
|
| 397 |
+
/* b <--------------. */
|
| 398 |
+
/* | | */
|
| 399 |
+
/* | error | */
|
| 400 |
+
/* | | */
|
| 401 |
+
/* V | */
|
| 402 |
+
/* ,-------------------> e<-. error | */
|
| 403 |
+
/* | |\_/ | */
|
| 404 |
+
/* | | | */
|
| 405 |
+
/* | ,---------> | good | */
|
| 406 |
+
/* | | V | */
|
| 407 |
+
/* | | if #good == min_good | */
|
| 408 |
+
/* error| corr| then store the segment ---' */
|
| 409 |
+
/* | | | */
|
| 410 |
+
/* | | V */
|
| 411 |
+
/* | `---------- g */
|
| 412 |
+
/* | | */
|
| 413 |
+
/* | | */
|
| 414 |
+
/* `---------------------' */
|
| 415 |
+
/* Modified: Nov 10, 1994 */
|
| 416 |
+
/* The synchronization between reference strings is lost if altern- */
|
| 417 |
+
/* ation is use in the reference strings. To correct the problem, */
|
| 418 |
+
/* code was added to re-sync the reference strings if needed. */
|
| 419 |
+
/* if the sync passes, the state is modified to dependent in the */
|
| 420 |
+
/* words skipped to for re-synchronization. */
|
| 421 |
+
/**********************************************************************/
|
| 422 |
+
void test_comp_sents(PATH *snt1, PATH *snt2, SEG ***seg_l, int *num_seg, int *max_seg, int min_good)
|
| 423 |
+
{
|
| 424 |
+
int ind1=0, ind2=0, eog1, eog2, state, num_good=0, dbg = 0;
|
| 425 |
+
|
| 426 |
+
eog1 = eog2 = 0;
|
| 427 |
+
state = 'b';
|
| 428 |
+
|
| 429 |
+
if (dbg){
|
| 430 |
+
printf("--------------------------------------------------\n");
|
| 431 |
+
printf(" number of adjacent good words %d\n\n",min_good);
|
| 432 |
+
PATH_print(snt1,stdout,100);
|
| 433 |
+
PATH_print(snt2,stdout,100);
|
| 434 |
+
}
|
| 435 |
+
while (ind1 < snt1->num){
|
| 436 |
+
if (dbg) printf("top of loop: state: %c ind1=%d ind2=%d\n",
|
| 437 |
+
state,ind1,ind2);
|
| 438 |
+
/* if either sent has an insertion mark it and goto state 'e' */
|
| 439 |
+
while ((ind1 < snt1->num) && snt1->pset[ind1].eval == P_INS)
|
| 440 |
+
ind1++, state = 'e';
|
| 441 |
+
while ((ind2 < snt2->num) && snt2->pset[ind2].eval == P_INS)
|
| 442 |
+
ind2++, state = 'e';
|
| 443 |
+
if (dbg) printf(" rm insert: state: %c ind1=%d ind2=%d\n",
|
| 444 |
+
state,ind1,ind2);
|
| 445 |
+
/* Check to see if there is a synchony error, and fix it ONLY */
|
| 446 |
+
/* if the evaluation of the words are different */
|
| 447 |
+
if (((ind1 < snt1->num && snt1->pset[ind1].a_ptr == NULL) ^
|
| 448 |
+
(ind2 < snt2->num && snt2->pset[ind2].a_ptr == NULL)) ||
|
| 449 |
+
((ind1 < snt1->num && ind2 < snt2->num) &&
|
| 450 |
+
(strcmp(snt1->pset[ind1].a_ptr,snt2->pset[ind2].a_ptr) != 0) &&
|
| 451 |
+
(snt1->pset[ind1].eval != snt2->pset[ind2].eval))){
|
| 452 |
+
|
| 453 |
+
int i1=ind1, i2=ind2, synched=FALSE;
|
| 454 |
+
if (dbg) printf(" Warning: Reference words out of alignment\n");
|
| 455 |
+
if (dbg) printf(" Attempting to correct\n");
|
| 456 |
+
/* the algorithm: trace the following network in a depth first */
|
| 457 |
+
/* manner until the first synchronization occurs: */
|
| 458 |
+
/* Where A1 is the ref word s_ref_wrd(snt1,i1) . . . */
|
| 459 |
+
/* A1 A2 A3 A4 || A1 A2 A3 A4 || A1 A2 A3 A4 */
|
| 460 |
+
/* | \ || /| \ || ____//| \ */
|
| 461 |
+
/* | \ || / | \ || / / | \ */
|
| 462 |
+
/* B1 B2 B3 B4 || B1 B2 B3 B4 || B1 B2 B3 B4 */
|
| 463 |
+
while (i1 < snt1->num && !synched){
|
| 464 |
+
if (dbg) printf(" Starting at %d - %d\n",i1,i2);
|
| 465 |
+
while (i2 < snt2->num &&
|
| 466 |
+
(i2 <= (ind2+1+(i1-ind1))) && !synched){
|
| 467 |
+
if (dbg) printf(" compare %d to %d ",i1,i2);
|
| 468 |
+
if (strcmp(snt1->pset[i1].a_ptr,snt2->pset[i2].a_ptr) != 0)
|
| 469 |
+
synched = TRUE;
|
| 470 |
+
if (!synched) {
|
| 471 |
+
if (dbg) printf("Not synched\n");
|
| 472 |
+
i2++;
|
| 473 |
+
} else
|
| 474 |
+
if (dbg) printf("Synched\n");
|
| 475 |
+
}
|
| 476 |
+
if (!synched)
|
| 477 |
+
i1++;
|
| 478 |
+
}
|
| 479 |
+
if (!synched) {
|
| 480 |
+
if (dbg) printf(" I FAILED to synchronize, I'm sorry\n");
|
| 481 |
+
} else {
|
| 482 |
+
char tstate = state;
|
| 483 |
+
int ii1, ii2;
|
| 484 |
+
for (ii1 = ind1; ii1 <= i1; ii1++)
|
| 485 |
+
if (snt1->pset[ii1].eval != P_CORR) state = 'e';
|
| 486 |
+
for (ii2 = ind2; ii2 <= i2; ii2++)
|
| 487 |
+
if (snt2->pset[ii2].eval != P_CORR) state = 'e';
|
| 488 |
+
ind1 = i1; ind2 = i2;
|
| 489 |
+
if (dbg) {
|
| 490 |
+
printf(" Synch WORKED, at %d - %d\n",ind1,ind2);
|
| 491 |
+
printf(" State was '%c' now '%c'\n",tstate,state);
|
| 492 |
+
}
|
| 493 |
+
}
|
| 494 |
+
}
|
| 495 |
+
switch (state){
|
| 496 |
+
case 'b':
|
| 497 |
+
/* this state means we haven't found any errors yet */
|
| 498 |
+
/* if both corr, mark the end of the good(eog) for each sent*/
|
| 499 |
+
if (ind1 < snt1->num && snt1->pset[ind1].eval == P_CORR &&
|
| 500 |
+
ind2 < snt2->num && snt2->pset[ind2].eval == P_CORR)
|
| 501 |
+
eog1 = ind1, eog2 = ind2;
|
| 502 |
+
else
|
| 503 |
+
state = 'e';
|
| 504 |
+
break;
|
| 505 |
+
case 'e':
|
| 506 |
+
/* if both are correct, then check to see if the num_good */
|
| 507 |
+
/* equals the minimum if it is mark the seg and goto 'b' */
|
| 508 |
+
if (ind1 < snt1->num && snt1->pset[ind1].eval == P_CORR &&
|
| 509 |
+
ind2 < snt2->num && snt2->pset[ind2].eval == P_CORR) {
|
| 510 |
+
num_good = 1;
|
| 511 |
+
if (num_good == min_good){
|
| 512 |
+
if (dbg) printf(" segment: snt1:%d-%d snt2:%d-%d\n",
|
| 513 |
+
eog1-(min_good-1),ind1,eog2-(min_good-1),ind2);
|
| 514 |
+
count_seg(snt1,snt2,eog1-(min_good-1),
|
| 515 |
+
eog2-(min_good-1),ind1,ind2,
|
| 516 |
+
seg_l, num_seg, max_seg, dbg);
|
| 517 |
+
eog1 = ind1, eog2 = ind2, state = 'b';
|
| 518 |
+
}
|
| 519 |
+
else
|
| 520 |
+
state = 'g';
|
| 521 |
+
}
|
| 522 |
+
break;
|
| 523 |
+
case 'g':
|
| 524 |
+
/* count the good words until the minimum number is found*/
|
| 525 |
+
if (ind1 < snt1->num && snt1->pset[ind1].eval == P_CORR &&
|
| 526 |
+
ind2 < snt2->num && snt2->pset[ind2].eval == P_CORR){
|
| 527 |
+
num_good++;
|
| 528 |
+
if (num_good == min_good){
|
| 529 |
+
if (dbg) {
|
| 530 |
+
printf(" segment: snt1:%d-%d snt2:%d-%d\n",
|
| 531 |
+
eog1-(min_good-1),ind1,eog2-(min_good-1),ind2);
|
| 532 |
+
}
|
| 533 |
+
count_seg(snt1,snt2,eog1-(min_good-1),
|
| 534 |
+
eog2-(min_good-1),ind1,ind2,seg_l,num_seg,
|
| 535 |
+
max_seg,dbg);
|
| 536 |
+
eog1 = ind1, eog2 = ind2, state = 'b';
|
| 537 |
+
}
|
| 538 |
+
else
|
| 539 |
+
state = 'g';
|
| 540 |
+
}
|
| 541 |
+
/* an error was found before the num_good == min_good */
|
| 542 |
+
else
|
| 543 |
+
state = 'e';
|
| 544 |
+
break;
|
| 545 |
+
}
|
| 546 |
+
|
| 547 |
+
if (ind1 < snt1->num) ind1++;
|
| 548 |
+
if (ind2 < snt2->num) ind2++;
|
| 549 |
+
if (dbg) printf("end of loop: state: %c ind1=%d ind2=%d\n\n",state,ind1,ind2);
|
| 550 |
+
}
|
| 551 |
+
if (dbg) printf( "outsid loop: state: %c ind1=%d ind2=%d\n\n",state,ind1,ind2);
|
| 552 |
+
/* if the state is anything but 'b' then the end of the sentence ends */
|
| 553 |
+
/* the segment */
|
| 554 |
+
if (state != 'b' || (state == 'b' && snt2->num > ind2)){
|
| 555 |
+
if (dbg) {
|
| 556 |
+
printf(" segment: snt1:%d-%d snt2:%d-%d\n",
|
| 557 |
+
eog1-(min_good-1),snt1->num-1,eog2-(min_good-1),snt2->num-1);
|
| 558 |
+
}
|
| 559 |
+
count_seg(snt1,snt2,eog1-(min_good-1), eog2-(min_good-1),snt1->num-1,
|
| 560 |
+
snt2->num-1,seg_l,num_seg,max_seg,dbg);
|
| 561 |
+
}
|
| 562 |
+
}
|
| 563 |
+
|
| 564 |
+
/**********************************************************************/
|
| 565 |
+
/* this procedure only stores the errors and reference words in */
|
| 566 |
+
/* the segment then it stores the info in a list for segments */
|
| 567 |
+
/**********************************************************************/
|
| 568 |
+
void count_seg(PATH *snt1, PATH *snt2, int beg1, int beg2, int end1, int end2, SEG ***seg_l, int *num_seg, int *max_seg, int dbg)
|
| 569 |
+
{
|
| 570 |
+
/* static char *ref_str=NULL, **hyp_strs;*/
|
| 571 |
+
int err1, err2, ref1, ref2;
|
| 572 |
+
|
| 573 |
+
/* do bounds checking, if indexes are < 0 */
|
| 574 |
+
if (beg1 < 0) beg1 = 0;
|
| 575 |
+
if (beg2 < 0) beg2 = 0;
|
| 576 |
+
|
| 577 |
+
if (*num_seg >= *max_seg)
|
| 578 |
+
expand_SEG_LIST(*seg_l,*num_seg,*max_seg);
|
| 579 |
+
|
| 580 |
+
seg_count(snt1,beg1,end1,&err1,&ref1);
|
| 581 |
+
seg_count(snt2,beg2,end2,&err2,&ref2);
|
| 582 |
+
|
| 583 |
+
seg_ref((*seg_l),*num_seg) = (ref1 + ref2)/2;
|
| 584 |
+
seg_hyp1((*seg_l),*num_seg) = err1;
|
| 585 |
+
seg_hyp2((*seg_l),*num_seg) = err2;
|
| 586 |
+
|
| 587 |
+
if (dbg)
|
| 588 |
+
printf("Count Segment: segment# %3d: sys1=[beg=%d,end=%d,ref=%d,err=%d] sys2=[beg=%d,end=%d,ref=%d,err=%d]\n",
|
| 589 |
+
*num_seg,beg1,end1,ref1,err1,beg2,end2,ref2,err2);
|
| 590 |
+
|
| 591 |
+
if (err1 == 0 && err2 == 0){
|
| 592 |
+
fprintf(scfp,"Warning: MAPSSWE segmentation produced a segment with"
|
| 593 |
+
" errors\n ignoring segment\n");
|
| 594 |
+
}
|
| 595 |
+
|
| 596 |
+
/* print the sentence segments to stdout */
|
| 597 |
+
if (dbg){
|
| 598 |
+
if (ref1 != ref2){
|
| 599 |
+
printf("***** Reference Counts Not Equal\n");
|
| 600 |
+
printf("Segment# %3d: #ref %1d (%d+%d)/2\n",
|
| 601 |
+
*num_seg,(ref1+ref2)/2,ref1,ref2);
|
| 602 |
+
} else
|
| 603 |
+
printf("Segment# %3d: #ref %1d\n",*num_seg,ref1);
|
| 604 |
+
|
| 605 |
+
printf(" #Err. %2d\n",err1);
|
| 606 |
+
PATH_n_print(snt1, stdout, beg1, end1+1, 100);
|
| 607 |
+
|
| 608 |
+
printf(" #Err. %2d\n",err2);
|
| 609 |
+
PATH_n_print(snt2, stdout, beg2, end2+1, 100);
|
| 610 |
+
printf("\n\n");
|
| 611 |
+
}
|
| 612 |
+
if (! (err1 == 0 && err2 == 0))
|
| 613 |
+
(*num_seg)++;
|
| 614 |
+
}
|
| 615 |
+
|
| 616 |
+
/**********************************************************************/
|
| 617 |
+
/* this routine counts the errors and ref words in a segment */
|
| 618 |
+
/**********************************************************************/
|
| 619 |
+
void seg_count(PATH *snt, int from, int to, int *err, int *ref)
|
| 620 |
+
{
|
| 621 |
+
int i;
|
| 622 |
+
|
| 623 |
+
*err = *ref = 0;
|
| 624 |
+
for (i=from;i<= to;i++){
|
| 625 |
+
if (snt->pset[i].eval != P_CORR)
|
| 626 |
+
(*err)++;
|
| 627 |
+
if (snt->pset[i].eval != P_INS)
|
| 628 |
+
(*ref)++;
|
| 629 |
+
}
|
| 630 |
+
}
|
| 631 |
+
|
| 632 |
+
/**********************************************************************/
|
| 633 |
+
/* when the average segment analysis is ran, this procedure prints */
|
| 634 |
+
/* the report, for each number of minimum good words. this report */
|
| 635 |
+
/* prints the average number of segments per sentence for each */
|
| 636 |
+
/* number of buffer words (min_good) */
|
| 637 |
+
/**********************************************************************/
|
| 638 |
+
void print_sent_seg_averaged_analysis(SCORES *scor[], int nscor, double ***seg_per_sent, char *tname)
|
| 639 |
+
{
|
| 640 |
+
int sys1,sys2,num_g,num_comp;
|
| 641 |
+
double tot_sps;
|
| 642 |
+
char pad[FULL_SCREEN];
|
| 643 |
+
char *sub_title="Average Number of Segments Per Sentence Report for";
|
| 644 |
+
char *sub_title1="Changing Numbers of Buffer Words";
|
| 645 |
+
|
| 646 |
+
set_pad_cent_n(pad,strlen(sub_title), FULL_SCREEN);
|
| 647 |
+
printf("%s%s\n",pad,sub_title);
|
| 648 |
+
set_pad_cent_n(pad,strlen(sub_title1), FULL_SCREEN);
|
| 649 |
+
printf("%s%s\n",pad,sub_title1);
|
| 650 |
+
if (*tname != '\0'){
|
| 651 |
+
set_pad(pad,tname, FULL_SCREEN);
|
| 652 |
+
printf("%s%s\n",pad,tname);
|
| 653 |
+
}
|
| 654 |
+
printf("\n\n");
|
| 655 |
+
|
| 656 |
+
set_pad(pad,"--------------------------------", FULL_SCREEN);
|
| 657 |
+
printf("%s--------------------------------\n",pad);
|
| 658 |
+
printf("%s| Num Buf | Ave Seg/Sent |\n",pad);
|
| 659 |
+
printf("%s|-------------+----------------|\n",pad);
|
| 660 |
+
for (num_g=0; num_g<MAX_SEG_ANAL; num_g++){
|
| 661 |
+
num_comp = tot_sps = 0;
|
| 662 |
+
for (sys1=0;sys1<nscor;sys1++)
|
| 663 |
+
for (sys2=sys1+1;sys2<nscor;sys2++)
|
| 664 |
+
num_comp++, tot_sps+= seg_per_sent[num_g][sys1][sys2];
|
| 665 |
+
printf("%s| %2d | %5.3f |\n",
|
| 666 |
+
pad,num_g+1,(tot_sps/num_comp));
|
| 667 |
+
}
|
| 668 |
+
printf("%s--------------------------------\n",pad);
|
| 669 |
+
form_feed(stdout);
|
| 670 |
+
}
|
| 671 |
+
|
| 672 |
+
/**********************************************************************/
|
| 673 |
+
/* when the long segment analysis is ran, this procedure prints */
|
| 674 |
+
/* the report, for each number of minimum good words. this report */
|
| 675 |
+
/* prints the number of segments per sentence for each system */
|
| 676 |
+
/* by system comparison */
|
| 677 |
+
/**********************************************************************/
|
| 678 |
+
void print_sent_seg_long_analysis(SCORES *scor[], int nscor, double ***seg_per_sent, char *tname)
|
| 679 |
+
{
|
| 680 |
+
int i,j,k;
|
| 681 |
+
char pad[FULL_SCREEN];
|
| 682 |
+
char *sub_title="Number of Segments Per Sentence Report for Changing";
|
| 683 |
+
char *sub_title1="Numbers of Buffer Words";
|
| 684 |
+
|
| 685 |
+
set_pad_cent_n(pad,strlen(sub_title), FULL_SCREEN);
|
| 686 |
+
printf("%s%s\n",pad,sub_title);
|
| 687 |
+
set_pad_cent_n(pad,strlen(sub_title1), FULL_SCREEN);
|
| 688 |
+
printf("%s%s\n",pad,sub_title1);
|
| 689 |
+
if (*tname != '\0'){
|
| 690 |
+
set_pad(pad,tname, FULL_SCREEN);
|
| 691 |
+
printf("%s%s\n",pad,tname);
|
| 692 |
+
}
|
| 693 |
+
printf("\n");
|
| 694 |
+
|
| 695 |
+
set_pad_cent_n(pad,(nscor+1) * 15, FULL_SCREEN);
|
| 696 |
+
printf("\n%s|-------------",pad);
|
| 697 |
+
for (k=0;k<nscor;k++)
|
| 698 |
+
printf("%13s","--------------");
|
| 699 |
+
printf("|\n");
|
| 700 |
+
|
| 701 |
+
printf("%s| |",pad);
|
| 702 |
+
for (i=0;i<nscor;i++)
|
| 703 |
+
printf(" %4s |",scor[i]->title);
|
| 704 |
+
printf("\n");
|
| 705 |
+
|
| 706 |
+
for (i=0;i<nscor;i++){
|
| 707 |
+
printf("%s|-------------",pad);
|
| 708 |
+
for (k=0;k<nscor;k++)
|
| 709 |
+
printf("+-------------");
|
| 710 |
+
printf("|\n");
|
| 711 |
+
printf("%s| %4s 0 |",pad,scor[i]->title);
|
| 712 |
+
for (j=0;j<nscor;j++)
|
| 713 |
+
if (j > i)
|
| 714 |
+
printf(" %5.3f |",seg_per_sent[0][i][j]);
|
| 715 |
+
else
|
| 716 |
+
printf(" |");
|
| 717 |
+
printf("\n");
|
| 718 |
+
if (MAX_SEG_ANAL >=2)
|
| 719 |
+
for (k=1; k<MAX_SEG_ANAL; k++){
|
| 720 |
+
printf("%s| %2d |",pad,k);
|
| 721 |
+
for (j=0;j<nscor;j++)
|
| 722 |
+
if (j > i)
|
| 723 |
+
printf(" %5.3f |",seg_per_sent[k][i][j]);
|
| 724 |
+
else
|
| 725 |
+
printf(" |");
|
| 726 |
+
printf("\n");
|
| 727 |
+
}
|
| 728 |
+
}
|
| 729 |
+
printf("%s|-------------",pad);
|
| 730 |
+
for (k=0;k<nscor;k++)
|
| 731 |
+
printf("%11s","--------------");
|
| 732 |
+
printf("|\n");
|
| 733 |
+
form_feed(stdout);
|
| 734 |
+
}
|
| 735 |
+
|
| 736 |
+
/**********************************************************************/
|
| 737 |
+
/* this procedure prints the Matched pairs report for a single */
|
| 738 |
+
/* min_num_good length. */
|
| 739 |
+
/**********************************************************************/
|
| 740 |
+
void print_compare_matrix_for_sys(SCORES *scor[], int nscor, int **winner, char *matrix_name, char *tname, char *v_desc, double **sys1_pct_arr, double **sys2_pct_arr, int **num_seg, double **Z_stat, int min_num_good, FILE *fp)
|
| 741 |
+
{
|
| 742 |
+
int i,j,k,block_size,sys,max_name_len=0;
|
| 743 |
+
int hyphen_len=49, space_len=49;
|
| 744 |
+
char pad[FULL_SCREEN], hyphens[50], spaces[50], sysname_fmt[40];
|
| 745 |
+
char *min_good_title="Minimum Number of Correct Boundary words";
|
| 746 |
+
|
| 747 |
+
/* init the hyphens and spaces array */
|
| 748 |
+
for (i=0; i<hyphen_len; i++){
|
| 749 |
+
hyphens[i]='-';
|
| 750 |
+
spaces[i]=' ';
|
| 751 |
+
}
|
| 752 |
+
hyphens[hyphen_len]='\0'; spaces[space_len]='\0';
|
| 753 |
+
/* find the largest system length */
|
| 754 |
+
for (sys=0;sys<nscor;sys++)
|
| 755 |
+
if ((i=strlen(scor[sys]->title)) > max_name_len)
|
| 756 |
+
max_name_len = i;
|
| 757 |
+
block_size = (3+max_name_len);
|
| 758 |
+
sprintf(sysname_fmt," %%%ds |",max_name_len);
|
| 759 |
+
|
| 760 |
+
set_pad(pad,matrix_name, FULL_SCREEN);
|
| 761 |
+
fprintf(fp,"\n\n\n%s%s\n",pad,matrix_name);
|
| 762 |
+
if (*v_desc != '\0'){
|
| 763 |
+
set_pad(pad,v_desc, FULL_SCREEN);
|
| 764 |
+
fprintf(fp,"%s%s\n",pad,v_desc);
|
| 765 |
+
}
|
| 766 |
+
if (*tname != '\0'){
|
| 767 |
+
|
| 768 |
+
|
| 769 |
+
set_pad(pad,tname, FULL_SCREEN);
|
| 770 |
+
fprintf(fp,"%s%s\n",pad,tname);
|
| 771 |
+
}
|
| 772 |
+
set_pad_cent_n(pad,strlen(min_good_title)+2, FULL_SCREEN);
|
| 773 |
+
fprintf(fp,"%s%s %1d\n",pad,min_good_title,min_num_good);
|
| 774 |
+
fprintf(fp,"\n");
|
| 775 |
+
|
| 776 |
+
set_pad_cent_n(pad,(nscor+1) * block_size, FULL_SCREEN);
|
| 777 |
+
fprintf(fp,"\n%s|%s",pad,hyphens+hyphen_len-MIN(hyphen_len,(block_size-1)));
|
| 778 |
+
for (k=0;k<nscor;k++)
|
| 779 |
+
fprintf(fp,"%s",hyphens+hyphen_len-MIN(hyphen_len,block_size));
|
| 780 |
+
fprintf(fp,"|\n");
|
| 781 |
+
|
| 782 |
+
fprintf(fp,"%s|%s|",pad,spaces+space_len-MIN(space_len,(block_size-1)));
|
| 783 |
+
for (i=0;i<nscor;i++)
|
| 784 |
+
fprintf(fp,sysname_fmt,scor[i]->title);
|
| 785 |
+
fprintf(fp,"\n");
|
| 786 |
+
|
| 787 |
+
for (i=0;i<nscor;i++){
|
| 788 |
+
fprintf(fp,"%s|%s",pad,hyphens+hyphen_len-MIN(hyphen_len,(block_size-1)));
|
| 789 |
+
for (k=0;k<nscor;k++)
|
| 790 |
+
fprintf(fp,"+%s",hyphens+hyphen_len-MIN(hyphen_len,(block_size-1)));
|
| 791 |
+
fprintf(fp,"|\n");
|
| 792 |
+
fprintf(fp,"%s|",pad);
|
| 793 |
+
fprintf(fp,sysname_fmt,scor[i]->title);
|
| 794 |
+
for (j=0;j<nscor;j++){
|
| 795 |
+
char *name="";
|
| 796 |
+
int t=0;
|
| 797 |
+
if (j > i){
|
| 798 |
+
if (winner[i][j] == TEST_DIFF)
|
| 799 |
+
name=scor[j]->title;
|
| 800 |
+
else if (winner[i][j] == NO_DIFF)
|
| 801 |
+
name="same";
|
| 802 |
+
else
|
| 803 |
+
name=scor[i]->title;
|
| 804 |
+
t = (block_size-1-strlen(name))/2;
|
| 805 |
+
}
|
| 806 |
+
fprintf(fp,"%s%s%s|",spaces+space_len-MIN(space_len,t),name,
|
| 807 |
+
spaces+space_len-MIN(space_len,(block_size-1-strlen(name)-t)));
|
| 808 |
+
}
|
| 809 |
+
fprintf(fp,"\n");
|
| 810 |
+
#ifdef you_want_more_output
|
| 811 |
+
fprintf(fp,"%s| |",pad);
|
| 812 |
+
for (j=0;j<nscor;j++)
|
| 813 |
+
if (j > i)
|
| 814 |
+
fprintf(fp," %3d %6.2f |",num_seg[i][j],Z_stat[i][j]);
|
| 815 |
+
else
|
| 816 |
+
fprintf(fp," |");
|
| 817 |
+
fprintf(fp,"\n");
|
| 818 |
+
fprintf(fp,"%s| |",pad);
|
| 819 |
+
for (j=0;j<nscor;j++)
|
| 820 |
+
if (j > i)
|
| 821 |
+
fprintf(fp," %4.1f%% %4.1f%% |",sys1_pct_arr[i][j],
|
| 822 |
+
sys2_pct_arr[i][j]);
|
| 823 |
+
else
|
| 824 |
+
fprintf(fp," |");
|
| 825 |
+
fprintf(fp,"\n");
|
| 826 |
+
#endif
|
| 827 |
+
}
|
| 828 |
+
fprintf(fp,"%s|%s",pad,hyphens+hyphen_len-MIN(hyphen_len,(block_size-1)));
|
| 829 |
+
for (k=0;k<nscor;k++)
|
| 830 |
+
fprintf(fp,"%s",hyphens+hyphen_len-MIN(hyphen_len,block_size));
|
| 831 |
+
fprintf(fp,"|\n");
|
| 832 |
+
}
|
| 833 |
+
|
SCTK/src/sclite/net_adt.o
ADDED
|
Binary file (43.1 kB). View file
|
|
|
SCTK/src/sclite/order.c
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**********************************************************************/
|
| 2 |
+
/* */
|
| 3 |
+
/* FILENAME: order.c */
|
| 4 |
+
/* BY: Jonathan G. Fiscus */
|
| 5 |
+
/* NATIONAL INSTITUTE OF STANDARDS AND TECHNOLOGY */
|
| 6 |
+
/* SPEECH RECOGNITION GROUP */
|
| 7 |
+
/* */
|
| 8 |
+
/* DESC: this file contains routines to sort and rank */
|
| 9 |
+
/* various types of numeric arrays in INCREASING */
|
| 10 |
+
/* of DECREASING order */
|
| 11 |
+
/* */
|
| 12 |
+
/**********************************************************************/
|
| 13 |
+
#include "sctk.h"
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
/**********************************************************************/
|
| 17 |
+
/* qsort short comparison functions */
|
| 18 |
+
int qsort_short_cmp(const void *p, const void *p1);
|
| 19 |
+
|
| 20 |
+
int qsort_short_deccmp(const void *p, const void *p1);
|
| 21 |
+
|
| 22 |
+
static short *short_cmp_arr;
|
| 23 |
+
int qsort_short_cmp(const void *p, const void *p1){
|
| 24 |
+
return(short_cmp_arr[*((int *)p)] - short_cmp_arr[*((int *)p1)]);
|
| 25 |
+
}
|
| 26 |
+
int qsort_short_deccmp(const void *p, const void *p1){
|
| 27 |
+
return(short_cmp_arr[*((int *)p1)] - short_cmp_arr[*((int *)p)]);
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
/**********************************************************************/
|
| 31 |
+
/* qsort int comparison functions */
|
| 32 |
+
int qsort_int_cmp(const void *p, const void *p1);
|
| 33 |
+
int qsort_int_deccmp(const void *p, const void *p1);
|
| 34 |
+
|
| 35 |
+
static int *int_cmp_arr;
|
| 36 |
+
int qsort_int_cmp(const void *p, const void *p1){
|
| 37 |
+
return(int_cmp_arr[*((int *)p)] - int_cmp_arr[*((int *)p1)]);
|
| 38 |
+
}
|
| 39 |
+
int qsort_int_deccmp(const void *p, const void *p1){
|
| 40 |
+
return(int_cmp_arr[*((int *)p1)] - int_cmp_arr[*((int *)p)]);
|
| 41 |
+
}
|
| 42 |
+
int qsort_int_compare(const void *i, const void *j) {
|
| 43 |
+
return(*((int *)i) - *((int *)j));
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
/**********************************************************************/
|
| 50 |
+
/* qsort double comparison functions */
|
| 51 |
+
int qsort_double_cmp(const void *p, const void *p1);
|
| 52 |
+
int qsort_double_deccmp(const void *p, const void *p1);
|
| 53 |
+
|
| 54 |
+
static double *double_cmp_arr;
|
| 55 |
+
int qsort_double_cmp(const void *p, const void *p1){
|
| 56 |
+
double f = double_cmp_arr[*((int *)p)] - double_cmp_arr[*((int *)p1)];
|
| 57 |
+
return((f < 0.0) ? -1 : ((f > 0) ? 1 : 0));
|
| 58 |
+
}
|
| 59 |
+
int qsort_double_deccmp(const void *p, const void *p1){
|
| 60 |
+
double f = double_cmp_arr[*((int *)p1)] - double_cmp_arr[*((int *)p)];
|
| 61 |
+
return((f < 0.0) ? -1 : ((f > 0) ? 1 : 0));
|
| 62 |
+
}
|
| 63 |
+
int qsort_double_compare(const void *i, const void *j) {
|
| 64 |
+
double f = *((double *)i) - *((double *)j);
|
| 65 |
+
return((f < 0.0) ? -1 : ((f > 0) ? 1 : 0));
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
/**********************************************************************/
|
| 69 |
+
/* Sort a short array */
|
| 70 |
+
/* arr -> the short array */
|
| 71 |
+
/* ptr_arr -> an integer array of indexes into arr. */
|
| 72 |
+
/* using this array to index arr, sorts the arr */
|
| 73 |
+
/**********************************************************************/
|
| 74 |
+
void sort_short_arr(short int *arr, int num, int *ptr_arr, int order)
|
| 75 |
+
{
|
| 76 |
+
int j;
|
| 77 |
+
/* init the indexes to 1-n */
|
| 78 |
+
for (j=0;j<num;j++)
|
| 79 |
+
ptr_arr[j] = j;
|
| 80 |
+
|
| 81 |
+
short_cmp_arr = arr;
|
| 82 |
+
if (order == INCREASING)
|
| 83 |
+
qsort((void *)ptr_arr,num,sizeof(int),qsort_short_cmp);
|
| 84 |
+
else
|
| 85 |
+
qsort((void *)ptr_arr,num,sizeof(int),qsort_short_deccmp);
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
/**********************************************************************/
|
| 90 |
+
/* Sort a double array */
|
| 91 |
+
/* arr -> the double array */
|
| 92 |
+
/* ptr_arr -> an integer array of indexes into arr. */
|
| 93 |
+
/* using this array to index arr, sorts the arr */
|
| 94 |
+
/**********************************************************************/
|
| 95 |
+
void sort_double_arr(double *arr, int num, int *ptr_arr, int order)
|
| 96 |
+
{
|
| 97 |
+
int j;
|
| 98 |
+
/* init the indexes to 1-n */
|
| 99 |
+
for (j=0;j<num;j++)
|
| 100 |
+
ptr_arr[j] = j;
|
| 101 |
+
|
| 102 |
+
double_cmp_arr = arr;
|
| 103 |
+
if (order == INCREASING)
|
| 104 |
+
qsort((void *)ptr_arr,num,sizeof(int),qsort_double_cmp);
|
| 105 |
+
else
|
| 106 |
+
qsort((void *)ptr_arr,num,sizeof(int),qsort_double_deccmp);
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
/**********************************************************************/
|
| 110 |
+
/* Sort a int array */
|
| 111 |
+
/* arr -> the int array */
|
| 112 |
+
/* ptr_arr -> an integer array of indexes into arr. */
|
| 113 |
+
/* using this array to index arr, sorts the arr */
|
| 114 |
+
/**********************************************************************/
|
| 115 |
+
void sort_int_arr(int *arr, int num, int *ptr_arr, int order)
|
| 116 |
+
{
|
| 117 |
+
int j;
|
| 118 |
+
/* init the indexes to 1-n */
|
| 119 |
+
for (j=0;j<num;j++)
|
| 120 |
+
ptr_arr[j] = j;
|
| 121 |
+
|
| 122 |
+
int_cmp_arr = arr;
|
| 123 |
+
if (order == INCREASING)
|
| 124 |
+
qsort((void *)ptr_arr,num,sizeof(int),qsort_int_cmp);
|
| 125 |
+
else
|
| 126 |
+
qsort((void *)ptr_arr,num,sizeof(int),qsort_int_deccmp);
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
/**********************************************************************/
|
| 130 |
+
/* Sort an array strings. to access the results, a double */
|
| 131 |
+
/* indirection is needed. */
|
| 132 |
+
/* arr -> the 2 dimarr of chars */
|
| 133 |
+
/**********************************************************************/
|
| 134 |
+
void sort_strings_using_index(char **arr, int *ind, int num, int order)
|
| 135 |
+
{
|
| 136 |
+
int i, j, tmp;
|
| 137 |
+
|
| 138 |
+
for (i=0;i<num;i++)
|
| 139 |
+
ind[i] = i;
|
| 140 |
+
|
| 141 |
+
if (order == DECREASING){
|
| 142 |
+
for (j=num;j>0;j--){
|
| 143 |
+
for (i=0;i<j-1;i++)
|
| 144 |
+
if (strcmp(arr[ind[i]],arr[ind[i+1]]) < 0){
|
| 145 |
+
tmp = ind[i];
|
| 146 |
+
ind[i] = ind[i+1];
|
| 147 |
+
ind[i+1] = tmp;
|
| 148 |
+
}
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
else{
|
| 152 |
+
for (j=num;j>0;j--)
|
| 153 |
+
for (i=0;i<j-1;i++)
|
| 154 |
+
if (strcmp(arr[ind[i]],arr[ind[i+1]]) > 0){
|
| 155 |
+
tmp = ind[i];
|
| 156 |
+
ind[i] = ind[i+1];
|
| 157 |
+
ind[i+1] = tmp;
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
/* printf("sort debug\n");
|
| 161 |
+
for (i=0;i<num;i++)
|
| 162 |
+
printf(" %d arr[%d]-> %s \n",i,ind[i],arr[ind[i]]);*/
|
| 163 |
+
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
/**********************************************************************/
|
| 167 |
+
/* Sort an array strings in place */
|
| 168 |
+
/* arr -> the 2 dimarr of chars */
|
| 169 |
+
/**********************************************************************/
|
| 170 |
+
void sort_strings_in_place(char **arr, int num, int order)
|
| 171 |
+
{
|
| 172 |
+
int i, j;
|
| 173 |
+
char *tmp;
|
| 174 |
+
|
| 175 |
+
if (order == DECREASING){
|
| 176 |
+
for (j=num;j>0;j--){
|
| 177 |
+
for (i=0;i<j-1;i++)
|
| 178 |
+
if (strcmp(arr[i],arr[i+1]) < 0){
|
| 179 |
+
tmp = arr[i];
|
| 180 |
+
arr[i] = arr[i+1];
|
| 181 |
+
arr[i+1] = tmp;
|
| 182 |
+
}
|
| 183 |
+
}
|
| 184 |
+
}
|
| 185 |
+
else{
|
| 186 |
+
for (j=num;j>0;j--)
|
| 187 |
+
for (i=0;i<j-1;i++)
|
| 188 |
+
if (strcmp(arr[i],arr[i+1]) > 0){
|
| 189 |
+
tmp = arr[i];
|
| 190 |
+
arr[i] = arr[i+1];
|
| 191 |
+
arr[i+1] = tmp;
|
| 192 |
+
}
|
| 193 |
+
}
|
| 194 |
+
/* for (i=0;i<num;i++)
|
| 195 |
+
printf("%s ",arr[i]);
|
| 196 |
+
printf("\n");*/
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
/**********************************************************************/
|
| 200 |
+
/* Sort and rank an integer array */
|
| 201 |
+
/* arr -> the integer array */
|
| 202 |
+
/* ptr_arr -> an integer array of indexes into arr. */
|
| 203 |
+
/* using this array to index arr, sorts the arr */
|
| 204 |
+
/* rank_arr -> an array of mean ranks of the elements in arr */
|
| 205 |
+
/**********************************************************************/
|
| 206 |
+
void rank_int_arr(int *arr, int num, int *ptr_arr, double *rank_arr, int order)
|
| 207 |
+
{
|
| 208 |
+
int i, j, tmp, count;
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
sort_int_arr(arr, num, ptr_arr, order);
|
| 212 |
+
|
| 213 |
+
/* mean rank the short arr */
|
| 214 |
+
/* . . . the average of the ranks for duplicate numbers */
|
| 215 |
+
for (j=0;j<num;j++){
|
| 216 |
+
/* if the next number is = the the current number */
|
| 217 |
+
if ((j<num-1) && (arr[ptr_arr[j]] == arr[ptr_arr[j+1]])){
|
| 218 |
+
/* find the last duplicate number */
|
| 219 |
+
count = j;
|
| 220 |
+
while((count < num-1) &&
|
| 221 |
+
(arr[ptr_arr[count]] == arr[ptr_arr[count+1]])){
|
| 222 |
+
count++;
|
| 223 |
+
}
|
| 224 |
+
/* count the number of duplicates */
|
| 225 |
+
tmp = 0;
|
| 226 |
+
for (i=j;i<count+1;i++)
|
| 227 |
+
tmp+=i;
|
| 228 |
+
/* install the averages in all duplicates */
|
| 229 |
+
for (i=j;i<count+1;i++)
|
| 230 |
+
rank_arr[ptr_arr[i]] = (double)tmp/(double)(count+1-j) + 1.0;
|
| 231 |
+
/* go the the end of the duplicates */
|
| 232 |
+
j=i-1;
|
| 233 |
+
}
|
| 234 |
+
else{
|
| 235 |
+
/* no duplicates, use the index as the rank */
|
| 236 |
+
rank_arr[ptr_arr[j]] = (double)(j+1);
|
| 237 |
+
}
|
| 238 |
+
}
|
| 239 |
+
}
|
| 240 |
+
|
| 241 |
+
/**********************************************************************/
|
| 242 |
+
/* Sort and rank an double array */
|
| 243 |
+
/* arr -> the double array */
|
| 244 |
+
/* ptr_arr -> an integer array of indexes into arr. */
|
| 245 |
+
/* using this array to index arr, sorts the arr */
|
| 246 |
+
/* rank_arr -> an array of mean ranks of the elements in arr */
|
| 247 |
+
/* */
|
| 248 |
+
/* *** for comments, look up at sort_int_arr */
|
| 249 |
+
/* */
|
| 250 |
+
/**********************************************************************/
|
| 251 |
+
void rank_double_arr(double *arr, int num, int *ptr_arr, double *rank_arr, int order)
|
| 252 |
+
{
|
| 253 |
+
int i, j, tmp, count;
|
| 254 |
+
|
| 255 |
+
sort_double_arr(arr, num, ptr_arr, order);
|
| 256 |
+
|
| 257 |
+
for (j=0;j<num;j++){
|
| 258 |
+
if ((j<num-1) && (arr[ptr_arr[j]] == arr[ptr_arr[j+1]])){
|
| 259 |
+
count = j;
|
| 260 |
+
while((count < num-1) &&
|
| 261 |
+
(arr[ptr_arr[count]] == arr[ptr_arr[count+1]])){
|
| 262 |
+
count++;
|
| 263 |
+
}
|
| 264 |
+
tmp = 0;
|
| 265 |
+
for (i=j;i<count+1;i++)
|
| 266 |
+
tmp+=i;
|
| 267 |
+
for (i=j;i<count+1;i++)
|
| 268 |
+
rank_arr[ptr_arr[i]] = (double)tmp/(double)(count+1-j) + 1.0;
|
| 269 |
+
j=i-1;
|
| 270 |
+
}
|
| 271 |
+
else{
|
| 272 |
+
rank_arr[ptr_arr[j]] = (double)(j+1);
|
| 273 |
+
}
|
| 274 |
+
}
|
| 275 |
+
}
|
| 276 |
+
|
| 277 |
+
|
SCTK/src/sclite/order.o
ADDED
|
Binary file (4.88 kB). View file
|
|
|
SCTK/src/sclite/pad.h
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
void init_pad_util PROTO((int pr_width)) ;
|
| 2 |
+
int pad_pr_width PROTO((void)) ;
|
| 3 |
+
void set_pad PROTO((char *pad, char *str, int max)) ;
|
| 4 |
+
void set_pad_n PROTO((char *pad, int n, int max)) ;
|
| 5 |
+
void set_pad_cent_n PROTO((char *pad, int len, int max)) ;
|
| 6 |
+
char *center PROTO((char *str, int len)) ;
|
| 7 |
+
void strncpy_pad PROTO((char *to, char *from, int len, int max, char chr)) ;
|
SCTK/src/sclite/sclite.c
ADDED
|
@@ -0,0 +1,764 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
#define MAIN
|
| 3 |
+
#include "sctk.h"
|
| 4 |
+
|
| 5 |
+
#define SCLITE_VERSION "2.10"
|
| 6 |
+
|
| 7 |
+
void do_exit(char *desc, char *prog, int ret);
|
| 8 |
+
void proc_args(int argc, char **argv, char *prog, char **rname, char **rfmt, char **hname, char **hfmt, int *nhyps, enum id_types *id_type, int *case_sens, int *outputs, char **title, int *feedback, int *linewidth, int *use_diff, char **out_dir, char **out_name,int *char_align, int *pipeout, int *pipein, int *infered_wordseg, char **lexicon, int *frag_correct, int *opt_del, int *inf_flags, int *stm2ctm_reduce, int *time_align, int *conf_outputs, int *left_to_right, char **wwl_file, char **lm_file);
|
| 9 |
+
int TEXT_set_lang_prof(char *lprof);
|
| 10 |
+
|
| 11 |
+
#define OUT_SUM 0x0001
|
| 12 |
+
#define OUT_RSUM 0x0002
|
| 13 |
+
#define OUT_PRALIGN 0x0004
|
| 14 |
+
#define OUT_LUR 0x0008
|
| 15 |
+
#define OUT_SGML 0x0010
|
| 16 |
+
#define OUT_STDOUT 0x0020
|
| 17 |
+
#define OUT_SENT 0x0040
|
| 18 |
+
#define OUT_SPKR 0x0080
|
| 19 |
+
#define OUT_DTL 0x0100
|
| 20 |
+
#define OUT_PRALIGN_FULL 0x0200
|
| 21 |
+
#define OUT_WWS 0x0400
|
| 22 |
+
#define OUT_NL_SGML 0x0800
|
| 23 |
+
|
| 24 |
+
#define CONF_OUT_NONE 0x0000
|
| 25 |
+
#define CONF_OUT_DET 0x0001
|
| 26 |
+
#define CONF_OUT_BHIST 0x0002
|
| 27 |
+
#define CONF_OUT_HIST 0x0004
|
| 28 |
+
#define CONF_OUT_SBHIST 0x0008
|
| 29 |
+
|
| 30 |
+
#define REDUCE_NOTHING 0x0000
|
| 31 |
+
#define REDUCE_REF_SEGMENTS 0x0001
|
| 32 |
+
#define REDUCE_HYP_WORDS 0x0002
|
| 33 |
+
|
| 34 |
+
char *usage = "%s: <OPTIONS>\n"
|
| 35 |
+
"sclite Version: " SCLITE_VERSION ", SCTK Version: " TK_VERSION "\n"
|
| 36 |
+
"Input Options:\n"
|
| 37 |
+
" -r reffile [ <rfmt> ]\n"
|
| 38 |
+
" Define the reference file, and it's format\n"
|
| 39 |
+
" -h hypfile [ <hfmt> <title> ]\n"
|
| 40 |
+
" Define the hypothesis file, it's format, and a 'title' used\n"
|
| 41 |
+
" for reports. The default title is 'hypfile'. This option\n"
|
| 42 |
+
" may be used more than once.\n"
|
| 43 |
+
" -i <ids> Set the utterance id type. (for transcript mode only)\n"
|
| 44 |
+
" -P Accept the piped input from another utility.\n"
|
| 45 |
+
" -e gb|euc|utf-8 [ case-conversion-localization ]\n"
|
| 46 |
+
" Interpret characters as GB, EUC, utf-8, or the default, 8-bit ASCII.\n"
|
| 47 |
+
" Optionally, case conversion localization can be set to either 'generic',\n"
|
| 48 |
+
" 'babel_turkish', or 'babel_vietnamese', 'ukranian'\n"
|
| 49 |
+
"Alignment Options:\n"
|
| 50 |
+
" -s Do Case-sensitive alignments.\n"
|
| 51 |
+
" -d Use GNU diff for alignments.\n"
|
| 52 |
+
" -c [ NOASCII DH ]\n"
|
| 53 |
+
" Do the alignment on characters not on words as usual by split-\n"
|
| 54 |
+
" ting words into chars. The optional argument NOASCII does not\n"
|
| 55 |
+
" split ASCII words and the optional arg. DH deletes hyphens from\n"
|
| 56 |
+
" both the ref and hyp before alingment. Exclusive with -d.\n"
|
| 57 |
+
" -L LM CMU-Cambridge SLM Language model file to use in alignment and scoring.\n"
|
| 58 |
+
" -S algo1 lexicon [ ASCIITOO ]\n"
|
| 59 |
+
" -S algo2 lexicon [ ASCIITOO ]\n"
|
| 60 |
+
" Instead of performing word alignments, infer the word segmenta-\n"
|
| 61 |
+
" tion using algo1 or algo2. See sclite(1) for algorithm details.\n"
|
| 62 |
+
" -F Score fragments as correct. Options -F and -d are exclusive.\n"
|
| 63 |
+
" -D Score words marked optionally deletable as correct if deleted.\n"
|
| 64 |
+
" Options -D and -d are exclusive.\n"
|
| 65 |
+
" -T Use time information, (if available), to calculated word-to-\n"
|
| 66 |
+
" word distances based on times. Options -F and -d are exlc.\n"
|
| 67 |
+
" -w wwl Perform Word-Weight Mediated alignments, using the WWL file 'wwl'.\n"
|
| 68 |
+
" IF wwl is 'unity' use weight 1.o for all words.\n"
|
| 69 |
+
" -m [ ref | hyp ]\n"
|
| 70 |
+
" Only used for scoring a hyp/ctm file, against a ref/stm file.\n"
|
| 71 |
+
" When the 'ref' option is used, reduce the reference segments\n"
|
| 72 |
+
" to time range of the hyp file's words. When the 'hyp' option\n"
|
| 73 |
+
" is used, reduce the hyp words to the time range of the ref\n"
|
| 74 |
+
" segments. The two may be used together. The argument -m\n"
|
| 75 |
+
" by itself defaults to '-m ref'. Exclusive with -d.\n"
|
| 76 |
+
"Output Options:\n"
|
| 77 |
+
" -O output_dir\n"
|
| 78 |
+
" Writes all output files into output_dir. Defaults to the\n"
|
| 79 |
+
" hypfile's directory.\n"
|
| 80 |
+
" -f level Defines feedback mode, default is 1\n"
|
| 81 |
+
" -l width Defines the line width.\n"
|
| 82 |
+
" -p Pipe the alignments to another sclite utility. Sets -f to 0.\n"
|
| 83 |
+
"Scoring Report Options:\n"
|
| 84 |
+
" -o [ sum | rsum | pralign | all | sgml | stdout | lur | snt | spk | \n"
|
| 85 |
+
" dtl | prf | wws | nl.sgml | none ]\n"
|
| 86 |
+
" Defines the output reports. Default: 'sum stdout'\n"
|
| 87 |
+
" -C [ det | bhist | sbhist | hist | none ] \n"
|
| 88 |
+
" Defines the output formats for analysis of confidence scores.\n"
|
| 89 |
+
" Default: 'none'\n"
|
| 90 |
+
" -n name Writes all outputs using 'name' as a root filename instead of\n"
|
| 91 |
+
" 'hypfile'. For multiple hypothesis files, the root filename\n"
|
| 92 |
+
" is 'name'.'hypfile'\n";
|
| 93 |
+
|
| 94 |
+
#define MAX_HYPS 40
|
| 95 |
+
|
| 96 |
+
int main(int argc, char **argv){
|
| 97 |
+
char *prog = "sclite";
|
| 98 |
+
char *refname, *hypname[MAX_HYPS], *reffmt, *hypfmt[MAX_HYPS],
|
| 99 |
+
*title[MAX_HYPS];
|
| 100 |
+
char *out_dir, *out_name;
|
| 101 |
+
char *wwl_file;
|
| 102 |
+
enum id_types id_type;
|
| 103 |
+
int errors = 0;
|
| 104 |
+
int num_hyps;
|
| 105 |
+
int linewidth;
|
| 106 |
+
int outputs;
|
| 107 |
+
int conf_outputs;
|
| 108 |
+
int feedback;
|
| 109 |
+
int use_diff;
|
| 110 |
+
SCORES *scor[MAX_HYPS];
|
| 111 |
+
int case_sense, nsc;
|
| 112 |
+
int char_align;
|
| 113 |
+
int pipeout;
|
| 114 |
+
int pipein;
|
| 115 |
+
int num_piped;
|
| 116 |
+
int nh;
|
| 117 |
+
char *hroot;
|
| 118 |
+
int hdirLen = FILENAME_MAX;
|
| 119 |
+
int outrootLen = FILENAME_MAX;
|
| 120 |
+
TEXT *hdir, *outroot;
|
| 121 |
+
int infered_wordseg;
|
| 122 |
+
char *lexicon;
|
| 123 |
+
int frag_correct;
|
| 124 |
+
int opt_del;
|
| 125 |
+
int inf_flags;
|
| 126 |
+
int stm2ctm_reduce;
|
| 127 |
+
int time_align;
|
| 128 |
+
int left_to_right;
|
| 129 |
+
WWL *wwl = (WWL *)0;
|
| 130 |
+
char *lm_file;
|
| 131 |
+
|
| 132 |
+
alloc_singZ(hdir, hdirLen, TEXT, NULL_TEXT);
|
| 133 |
+
alloc_singZ(outroot, outrootLen, TEXT, NULL_TEXT);
|
| 134 |
+
|
| 135 |
+
#ifdef LM_ALIGN
|
| 136 |
+
/* ng_t ng; */
|
| 137 |
+
|
| 138 |
+
#endif
|
| 139 |
+
|
| 140 |
+
db = db_level = 0;
|
| 141 |
+
proc_args(argc, argv, prog, &refname, &reffmt, hypname, hypfmt,
|
| 142 |
+
&num_hyps, &id_type, &case_sense,&outputs,title,&feedback,
|
| 143 |
+
&linewidth,&use_diff,&out_dir,&out_name,&char_align,&pipeout,
|
| 144 |
+
&pipein, &infered_wordseg, &lexicon, &frag_correct, &opt_del,
|
| 145 |
+
&inf_flags, &stm2ctm_reduce, &time_align, &conf_outputs,
|
| 146 |
+
&left_to_right, &wwl_file, &lm_file);
|
| 147 |
+
|
| 148 |
+
if (feedback > 0) printf("sclite: " SCLITE_VERSION
|
| 149 |
+
" TK Version " TK_VERSION"\n");
|
| 150 |
+
|
| 151 |
+
if (pipein){
|
| 152 |
+
if (feedback >= 1) printf("Loading Piped input. . . ");
|
| 153 |
+
num_piped = 0;
|
| 154 |
+
if (!load_SCORES_sgml(stdin,scor,&num_piped,MAX_HYPS)){
|
| 155 |
+
fprintf(scfp,"load_SCORES_sgml Failed\n");
|
| 156 |
+
exit(1);
|
| 157 |
+
}
|
| 158 |
+
if (feedback >= 1) printf("%d systems loaded.\n",num_piped);
|
| 159 |
+
} else
|
| 160 |
+
num_piped = 0;
|
| 161 |
+
|
| 162 |
+
if (wwl_file != (char *)0){
|
| 163 |
+
if (feedback >= 1)
|
| 164 |
+
printf("Loading WWL file '%s'\n",wwl_file);
|
| 165 |
+
if (load_WWL(&wwl,(TEXT *)wwl_file) != 0){
|
| 166 |
+
fprintf(stderr,"Error: Unable to read WWL file '%s'\n",wwl_file);
|
| 167 |
+
exit(1);
|
| 168 |
+
}
|
| 169 |
+
wwl->curw = 0;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
for (nsc=0; nsc<num_hyps + num_piped; nsc++){
|
| 173 |
+
if (nsc >= num_piped){
|
| 174 |
+
nh = nsc - num_piped;
|
| 175 |
+
if (feedback >= 1)
|
| 176 |
+
printf("Begin alignment of Ref File: '%s' and %s: '%s'\n",
|
| 177 |
+
refname, "Hyp File", hypname[nh]);
|
| 178 |
+
|
| 179 |
+
/* Set up the output root name */
|
| 180 |
+
if ((hroot = strrchr(hypname[nh],'/')) != NULL){
|
| 181 |
+
if (hroot-hypname[nh] + 1 > hdirLen){
|
| 182 |
+
expand_singarr_to_size(hdir,(hroot-hypname[nh]),hdirLen,hroot-hypname[nh]+1,TEXT);
|
| 183 |
+
}
|
| 184 |
+
TEXT_strBcpy((TEXT *)hdir,(TEXT *)hypname[nh],hroot-hypname[nh]);
|
| 185 |
+
hroot++;
|
| 186 |
+
} else {
|
| 187 |
+
hroot = hypname[nh];
|
| 188 |
+
TEXT_strcpy(hdir,(TEXT *)".");
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
{ char *name;
|
| 192 |
+
if ((out_dir != (char *)0) ||
|
| 193 |
+
TEXT_strcmp(((out_dir != (char *)0) ? (TEXT *)out_dir : (TEXT *)hdir),(TEXT *)".") != 0)
|
| 194 |
+
name = rsprintf("%s/%s",((out_dir != (char *)0) ? out_dir : (char *)hdir),
|
| 195 |
+
(out_name != (char *)0) ? out_name : hroot);
|
| 196 |
+
else
|
| 197 |
+
name = rsprintf("%s",(out_name != (char *)0) ? out_name : hroot);
|
| 198 |
+
if (outrootLen < TEXT_strlen((TEXT *)name)+1){
|
| 199 |
+
expand_singarr(outroot,TEXT_strlen((TEXT *)name),outrootLen,1.5,TEXT);
|
| 200 |
+
}
|
| 201 |
+
TEXT_strcpy(outroot, (TEXT *)name);
|
| 202 |
+
}
|
| 203 |
+
if (strcmp(reffmt,"trn") == 0 && strcmp(hypfmt[nh],"trn") == 0)
|
| 204 |
+
if (!use_diff)
|
| 205 |
+
scor[nh]=align_trans_mode_dp(refname,hypname[nh],title[nh],
|
| 206 |
+
1,case_sense,feedback,
|
| 207 |
+
char_align,id_type,
|
| 208 |
+
infered_wordseg, lexicon,
|
| 209 |
+
frag_correct, opt_del,
|
| 210 |
+
inf_flags, wwl, lm_file);
|
| 211 |
+
else
|
| 212 |
+
scor[nh]=align_trans_mode_diff(refname,hypname[nh],
|
| 213 |
+
title[nh],1,case_sense,
|
| 214 |
+
feedback,id_type);
|
| 215 |
+
else if (strcmp(reffmt,"stm")== 0 && strcmp(hypfmt[nh],"ctm") == 0)
|
| 216 |
+
if (!use_diff)
|
| 217 |
+
scor[nh]=align_ctm_to_stm_dp(refname,hypname[nh],title[nh],
|
| 218 |
+
1, case_sense,feedback,
|
| 219 |
+
char_align,id_type,
|
| 220 |
+
infered_wordseg, lexicon,
|
| 221 |
+
frag_correct, opt_del,
|
| 222 |
+
inf_flags,
|
| 223 |
+
BF_isSET(stm2ctm_reduce,REDUCE_REF_SEGMENTS),
|
| 224 |
+
BF_isSET(stm2ctm_reduce,REDUCE_HYP_WORDS),
|
| 225 |
+
left_to_right, wwl, lm_file);
|
| 226 |
+
else {
|
| 227 |
+
if (left_to_right)
|
| 228 |
+
scor[nh]=align_ctm_to_stm_diff(refname, hypname[nh],
|
| 229 |
+
title[nh],1,case_sense,
|
| 230 |
+
feedback,id_type);
|
| 231 |
+
else {
|
| 232 |
+
fprintf(scfp,"Error: can't perform diff alignments on "
|
| 233 |
+
"right-to-left data\n");
|
| 234 |
+
exit(1);
|
| 235 |
+
}
|
| 236 |
+
}
|
| 237 |
+
else if (strcmp(reffmt,"ctm")== 0 && strcmp(hypfmt[nh],"ctm") == 0)
|
| 238 |
+
scor[nh]=align_ctm_to_ctm(hypname[nh], refname, title[nh],
|
| 239 |
+
feedback, frag_correct, opt_del,
|
| 240 |
+
case_sense, time_align, left_to_right, wwl,
|
| 241 |
+
lm_file);
|
| 242 |
+
else if (strcmp(reffmt,"stm")== 0 && strcmp(hypfmt[nh],"txt") ==0){
|
| 243 |
+
#if DIFF_ENABLED
|
| 244 |
+
if (left_to_right)
|
| 245 |
+
scor[nh] =align_text_to_stm(refname, hypname[nh],title[nh],
|
| 246 |
+
1,case_sense,feedback,id_type);
|
| 247 |
+
else {
|
| 248 |
+
fprintf(scfp,"Error: can't perform diff alignments on "
|
| 249 |
+
"right-to-left data\n");
|
| 250 |
+
exit(1);
|
| 251 |
+
}
|
| 252 |
+
#else
|
| 253 |
+
do_exit("Alignments via diff have been disabled",prog,1);
|
| 254 |
+
#endif
|
| 255 |
+
} else{
|
| 256 |
+
fprintf(stderr,"Error: Unable to score '%s' against '%s'\n",
|
| 257 |
+
hypfmt[nh],reffmt);
|
| 258 |
+
exit(1);
|
| 259 |
+
}
|
| 260 |
+
|
| 261 |
+
if (scor[nh] == (SCORES *)0){
|
| 262 |
+
fprintf(stderr,"%s: Alignment failed. Exiting.\n",prog);
|
| 263 |
+
exit(1);
|
| 264 |
+
}
|
| 265 |
+
} else { /* input came from piped input */
|
| 266 |
+
/* Set up the output root name */
|
| 267 |
+
if ((hroot = strrchr(scor[nsc]->title,'/')) != NULL){
|
| 268 |
+
strncpy((char *)hdir,scor[nsc]->title,hroot-scor[nsc]->title);
|
| 269 |
+
hdir[hroot-scor[nsc]->title] = '\0';
|
| 270 |
+
hroot++;
|
| 271 |
+
} else {
|
| 272 |
+
hroot = scor[nsc]->title;
|
| 273 |
+
strcpy((char *)hdir,".");
|
| 274 |
+
}
|
| 275 |
+
if ((out_dir != (char *)0) ||
|
| 276 |
+
strcmp(((out_dir != (char *)0) ? out_dir : (char *)hdir),".") != 0)
|
| 277 |
+
sprintf((char *)outroot,"%s/%s",((out_dir != (char *)0) ? out_dir : (char *)hdir),
|
| 278 |
+
(out_name != (char *)0) ? out_name : hroot);
|
| 279 |
+
else
|
| 280 |
+
sprintf((char *)outroot,"%s",(out_name != (char *)0) ? out_name : hroot);
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
+
if (BF_isSET(outputs,OUT_SUM))
|
| 284 |
+
print_system_summary(scor[nsc],
|
| 285 |
+
BF_isSET(outputs,OUT_STDOUT) ? "-": (char *)outroot,
|
| 286 |
+
0, 0, 0, feedback);
|
| 287 |
+
if (BF_isSET(outputs,OUT_WWS)){
|
| 288 |
+
if (scor[nsc]->weight_ali)
|
| 289 |
+
print_system_summary(scor[nsc],
|
| 290 |
+
BF_isSET(outputs,OUT_STDOUT) ? "-": (char *)outroot,
|
| 291 |
+
0, 0, 1, feedback);
|
| 292 |
+
else
|
| 293 |
+
printf(" Skipping WWS Report, no word weights supplied.\n");
|
| 294 |
+
}
|
| 295 |
+
if (BF_isSET(outputs,OUT_RSUM))
|
| 296 |
+
print_system_summary(scor[nsc],
|
| 297 |
+
BF_isSET(outputs,OUT_STDOUT) ? "-":(char *)outroot,
|
| 298 |
+
0, 1, 0, feedback);
|
| 299 |
+
if (BF_isSET(outputs,OUT_SENT))
|
| 300 |
+
score_dtl_sent(scor[nsc], BF_isSET(outputs,OUT_STDOUT)?"-":(char *)outroot,
|
| 301 |
+
feedback);
|
| 302 |
+
if (BF_isSET(outputs,OUT_SPKR))
|
| 303 |
+
score_dtl_spkr(scor[nsc], BF_isSET(outputs,OUT_STDOUT)?"-":(char *)outroot,
|
| 304 |
+
feedback);
|
| 305 |
+
if (BF_isSET(outputs,OUT_DTL))
|
| 306 |
+
score_dtl_overall(scor[nsc],
|
| 307 |
+
BF_isSET(outputs,OUT_STDOUT) ? "-":(char *)outroot,
|
| 308 |
+
feedback);
|
| 309 |
+
if (BF_isSET(outputs,OUT_LUR))
|
| 310 |
+
print_lur(scor[nsc],
|
| 311 |
+
BF_isSET(outputs,OUT_STDOUT) ? "-":(char *)outroot, feedback);
|
| 312 |
+
if (BF_isSET(outputs,OUT_PRALIGN)){
|
| 313 |
+
FILE *fp = stdout;
|
| 314 |
+
if (BF_notSET(outputs,OUT_STDOUT))
|
| 315 |
+
fp = fopen(rsprintf("%s.pra",outroot),"w");
|
| 316 |
+
if (fp == (FILE *)0) fp = stdout;
|
| 317 |
+
if (feedback >= 1)
|
| 318 |
+
printf(" Writing string alignments to '%s'\n",
|
| 319 |
+
(fp == stdout) ? "stdout" :
|
| 320 |
+
rsprintf("%s.pra",outroot));
|
| 321 |
+
dump_SCORES_alignments(scor[nsc],fp,linewidth,0);
|
| 322 |
+
if (fp != stdout) fclose(fp);
|
| 323 |
+
}
|
| 324 |
+
if (BF_isSET(outputs,OUT_PRALIGN_FULL)){
|
| 325 |
+
FILE *fp = stdout;
|
| 326 |
+
if (BF_notSET(outputs,OUT_STDOUT))
|
| 327 |
+
fp = fopen(rsprintf("%s.prf",outroot),"w");
|
| 328 |
+
if (fp == (FILE *)0) fp = stdout;
|
| 329 |
+
if (feedback >= 1)
|
| 330 |
+
printf(" Writing string alignments to '%s'\n",
|
| 331 |
+
(fp == stdout) ? "stdout" :
|
| 332 |
+
rsprintf("%s.prf",outroot));
|
| 333 |
+
dump_SCORES_alignments(scor[nsc],fp,linewidth,1);
|
| 334 |
+
if (fp != stdout) fclose(fp);
|
| 335 |
+
}
|
| 336 |
+
if (BF_isSET(outputs,OUT_SGML)){
|
| 337 |
+
FILE *fp = stdout;
|
| 338 |
+
if (BF_notSET(outputs,OUT_STDOUT))
|
| 339 |
+
fp = fopen(rsprintf("%s.sgml",outroot),"w");
|
| 340 |
+
if (fp == (FILE *)0) fp = stdout;
|
| 341 |
+
if (fp != stdout && feedback >= 1)
|
| 342 |
+
printf(" Writing SGML string alignments to '%s'\n",
|
| 343 |
+
rsprintf("%s.sgml",outroot));
|
| 344 |
+
dump_SCORES_sgml(scor[nsc],fp,(TEXT *)":",(TEXT *)",");
|
| 345 |
+
if (fp != stdout) fclose(fp);
|
| 346 |
+
}
|
| 347 |
+
if (BF_isSET(outputs,OUT_NL_SGML)){
|
| 348 |
+
FILE *fp = stdout;
|
| 349 |
+
if (BF_notSET(outputs,OUT_STDOUT))
|
| 350 |
+
fp = fopen(rsprintf("%s.nl.sgml",outroot),"w");
|
| 351 |
+
if (fp == (FILE *)0) fp = stdout;
|
| 352 |
+
if (fp != stdout && feedback >= 1)
|
| 353 |
+
printf(" Writing Newline Separated SGML string alignments to '%s'\n",
|
| 354 |
+
rsprintf("%s.nl.sgml",outroot));
|
| 355 |
+
dump_SCORES_sgml(scor[nsc],fp,(TEXT *)"\n",(TEXT *)"\n");
|
| 356 |
+
if (fp != stdout) fclose(fp);
|
| 357 |
+
}
|
| 358 |
+
if (BF_isSET(conf_outputs,CONF_OUT_DET))
|
| 359 |
+
if (make_SCORES_DET_curve(&(scor[nsc]),1,(char *)outroot,feedback,"") != 0)
|
| 360 |
+
errors++;
|
| 361 |
+
if (BF_isSET(conf_outputs,CONF_OUT_BHIST))
|
| 362 |
+
if (make_binned_confidence(scor[nsc],(char *)outroot,feedback) != 0)
|
| 363 |
+
errors++;
|
| 364 |
+
if (BF_isSET(conf_outputs,CONF_OUT_HIST))
|
| 365 |
+
if (make_confidence_histogram(scor[nsc],(char *)outroot,feedback) != 0)
|
| 366 |
+
errors++;
|
| 367 |
+
if (BF_isSET(conf_outputs,CONF_OUT_SBHIST))
|
| 368 |
+
if (make_scaled_binned_confidence(scor[nsc],(char *)outroot,20,feedback) != 0)
|
| 369 |
+
errors++;
|
| 370 |
+
|
| 371 |
+
}
|
| 372 |
+
|
| 373 |
+
if (pipeout)
|
| 374 |
+
for (nsc=0; nsc < num_hyps + num_piped; nsc++)
|
| 375 |
+
dump_SCORES_sgml(scor[nsc],stdout,(TEXT *)"\n",(TEXT *)"\n");
|
| 376 |
+
|
| 377 |
+
/* clean up the score structures */
|
| 378 |
+
for (nsc=0; nsc < num_hyps + num_piped; nsc++)
|
| 379 |
+
SCORES_free(scor[nsc]);
|
| 380 |
+
if (wwl != (WWL *)0) free_WWL(&wwl);
|
| 381 |
+
|
| 382 |
+
if (feedback >= 1) {
|
| 383 |
+
if (errors == 0)
|
| 384 |
+
printf("\nSuccessful Completion\n");
|
| 385 |
+
else
|
| 386 |
+
printf("\nUnsuccessful Completion\n");
|
| 387 |
+
}
|
| 388 |
+
return(0);
|
| 389 |
+
}
|
| 390 |
+
|
| 391 |
+
void proc_args(int argc, char **argv, char *prog, char **rname, char **rfmt, char **hname, char **hfmt, int *nhyps, enum id_types *id_type, int *case_sense, int *outputs, char **title, int *feedback, int *linewidth, int *use_diff, char **out_dir, char **out_name, int *char_align, int *pipeout, int *pipein, int *infered_wordseg, char **lexicon, int *frag_correct, int *opt_del, int *inf_flags, int *stm2ctm_reduce, int *time_align, int *conf_outputs, int *left_to_right, char **wwl_file, char **lm_file){
|
| 392 |
+
int opt, fbset=0, outset=0, i, nh;
|
| 393 |
+
char *id;
|
| 394 |
+
struct stat fileinfo;
|
| 395 |
+
|
| 396 |
+
if (argc <= 1)
|
| 397 |
+
do_exit("Arguments reguired",prog,1);
|
| 398 |
+
|
| 399 |
+
*linewidth=1000;
|
| 400 |
+
*feedback=1;
|
| 401 |
+
*nhyps = 0;
|
| 402 |
+
*rname=(char *)0; *hname=(char *)0;
|
| 403 |
+
*rfmt=(char *)0; *hfmt=(char *)0;
|
| 404 |
+
id=(char *)0;
|
| 405 |
+
*outputs=0;
|
| 406 |
+
*case_sense=0;
|
| 407 |
+
*title=(char *)0;
|
| 408 |
+
*out_dir = (char *)0;
|
| 409 |
+
*out_name = (char *)0;
|
| 410 |
+
*use_diff = 0;
|
| 411 |
+
*char_align = 0;
|
| 412 |
+
*pipeout = 0;
|
| 413 |
+
*pipein = 0;
|
| 414 |
+
*infered_wordseg = 0;
|
| 415 |
+
*lexicon = (char *)0;
|
| 416 |
+
*frag_correct = 0;
|
| 417 |
+
*opt_del = 0;
|
| 418 |
+
*inf_flags = 0;
|
| 419 |
+
*stm2ctm_reduce = 0;
|
| 420 |
+
*time_align = 0;
|
| 421 |
+
*conf_outputs = CONF_OUT_NONE;
|
| 422 |
+
*left_to_right = 1;
|
| 423 |
+
*wwl_file = (char *)0;
|
| 424 |
+
*lm_file = (char *)0;
|
| 425 |
+
|
| 426 |
+
for (opt = 1; opt < argc && (*(argv[opt]) == '-'); opt++){
|
| 427 |
+
/* printf("Current OP %s\n",argv[opt]); */
|
| 428 |
+
if (strcmp(argv[opt],"-r") == 0){
|
| 429 |
+
if (argc < opt + 2) do_exit("Not enough Ref arguments",prog,1);
|
| 430 |
+
if (*(argv[opt+1]) == '-') do_exit("Req'd Ref File name",prog,1);
|
| 431 |
+
*rname = argv[++opt];
|
| 432 |
+
if (argc >= opt + 2 && *(argv[opt+1]) != '-') *rfmt = argv[++opt];
|
| 433 |
+
} else if (strcmp(argv[opt],"-h") == 0){
|
| 434 |
+
if (argc < opt + 2) do_exit("Not enough Hyp arguments",prog,1);
|
| 435 |
+
if (*(argv[opt+1]) == '-') do_exit("Req'd Hyp File name",prog,1);
|
| 436 |
+
hname[*nhyps] = argv[++opt];
|
| 437 |
+
if (argc >= opt + 2 && *(argv[opt+1]) != '-')
|
| 438 |
+
hfmt[*nhyps] = argv[++opt];
|
| 439 |
+
else
|
| 440 |
+
hfmt[*nhyps] = "trn";
|
| 441 |
+
if (argc >= opt + 2 && *(argv[opt+1]) != '-')
|
| 442 |
+
title[*nhyps] = argv[++opt];
|
| 443 |
+
else
|
| 444 |
+
title[*nhyps] = hname[*nhyps];
|
| 445 |
+
(*nhyps)++;
|
| 446 |
+
} else if (strcmp(argv[opt],"-i") == 0){
|
| 447 |
+
if (argc <= opt+1) do_exit("Not enough ID arguments",prog,1);
|
| 448 |
+
id = argv[++opt];
|
| 449 |
+
} else if (strcmp(argv[opt],"-l") == 0){
|
| 450 |
+
if (argc <= opt+1)
|
| 451 |
+
do_exit("Not enough Line Width arguments",prog,1);
|
| 452 |
+
*linewidth = atoi(argv[++opt]);
|
| 453 |
+
} else if (strcmp(argv[opt],"-L") == 0){
|
| 454 |
+
#ifdef WITH_SLM
|
| 455 |
+
if (argc <= opt+1)
|
| 456 |
+
do_exit("Not enough Language Model arguments",prog,1);
|
| 457 |
+
*lm_file = argv[++opt];
|
| 458 |
+
#else
|
| 459 |
+
do_exit("-L option used, but SLM toolkit not compiled into sctk\n",prog,1);
|
| 460 |
+
#endif
|
| 461 |
+
} else if (strcmp(argv[opt],"-f") == 0){
|
| 462 |
+
if (argc <= opt+1) do_exit("Not enough Feedback arguments",prog,1);
|
| 463 |
+
*feedback = atoi(argv[++opt]);
|
| 464 |
+
fbset = 1;
|
| 465 |
+
} else if (strcmp(argv[opt],"-o") == 0){
|
| 466 |
+
opt ++;
|
| 467 |
+
if (argc < opt + 1) do_exit("Not enough Report arguments",prog,1);
|
| 468 |
+
while (opt < argc && *(argv[opt]) != '-'){
|
| 469 |
+
if (strcmp(argv[opt],"sum") == 0)
|
| 470 |
+
BF_FLIP(*outputs,OUT_SUM);
|
| 471 |
+
else if (strcmp(argv[opt],"wws") == 0)
|
| 472 |
+
BF_FLIP(*outputs,OUT_WWS);
|
| 473 |
+
else if (strcmp(argv[opt],"rsum") == 0)
|
| 474 |
+
BF_FLIP(*outputs,OUT_RSUM);
|
| 475 |
+
else if ((strcmp(argv[opt],"pralign") == 0) ||
|
| 476 |
+
(strcmp(argv[opt],"pra") == 0))
|
| 477 |
+
BF_FLIP(*outputs,OUT_PRALIGN);
|
| 478 |
+
else if (strcmp(argv[opt],"prf") == 0)
|
| 479 |
+
BF_FLIP(*outputs,OUT_PRALIGN_FULL);
|
| 480 |
+
else if (strcmp(argv[opt],"lur") == 0)
|
| 481 |
+
BF_FLIP(*outputs,OUT_LUR);
|
| 482 |
+
else if (strcmp(argv[opt],"stdout") == 0)
|
| 483 |
+
BF_FLIP(*outputs,OUT_STDOUT);
|
| 484 |
+
else if (strcmp(argv[opt],"sgml") == 0)
|
| 485 |
+
BF_FLIP(*outputs,OUT_SGML);
|
| 486 |
+
else if (strcmp(argv[opt],"nl.sgml") == 0)
|
| 487 |
+
BF_FLIP(*outputs,OUT_NL_SGML);
|
| 488 |
+
else if (strcmp(argv[opt],"snt") == 0)
|
| 489 |
+
BF_FLIP(*outputs,OUT_SENT);
|
| 490 |
+
else if (strcmp(argv[opt],"spk") == 0)
|
| 491 |
+
BF_FLIP(*outputs,OUT_SPKR);
|
| 492 |
+
else if (strcmp(argv[opt],"dtl") == 0)
|
| 493 |
+
BF_FLIP(*outputs,OUT_DTL);
|
| 494 |
+
else if (strcmp(argv[opt],"all") == 0)
|
| 495 |
+
BF_FLIP(*outputs,OUT_PRALIGN + OUT_SUM + OUT_RSUM);
|
| 496 |
+
else if (strcmp(argv[opt],"none") == 0)
|
| 497 |
+
*outputs = 0;
|
| 498 |
+
else
|
| 499 |
+
fprintf(stderr,"Unknown report '%s'\n",argv[opt]);
|
| 500 |
+
opt++;
|
| 501 |
+
}
|
| 502 |
+
/* backup if we've gone to far */
|
| 503 |
+
if (opt < argc && *(argv[opt]) == '-') opt--;
|
| 504 |
+
outset=1;
|
| 505 |
+
} else if (strcmp(argv[opt],"-C") == 0){
|
| 506 |
+
opt ++;
|
| 507 |
+
if (argc < opt + 1)
|
| 508 |
+
do_exit("Not enough Confidence Report arguments",prog,1);
|
| 509 |
+
while (opt < argc && *(argv[opt]) != '-'){
|
| 510 |
+
if (strcmp(argv[opt],"det") == 0)
|
| 511 |
+
BF_FLIP(*conf_outputs,CONF_OUT_DET);
|
| 512 |
+
else if (strcmp(argv[opt],"bhist") == 0)
|
| 513 |
+
BF_FLIP(*conf_outputs,CONF_OUT_BHIST);
|
| 514 |
+
else if (strcmp(argv[opt],"sbhist") == 0)
|
| 515 |
+
BF_FLIP(*conf_outputs,CONF_OUT_SBHIST);
|
| 516 |
+
else if (strcmp(argv[opt],"hist") == 0)
|
| 517 |
+
BF_FLIP(*conf_outputs,CONF_OUT_HIST);
|
| 518 |
+
else if (strcmp(argv[opt],"none") == 0)
|
| 519 |
+
*conf_outputs = CONF_OUT_NONE;
|
| 520 |
+
else
|
| 521 |
+
fprintf(stderr,"Unknown confidence report '%s'\n",
|
| 522 |
+
argv[opt]);
|
| 523 |
+
opt++;
|
| 524 |
+
}
|
| 525 |
+
/* backup if we've gone to far */
|
| 526 |
+
if (opt < argc && *(argv[opt]) == '-') opt--;
|
| 527 |
+
outset=1;
|
| 528 |
+
} else if (strcmp(argv[opt],"-O") == 0){
|
| 529 |
+
if (argc <= opt+1)do_exit("Output directory not specified",prog,1);
|
| 530 |
+
*out_dir = argv[++opt];
|
| 531 |
+
} else if (strcmp(argv[opt],"-n") == 0){
|
| 532 |
+
if (argc <= opt+1)do_exit("Output name not specified",prog,1);
|
| 533 |
+
*out_name = argv[++opt];
|
| 534 |
+
} else if (strcmp(argv[opt],"-d") == 0){
|
| 535 |
+
#if DIFF_ENABLED
|
| 536 |
+
*use_diff = 1;
|
| 537 |
+
#else
|
| 538 |
+
do_exit("Alignments via diff have been disabled",prog,1);
|
| 539 |
+
#endif
|
| 540 |
+
} else if (strcmp(argv[opt],"-s") == 0){
|
| 541 |
+
*case_sense = 1;
|
| 542 |
+
} else if (strcmp(argv[opt],"-m") == 0){
|
| 543 |
+
*stm2ctm_reduce = REDUCE_NOTHING;
|
| 544 |
+
while (opt+1 < argc && *(argv[opt+1]) != '-') {
|
| 545 |
+
opt++;
|
| 546 |
+
if (strcmp(argv[opt],"ref") == 0)
|
| 547 |
+
BF_SET(*stm2ctm_reduce,REDUCE_REF_SEGMENTS);
|
| 548 |
+
else if (strcmp(argv[opt],"hyp") == 0)
|
| 549 |
+
BF_SET(*stm2ctm_reduce,REDUCE_HYP_WORDS);
|
| 550 |
+
else
|
| 551 |
+
do_exit(rsprintf("Unrecognized -m option '%s'",
|
| 552 |
+
argv[opt]),prog,1);
|
| 553 |
+
}
|
| 554 |
+
if (*stm2ctm_reduce == REDUCE_NOTHING)
|
| 555 |
+
*stm2ctm_reduce = REDUCE_REF_SEGMENTS;
|
| 556 |
+
} else if (strcmp(argv[opt],"-F") == 0){
|
| 557 |
+
*frag_correct = 1;
|
| 558 |
+
} else if (strcmp(argv[opt],"-D") == 0){
|
| 559 |
+
*opt_del = 1;
|
| 560 |
+
} else if (strcmp(argv[opt],"-c") == 0){
|
| 561 |
+
*char_align = CALI_ON;
|
| 562 |
+
while (opt+1 < argc && *(argv[opt+1]) != '-') {
|
| 563 |
+
opt++;
|
| 564 |
+
if (strcmp(argv[opt],"NOASCII") == 0)
|
| 565 |
+
BF_SET(*char_align,CALI_NOASCII);
|
| 566 |
+
else if (strcmp(argv[opt],"DH") == 0)
|
| 567 |
+
BF_SET(*char_align,CALI_DELHYPHEN);
|
| 568 |
+
else
|
| 569 |
+
do_exit(rsprintf("Unrecognized character alignment "
|
| 570 |
+
"option '%s'",argv[opt]),prog,1);
|
| 571 |
+
}
|
| 572 |
+
} else if (strcmp(argv[opt],"-e") == 0){
|
| 573 |
+
if (opt+1 >= argc || (opt+1 < argc && *(argv[opt+1]) == '-'))
|
| 574 |
+
do_exit("Argument required for character encoding\n",prog,1);
|
| 575 |
+
opt++;
|
| 576 |
+
if (!TEXT_set_encoding(argv[opt]))
|
| 577 |
+
do_exit(rsprintf("Unrecognized character encoding "
|
| 578 |
+
"option '%s'",argv[opt]),prog,1);
|
| 579 |
+
// Parse the optional localization
|
| 580 |
+
if (opt+1 < argc && *(argv[opt+1]) != '-'){
|
| 581 |
+
if (!TEXT_set_lang_prof(argv[opt+1]))
|
| 582 |
+
do_exit(rsprintf("Optional case conversion localization failed /%s/\n",
|
| 583 |
+
argv[opt+1]),prog,1);
|
| 584 |
+
opt++;
|
| 585 |
+
}
|
| 586 |
+
} else if (strcmp(argv[opt],"-p") == 0){
|
| 587 |
+
*pipeout = 1;
|
| 588 |
+
outset = 1;
|
| 589 |
+
} else if (strcmp(argv[opt],"-P") == 0){
|
| 590 |
+
*pipein = 1;
|
| 591 |
+
} else if (strcmp(argv[opt],"-T") == 0){
|
| 592 |
+
*time_align = 1;
|
| 593 |
+
} else if (strcmp(argv[opt],"-S") == 0){
|
| 594 |
+
opt ++;
|
| 595 |
+
if (argc < opt + 2) do_exit("Not enough Inferred Segmentation "
|
| 596 |
+
"arguments",prog,1);
|
| 597 |
+
if (opt < argc && *(argv[opt]) != '-')
|
| 598 |
+
if (strcmp(argv[opt],"algo1") == 0)
|
| 599 |
+
*infered_wordseg ^= INF_SEG_ALGO1;
|
| 600 |
+
else if (strcmp(argv[opt],"algo2") == 0)
|
| 601 |
+
*infered_wordseg ^= INF_SEG_ALGO2;
|
| 602 |
+
else
|
| 603 |
+
do_exit(rsprintf("Unrecognize inferred segmentation "
|
| 604 |
+
"algorithm '%s'",argv[opt]),prog,1);
|
| 605 |
+
else
|
| 606 |
+
do_exit("No Inferred Segmentation algorithm",prog,1);
|
| 607 |
+
opt++;
|
| 608 |
+
if (opt < argc && *(argv[opt]) != '-'){
|
| 609 |
+
if (stat(argv[opt],&fileinfo) != 0)
|
| 610 |
+
do_exit(rsprintf("Inferred Segmentation lexicon '%s'"
|
| 611 |
+
" does not exist",argv[opt]),prog,1);
|
| 612 |
+
*lexicon = argv[opt];
|
| 613 |
+
} else
|
| 614 |
+
do_exit("No Inferred Segmentation lexicon",prog,1);
|
| 615 |
+
if (opt+1 < argc && *(argv[opt+1]) != '-'){
|
| 616 |
+
opt++;
|
| 617 |
+
if (strcmp(argv[opt],"ASCIITOO") == 0)
|
| 618 |
+
BF_SET(*inf_flags,INF_ASCII_TOO);
|
| 619 |
+
else
|
| 620 |
+
do_exit(rsprintf("Unrecognized Inferred Segmentation"
|
| 621 |
+
" flag '%s'",argv[opt]),prog,1);
|
| 622 |
+
}
|
| 623 |
+
} else if (strcmp(argv[opt],"-w") == 0){
|
| 624 |
+
if (argc <= opt+1)do_exit("Word Weight list file not specified",prog,1);
|
| 625 |
+
*wwl_file = argv[++opt];
|
| 626 |
+
} else {
|
| 627 |
+
(void) fprintf(stderr,usage,prog);
|
| 628 |
+
printf("Illegal argument: %s\n",argv[opt]);
|
| 629 |
+
exit(1);
|
| 630 |
+
}
|
| 631 |
+
}
|
| 632 |
+
|
| 633 |
+
if (*pipeout){
|
| 634 |
+
*feedback = 0;
|
| 635 |
+
if (BF_isSET(*outputs,OUT_STDOUT))
|
| 636 |
+
do_exit("Error: output can not be both to stdout and a pipe",
|
| 637 |
+
prog,1);
|
| 638 |
+
}
|
| 639 |
+
|
| 640 |
+
/* set the default outputs */
|
| 641 |
+
if (*outputs == 0 && !outset)
|
| 642 |
+
BF_SET(*outputs,OUT_SUM + OUT_STDOUT);
|
| 643 |
+
|
| 644 |
+
/* reset feedback to 0 if STDOUT is used */
|
| 645 |
+
if ((BF_isSET(*outputs,OUT_STDOUT) && outset) &&
|
| 646 |
+
(*feedback > 0 && !fbset)){
|
| 647 |
+
/* fprintf(stderr,"Feedback level changed to 0\n");*/
|
| 648 |
+
*feedback = 0;
|
| 649 |
+
}
|
| 650 |
+
|
| 651 |
+
/* Check the input arguments */
|
| 652 |
+
if (! *pipein && ! (*rname != (char *)0 && *nhyps > 0))
|
| 653 |
+
do_exit("Input not specified, use transcription input or "
|
| 654 |
+
"piped input",prog,1);
|
| 655 |
+
|
| 656 |
+
if (*rname == (char *)0 && *nhyps > 0)
|
| 657 |
+
do_exit("Hypothesis input(s) specified, but no reference file",
|
| 658 |
+
prog,1);
|
| 659 |
+
if (*rname != (char *)0 && *nhyps == 0)
|
| 660 |
+
do_exit("Reference input specified, but no Hypothesis input(s).",
|
| 661 |
+
prog,1);
|
| 662 |
+
|
| 663 |
+
if (*rname != (char *)0 && *nhyps > 0){
|
| 664 |
+
if (stat(*rname,&fileinfo) != 0)
|
| 665 |
+
do_exit(rsprintf("Reference file '%s' does not exist",*rname),
|
| 666 |
+
prog,1);
|
| 667 |
+
|
| 668 |
+
for (nh=0; nh < *nhyps; nh++)
|
| 669 |
+
if (stat(hname[nh],&fileinfo) != 0)
|
| 670 |
+
do_exit(rsprintf("Hypothesis file '%s' does not exist",
|
| 671 |
+
hname[nh]),prog,1);
|
| 672 |
+
|
| 673 |
+
/* check the ref and hyp format arguments */
|
| 674 |
+
if (*rfmt == (char *)0) *rfmt = "trn";
|
| 675 |
+
if (! (strcmp(*rfmt,"trn") == 0 || strcmp(*rfmt,"ctm") == 0 ||
|
| 676 |
+
strcmp(*rfmt,"tmk") == 0 || strcmp(*rfmt,"stm") == 0))
|
| 677 |
+
do_exit(rsprintf("Reference file format '%s' not acceptable",*rfmt),
|
| 678 |
+
prog,1);
|
| 679 |
+
|
| 680 |
+
if (*hfmt == (char *)0) *hfmt = "trn";
|
| 681 |
+
for (i=0; i<*nhyps; i++)
|
| 682 |
+
if (! (strcmp(hfmt[i],"trn") == 0 || strcmp(hfmt[i],"ctm") == 0 ||
|
| 683 |
+
strcmp(hfmt[i],"tmk") == 0 || strcmp(hfmt[i],"txt") == 0))
|
| 684 |
+
do_exit(rsprintf("Hypothesis file format '%s' not acceptable",
|
| 685 |
+
hfmt[i]),prog,1);
|
| 686 |
+
|
| 687 |
+
/* check the id arguments */
|
| 688 |
+
if (id == (char *)0){
|
| 689 |
+
if (strcmp(*rfmt,"trn") == 0)
|
| 690 |
+
do_exit("Required utterance id (option -i) for"
|
| 691 |
+
" transcript mode", prog,1);
|
| 692 |
+
for (i=0; i<*nhyps; i++){
|
| 693 |
+
if (strcmp(hfmt[i],"trn") == 0)
|
| 694 |
+
do_exit("Required utterance id (option -i) for"
|
| 695 |
+
" transcript mode",prog,1);
|
| 696 |
+
}
|
| 697 |
+
}
|
| 698 |
+
|
| 699 |
+
/* only do time alignment on ctm to ctm */
|
| 700 |
+
if (*time_align){
|
| 701 |
+
if (strcmp(*rfmt,"ctm") != 0)
|
| 702 |
+
do_exit("Time-mediated alignments require the reference"
|
| 703 |
+
" file to be in CTM format",prog,1);
|
| 704 |
+
for (i=0; i<*nhyps; i++)
|
| 705 |
+
if (strcmp(hfmt[i],"ctm") != 0)
|
| 706 |
+
do_exit("Time-mediated alignments require the hypothesis"
|
| 707 |
+
" file to be in CTM format",prog,1);
|
| 708 |
+
}
|
| 709 |
+
}
|
| 710 |
+
|
| 711 |
+
if (id != (char *)0){
|
| 712 |
+
if (strcmp(id,"swb") == 0) *id_type=SWB;
|
| 713 |
+
else if (strcmp(id,"rm") == 0) *id_type=RM;
|
| 714 |
+
else if (strcmp(id,"wsj") == 0) *id_type=WSJ;
|
| 715 |
+
else if (strcmp(id,"spu_id") == 0) *id_type=SPUID;
|
| 716 |
+
else if (strcmp(id,"sp") == 0) *id_type=SP;
|
| 717 |
+
else
|
| 718 |
+
do_exit(rsprintf("Utterance id type '%s' not acceptable",id),
|
| 719 |
+
prog,1);
|
| 720 |
+
}
|
| 721 |
+
|
| 722 |
+
if (*stm2ctm_reduce){
|
| 723 |
+
if (strcmp(*rfmt,"stm") != 0)
|
| 724 |
+
do_exit("-m flag requires stm format reference file",prog,1);
|
| 725 |
+
for (i=0; i<*nhyps; i++)
|
| 726 |
+
if (strcmp(hfmt[i],"ctm") != 0)
|
| 727 |
+
do_exit("-m flag requires ctm format hypothesis file",prog,1);
|
| 728 |
+
if (*use_diff)
|
| 729 |
+
do_exit("-m flag can not be used with -d flag",prog,1);
|
| 730 |
+
}
|
| 731 |
+
|
| 732 |
+
if (*char_align && (*use_diff ||
|
| 733 |
+
(strcmp(*rfmt,"stm") == 0 && strcmp(*hfmt,"txt")==0)))
|
| 734 |
+
do_exit("Unable to do character alignments using diff\n",prog,1);
|
| 735 |
+
|
| 736 |
+
if (*wwl_file != (char *)0 && *lm_file != (char *)0)
|
| 737 |
+
do_exit("Flags '-L' and '-w' are mutually exclusive\n",prog,1);
|
| 738 |
+
|
| 739 |
+
if (*wwl_file != (char *)0){
|
| 740 |
+
if (*time_align) do_exit("Flags '-T' and '-w' are mutually exclusive\n",prog,1);
|
| 741 |
+
if (*char_align) do_exit("Flags '-c' and '-w' are mutually exclusive\n",prog,1);
|
| 742 |
+
if (*infered_wordseg) do_exit("Flags '-S' and '-w' are mutually exclusive\n",prog,1);
|
| 743 |
+
if (*use_diff) do_exit("Flags '-d' and '-w' are mutually exclusive\n",prog,1);
|
| 744 |
+
}
|
| 745 |
+
if (*lm_file != (char *)0){
|
| 746 |
+
if (*time_align) do_exit("Flags '-T' and '-L' are mutually exclusive\n",prog,1);
|
| 747 |
+
if (*char_align) do_exit("Flags '-c' and '-L' are mutually exclusive\n",prog,1);
|
| 748 |
+
if (*infered_wordseg) do_exit("Flags '-S' and '-L' are mutually exclusive\n",prog,1);
|
| 749 |
+
if (*use_diff) do_exit("Flags '-d' and '-L' are mutually exclusive\n",prog,1);
|
| 750 |
+
}
|
| 751 |
+
|
| 752 |
+
if (BF_isSET(*outputs,OUT_WWS))
|
| 753 |
+
if ((*wwl_file == (char *)0) && (*lm_file == (char *)0))
|
| 754 |
+
do_exit("-o wws option specified without a word weight file (via -w) or "
|
| 755 |
+
"LM file (via -L) specified\n",
|
| 756 |
+
prog,1) ;
|
| 757 |
+
}
|
| 758 |
+
|
| 759 |
+
void do_exit(char *desc, char *prog, int ret){
|
| 760 |
+
fprintf(stderr,usage,prog);
|
| 761 |
+
fprintf(stderr,"\n%s: Error, %s\n\n",prog,desc);
|
| 762 |
+
exit(ret);
|
| 763 |
+
}
|
| 764 |
+
|
SCTK/src/sclite/signtest.c
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**********************************************************************/
|
| 2 |
+
/* */
|
| 3 |
+
/* FILE: signtest.c */
|
| 4 |
+
/* WRITTEN BY: Jonathan G. Fiscus */
|
| 5 |
+
/* DATE: April 14 1989 */
|
| 6 |
+
/* NATIONAL INSTITUTE OF STANDARDS AND TECHNOLOGY */
|
| 7 |
+
/* SPEECH RECOGNITION GROUP */
|
| 8 |
+
/* */
|
| 9 |
+
/* USAGE: This uses the rank structure to perform */
|
| 10 |
+
/* the non-parametric Sign Test and generates */
|
| 11 |
+
/* a report. */
|
| 12 |
+
/* */
|
| 13 |
+
/* SOURCE:Statistics: Basic Techniques for Solving */
|
| 14 |
+
/* Applied Problems, by Stephen A. Book, 1977 */
|
| 15 |
+
/* */
|
| 16 |
+
/* See Also: The documentation file "signtest.doc" */
|
| 17 |
+
/* */
|
| 18 |
+
/**********************************************************************/
|
| 19 |
+
|
| 20 |
+
#include "sctk.h"
|
| 21 |
+
|
| 22 |
+
/****************************************************************/
|
| 23 |
+
/* main procedure to perform the sign test on the RANK */
|
| 24 |
+
/* structure. */
|
| 25 |
+
/****************************************************************/
|
| 26 |
+
void perform_signtest(RANK *rank, int verbose, int report, char *formula_str, char formula_id, int ***out_winner, char *outroot, int feedback, double ***out_confidence)
|
| 27 |
+
{
|
| 28 |
+
int comp1, comp2, **winner;
|
| 29 |
+
double **confidence;
|
| 30 |
+
FILE *fp = stdout;
|
| 31 |
+
|
| 32 |
+
if (report || verbose){
|
| 33 |
+
char *f = rsprintf("%s.sign",outroot);
|
| 34 |
+
if ((fp=(strcmp(outroot,"-") == 0) ? stdout : fopen(f,"w")) ==
|
| 35 |
+
(FILE *)0){
|
| 36 |
+
fprintf(stderr,"Warning: Open of %s for write failed. "
|
| 37 |
+
"Using stdout instead.\n",f);
|
| 38 |
+
fp = stdout;
|
| 39 |
+
} else
|
| 40 |
+
if (feedback >= 1) printf(" Output written to '%s'\n",f);
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
alloc_2dimZ(winner,rank->n_trt,rank->n_trt,int,NO_DIFF);
|
| 44 |
+
alloc_2dimZ(confidence,rank->n_trt,rank->n_trt,double,0.0);
|
| 45 |
+
*out_confidence = confidence;
|
| 46 |
+
*out_winner = winner;
|
| 47 |
+
|
| 48 |
+
for (comp1=0; comp1 < rank->n_trt -1; comp1++)
|
| 49 |
+
for (comp2=comp1+1; comp2< rank->n_trt ; comp2++){
|
| 50 |
+
winner[comp1][comp2] =
|
| 51 |
+
compute_signtest_for_treatment(rank,comp1,comp2,"Spkr",
|
| 52 |
+
formula_str,verbose,
|
| 53 |
+
formula_id=='E',fp,
|
| 54 |
+
&(confidence[comp1][comp2]));
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
if (report) print_trt_comp_matrix_for_RANK_one_winner(winner,rank,
|
| 58 |
+
"Comparison Matrix for the Sign Test",formula_str,
|
| 59 |
+
"Speaker",fp);
|
| 60 |
+
if (fp != stdout) fclose(fp);
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
/****************************************************************/
|
| 64 |
+
/* Given the two indexes of treatments to compare (in the */
|
| 65 |
+
/* RANK Struct) compute the Rank Sum statistics */
|
| 66 |
+
/* vars: */
|
| 67 |
+
/* zero_is_best : This identifies the "ideal" value for */
|
| 68 |
+
/* the value computed in the rank struct */
|
| 69 |
+
/* percentages. */
|
| 70 |
+
/****************************************************************/
|
| 71 |
+
int compute_signtest_for_treatment(RANK *rank, int treat1, int treat2, char *block_id, char *formula_str, int verbose, int zero_is_best, FILE *fp, double *confidence)
|
| 72 |
+
{
|
| 73 |
+
int sum_plus=0, sum_minus=0, sum_equal=0, i;
|
| 74 |
+
int block, max_len_block=0, max_len_treat=6;
|
| 75 |
+
int tptr[2]; /* a sorting pointer array for the treatment numbers */
|
| 76 |
+
char *pct_format, thresh_str[140];
|
| 77 |
+
TEXT *title_line = (TEXT *)0;
|
| 78 |
+
char *diff_line;
|
| 79 |
+
int paper_width = 79, rep_width, diff_col_len;
|
| 80 |
+
double equal_thresh = 0.005;
|
| 81 |
+
double sum_trt1=0.0, sum_trt2=0.0;
|
| 82 |
+
|
| 83 |
+
/* compute the maximum block title length */
|
| 84 |
+
max_len_block = strlen(block_id);
|
| 85 |
+
for (block=0; block <rank->n_blk ; block++)
|
| 86 |
+
if (strlen(rank->blk_name [ block ] ) > max_len_block)
|
| 87 |
+
max_len_block = strlen(rank->blk_name [ block ] );
|
| 88 |
+
|
| 89 |
+
if (max_len_treat < strlen(rank->trt_name [ treat1 ] ))
|
| 90 |
+
max_len_treat = strlen(rank->trt_name [ treat1 ] );
|
| 91 |
+
|
| 92 |
+
if (max_len_treat < strlen(rank->trt_name [ treat2 ] ))
|
| 93 |
+
max_len_treat = strlen(rank->trt_name [ treat2 ] );
|
| 94 |
+
|
| 95 |
+
/* set the treatment sorting array */
|
| 96 |
+
for (block=0; block <rank->n_blk ; block++){
|
| 97 |
+
sum_trt1 += rank->pcts [ block ][ treat1 ] ;
|
| 98 |
+
sum_trt2 += rank->pcts [ block ][ treat2 ] ;
|
| 99 |
+
}
|
| 100 |
+
if (sum_trt1 > sum_trt2)
|
| 101 |
+
tptr[0] = treat1, tptr[1] = treat2;
|
| 102 |
+
else
|
| 103 |
+
tptr[0] = treat2, tptr[1] = treat1;
|
| 104 |
+
|
| 105 |
+
/* set up format strings and titles */
|
| 106 |
+
sprintf(thresh_str,"(Threshold for equal percentages +- %5.3f)",
|
| 107 |
+
equal_thresh);
|
| 108 |
+
alloc_singarr(pct_format, max_len_treat + 2,char);
|
| 109 |
+
alloc_singarr(diff_line, max_len_treat*2 + 7,char);
|
| 110 |
+
pct_format[0] = '\0';
|
| 111 |
+
strcat(pct_format,center("",(max_len_treat-6)/2));
|
| 112 |
+
strcat(pct_format,"%6.2f");
|
| 113 |
+
strcat(pct_format,center("",max_len_treat - ((max_len_treat-6)/2 + 6) ));
|
| 114 |
+
sprintf(diff_line,"[%s - %s]",rank->trt_name[tptr[0]],
|
| 115 |
+
rank->trt_name[tptr[1]]);
|
| 116 |
+
diff_col_len = 15;
|
| 117 |
+
if (strlen(diff_line) > diff_col_len) diff_col_len=strlen(diff_line);
|
| 118 |
+
|
| 119 |
+
rep_width = max_len_block + max_len_treat * 2 + 4 * 3 + diff_col_len;
|
| 120 |
+
|
| 121 |
+
/* Print a detailed table showing sign differences */
|
| 122 |
+
if (verbose) {
|
| 123 |
+
sum_trt1 = sum_trt2 = 0.0;
|
| 124 |
+
fprintf(fp,"%s\n",center("Sign Test Calculations Table Comparing",
|
| 125 |
+
paper_width));
|
| 126 |
+
title_line = TEXT_strdup((TEXT *)rsprintf("%s %s Percentages for Systems %s and %s",
|
| 127 |
+
block_id, formula_str,rank->trt_name[tptr[0]],
|
| 128 |
+
rank->trt_name [ tptr[1] ] ));
|
| 129 |
+
fprintf(fp,"%s\n",center((char *)title_line,paper_width));
|
| 130 |
+
fprintf(fp,"%s\n\n",center(thresh_str,paper_width));
|
| 131 |
+
|
| 132 |
+
fprintf(fp,"%s",center("",(paper_width - rep_width)/2));
|
| 133 |
+
fprintf(fp,"%s",center("",max_len_block));
|
| 134 |
+
fprintf(fp," "); fprintf(fp,"%s",center("",max_len_treat));
|
| 135 |
+
fprintf(fp," "); fprintf(fp,"%s",center("",max_len_treat));
|
| 136 |
+
fprintf(fp," ");
|
| 137 |
+
fprintf(fp,"%s\n",center("Difference Sign",diff_col_len));
|
| 138 |
+
|
| 139 |
+
fprintf(fp,"%s",center("",(paper_width - rep_width)/2));
|
| 140 |
+
fprintf(fp,"%s",center(block_id,max_len_block));
|
| 141 |
+
fprintf(fp," ");
|
| 142 |
+
fprintf(fp,"%s",center(rank->trt_name [ tptr[0] ] ,max_len_treat));
|
| 143 |
+
fprintf(fp," ");
|
| 144 |
+
fprintf(fp,"%s",center(rank->trt_name [ tptr[1] ] ,max_len_treat));
|
| 145 |
+
fprintf(fp," ");
|
| 146 |
+
fprintf(fp,"%s\n",center(diff_line,diff_col_len));
|
| 147 |
+
fprintf(fp,"%s",center("",(paper_width - rep_width)/2));
|
| 148 |
+
for (i=0; i<rep_width; i++)
|
| 149 |
+
fprintf(fp,"-");
|
| 150 |
+
fprintf(fp,"\n");
|
| 151 |
+
}
|
| 152 |
+
for (block=0; block <rank->n_blk ; block++){
|
| 153 |
+
if (verbose) {
|
| 154 |
+
fprintf(fp,"%s",center("",(paper_width - rep_width)/2));
|
| 155 |
+
fprintf(fp,"%s",center(rank->blk_name [ block ] ,max_len_block));
|
| 156 |
+
fprintf(fp," ");
|
| 157 |
+
fprintf(fp,pct_format,rank->pcts [ block ][ tptr[0] ] );
|
| 158 |
+
fprintf(fp," ");
|
| 159 |
+
fprintf(fp,pct_format,rank->pcts [ block ][ tptr[1] ] );
|
| 160 |
+
fprintf(fp," ");
|
| 161 |
+
}
|
| 162 |
+
if (fabs(rank->pcts [ block ][ tptr[0] ] - rank->pcts [ block ][ tptr[1] ] ) <=
|
| 163 |
+
equal_thresh){
|
| 164 |
+
if (verbose) fprintf(fp,"%s\n",center("0",diff_col_len));
|
| 165 |
+
sum_equal++;
|
| 166 |
+
}
|
| 167 |
+
else if (rank->pcts [ block ][ tptr[0] ] < rank->pcts [ block ][ tptr[1] ] ){
|
| 168 |
+
if (verbose) fprintf(fp,"%s\n",center("-",diff_col_len));
|
| 169 |
+
sum_minus++;
|
| 170 |
+
}
|
| 171 |
+
else {
|
| 172 |
+
if (verbose) fprintf(fp,"%s\n",center("+",diff_col_len));
|
| 173 |
+
sum_plus++;
|
| 174 |
+
}
|
| 175 |
+
sum_trt1 += rank->pcts [ block ][ tptr[0] ] ;
|
| 176 |
+
sum_trt2 += rank->pcts [ block ][ tptr[1] ] ;
|
| 177 |
+
}
|
| 178 |
+
if (verbose){
|
| 179 |
+
fprintf(fp,"%s",center("",(paper_width - rep_width)/2));
|
| 180 |
+
for (i=0; i<rep_width; i++)
|
| 181 |
+
fprintf(fp,"-");
|
| 182 |
+
fprintf(fp,"\n");
|
| 183 |
+
/* an Average line */
|
| 184 |
+
fprintf(fp,"%s",center("",(paper_width - rep_width)/2));
|
| 185 |
+
fprintf(fp,"%s",center("Avg.",max_len_block));
|
| 186 |
+
fprintf(fp," ");
|
| 187 |
+
fprintf(fp,pct_format,sum_trt1 /rank->n_blk );
|
| 188 |
+
fprintf(fp," ");
|
| 189 |
+
fprintf(fp,pct_format,sum_trt2 /rank->n_blk );
|
| 190 |
+
fprintf(fp,"\n\n");
|
| 191 |
+
|
| 192 |
+
sprintf((char *)title_line,"No. Speakers with Positive %s Differences = N(+) = %2d",formula_str,sum_plus);
|
| 193 |
+
fprintf(fp,"%s\n",center((char *)title_line,paper_width));
|
| 194 |
+
sprintf((char *)title_line,"No. Speakers with Negative %s Differences = N(-) = %2d",formula_str,sum_minus);
|
| 195 |
+
fprintf(fp,"%s\n",center((char *)title_line,paper_width));
|
| 196 |
+
sprintf((char *)title_line,"No. Speakers with No %s Differences = N(0) = %2d",formula_str,sum_equal);
|
| 197 |
+
fprintf(fp,"%s\n",center((char *)title_line,paper_width));
|
| 198 |
+
fprintf(fp,"\n\n");
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
free_singarr(pct_format,char);
|
| 202 |
+
free_singarr(diff_line,char);
|
| 203 |
+
if (title_line != (TEXT *)0)
|
| 204 |
+
free_singarr(title_line, TEXT);
|
| 205 |
+
/* Analyze the Results */
|
| 206 |
+
{ int result;
|
| 207 |
+
result = sign_test_analysis(sum_plus,sum_minus,sum_equal,"+","-",0,
|
| 208 |
+
0.05,verbose, rank->trt_name [ tptr[0] ] ,
|
| 209 |
+
rank->trt_name [ tptr[1] ] ,
|
| 210 |
+
tptr,zero_is_best,fp,confidence);
|
| 211 |
+
/* if the result is significant, system which is better depends on if */
|
| 212 |
+
/* the treatments have been swapped, a negative result means tprt[0] is */
|
| 213 |
+
/* better, positive one tprt[1] is better */
|
| 214 |
+
return(result * ((tptr[0] == treat1) ? 1 : (-1)));
|
| 215 |
+
}
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
/****************************************************************/
|
| 219 |
+
/* Given the vital numbers for computing a rank sum test, */
|
| 220 |
+
/* Compute it, and if requested, print a verbose analysis */
|
| 221 |
+
/****************************************************************/
|
| 222 |
+
int sign_test_analysis(int num_a, int num_b, int num_z, char *str_a, char *str_b, int str_z, double alpha, int verbose, char *treat1_str, char *treat2_str, int *tptr, int zero_is_best, FILE *fp, double *confidence)
|
| 223 |
+
{
|
| 224 |
+
double test_stat, p=0.5;
|
| 225 |
+
int i;
|
| 226 |
+
|
| 227 |
+
num_b += (num_z / 2) + (num_z % 2);
|
| 228 |
+
num_a += (num_z / 2);
|
| 229 |
+
num_z = 0;
|
| 230 |
+
|
| 231 |
+
/* multiplication by 2 means it's a two-tailed test */
|
| 232 |
+
if (num_a != num_b)
|
| 233 |
+
test_stat = 2.0 * compute_acc_binomial(MIN(num_a,num_b),num_a+num_b,p);
|
| 234 |
+
else
|
| 235 |
+
test_stat = 1.0;
|
| 236 |
+
*confidence = test_stat;
|
| 237 |
+
|
| 238 |
+
if (verbose){
|
| 239 |
+
fprintf(fp,"The NULL Hypothesis:\n\n");
|
| 240 |
+
fprintf(fp," The number of speakers for which the differences is positive\n");
|
| 241 |
+
fprintf(fp," equals the number of speakers for which the differences is\n");
|
| 242 |
+
fprintf(fp," negative.\n");
|
| 243 |
+
fprintf(fp," P(N(+)) = P(N(-)) = 0.50\n\n");
|
| 244 |
+
|
| 245 |
+
fprintf(fp,"Alternate Hypothesis:\n\n");
|
| 246 |
+
fprintf(fp," The number of speakers for which the differences is positive \n");
|
| 247 |
+
fprintf(fp," is NOT equal to the number of speakers for which the difference\n");
|
| 248 |
+
fprintf(fp," is negative.\n\n");
|
| 249 |
+
fprintf(fp,"Decision Analysis:\n\n");
|
| 250 |
+
fprintf(fp," Assumptions:\n");
|
| 251 |
+
fprintf(fp," A1: The distibrution of positive and negative differences\n");
|
| 252 |
+
fprintf(fp," follows the binomial distribution for N fair coin tosses.\n");
|
| 253 |
+
fprintf(fp,"\n");
|
| 254 |
+
fprintf(fp," A2: In order to resolve the complication caused by cases where the\n");
|
| 255 |
+
fprintf(fp," difference in Word Accuracy is zero, half of the cases will\n");
|
| 256 |
+
fprintf(fp," be assigned to N(+) and half to N(-). In the event of an\n");
|
| 257 |
+
fprintf(fp," odd number of zero differences, N(-) will get one extra, this\n");
|
| 258 |
+
fprintf(fp," reduces the probability of there being a difference between\n");
|
| 259 |
+
fprintf(fp," the two systems.\n\n");
|
| 260 |
+
fprintf(fp," Rejection criterion:\n");
|
| 261 |
+
fprintf(fp," Reject the null hypothesis at the 95%% confidence level based\n");
|
| 262 |
+
fprintf(fp," on the following critical values table. N is the number of\n");
|
| 263 |
+
fprintf(fp," speakers being compared and N(-) is the number of negative\n");
|
| 264 |
+
fprintf(fp," differences.\n\n");
|
| 265 |
+
/* print a table of critical values */
|
| 266 |
+
fprintf(fp," MIN(N(-),N(+)) P(MIN(N(-),N(+)) | N=%2d)\n",num_a+num_b);
|
| 267 |
+
|
| 268 |
+
fprintf(fp," -------------- ------------------------\n");
|
| 269 |
+
for (i=0; i <= (num_a+num_b)/2 && (i - 3) <= num_b; i++){
|
| 270 |
+
double val = 2.0*compute_acc_binomial(i,num_a+num_b,p),
|
| 271 |
+
valp1 = 2.0*compute_acc_binomial(i+1,num_a+num_b,p);
|
| 272 |
+
if (val >= 0.0005)
|
| 273 |
+
fprintf(fp," %3d %5.3f", i,val);
|
| 274 |
+
else
|
| 275 |
+
fprintf(fp," %3d <0.001 ", i);
|
| 276 |
+
|
| 277 |
+
if ((val < alpha) && (valp1 > alpha))
|
| 278 |
+
fprintf(fp," <--- Null Hypothesis rejected at or below this point\n");
|
| 279 |
+
else
|
| 280 |
+
fprintf(fp,"\n");
|
| 281 |
+
}
|
| 282 |
+
fprintf(fp,"\n");
|
| 283 |
+
fprintf(fp," Decision:\n");
|
| 284 |
+
|
| 285 |
+
fprintf(fp," There were N(-)=%d negative differences , the probability of\n",num_b);
|
| 286 |
+
fprintf(fp," it occurring is %5.3f, therefore the null hypothesis ",test_stat);
|
| 287 |
+
if (test_stat < alpha){
|
| 288 |
+
fprintf(fp,"is REJECTED\n");
|
| 289 |
+
fprintf(fp," in favor of the Alternate Hypothesis. Further, %s is the\n",
|
| 290 |
+
(zero_is_best) ? treat2_str : treat1_str);
|
| 291 |
+
fprintf(fp," better System.\n");
|
| 292 |
+
} else{
|
| 293 |
+
fprintf(fp,"is ACCEPTED\n");
|
| 294 |
+
fprintf(fp," There is no statistical difference between %s and %s\n",treat1_str,treat2_str);
|
| 295 |
+
}
|
| 296 |
+
form_feed(fp);
|
| 297 |
+
}
|
| 298 |
+
if (test_stat < alpha){
|
| 299 |
+
if (0) fprintf(fp,"Returning Result %d\n",TEST_DIFF * ((zero_is_best) ? 1 : -1));
|
| 300 |
+
return(TEST_DIFF * ((zero_is_best) ? 1 : -1));
|
| 301 |
+
}
|
| 302 |
+
return(NO_DIFF);
|
| 303 |
+
}
|
| 304 |
+
|
SCTK/src/sclite/slm_intf.c
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#include "sctk.h"
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
/*
|
| 5 |
+
File: slm_intf.c
|
| 6 |
+
Date: March 20, 1998
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
This file contains interface functions to lookup probs from a language
|
| 10 |
+
model read in by the SLM toolkit libraries.
|
| 11 |
+
|
| 12 |
+
The only function that is always defined is lookup_lm_word_weight. If the
|
| 13 |
+
SLM is not included, then executing this function is an error.
|
| 14 |
+
|
| 15 |
+
*/
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
void lookup_lm_word_weight(ARC *arc, void *ptr){
|
| 19 |
+
|
| 20 |
+
#ifdef WITH_SLM
|
| 21 |
+
WORD *tw = (WORD *)(arc->data);
|
| 22 |
+
static init = 1;
|
| 23 |
+
static ng_t ng;
|
| 24 |
+
static fb_info *fb_list;
|
| 25 |
+
WORD *w = (WORD *)arc->data, *w_m1, *w_m2;
|
| 26 |
+
double sum_weight, lu_prob, def_w;
|
| 27 |
+
int nprob;
|
| 28 |
+
ARC_LIST_ATOM *oarc_a, *oarc_b;
|
| 29 |
+
int dbg = 0;
|
| 30 |
+
|
| 31 |
+
if (init){
|
| 32 |
+
initialize_lm(&ng,&fb_list, (char *)ptr, dbg);
|
| 33 |
+
init = 0;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
#define W_func(_d) (log(1.0 / (_d)) * 1.4426950408889634074)
|
| 37 |
+
|
| 38 |
+
/* Set the default weight for this word */
|
| 39 |
+
def_w = (w->opt_del) ? 0.0 : 20.0;
|
| 40 |
+
|
| 41 |
+
nprob = 0, sum_weight = 0;
|
| 42 |
+
|
| 43 |
+
if (dbg) printf("w->value= %s\n",w->value);
|
| 44 |
+
/* search for the previous word */
|
| 45 |
+
if (! arc->from_node->start_state && ng.n > 1 && ! w->opt_del){
|
| 46 |
+
for (oarc_a = arc->from_node->in_arcs; oarc_a != NULL; oarc_a=oarc_a->next){
|
| 47 |
+
w_m1 = (WORD*)(oarc_a->arc->data);
|
| 48 |
+
|
| 49 |
+
if (! oarc_a->arc->from_node->start_state && ng.n > 2){
|
| 50 |
+
for (oarc_b = oarc_a->arc->from_node->in_arcs; oarc_b != NULL; oarc_b=oarc_b->next){
|
| 51 |
+
w_m2 = (WORD*)(oarc_b->arc->data);
|
| 52 |
+
if (dbg) printf(" w-1= %s w-2= %s\n",w_m1->value,w_m2->value);
|
| 53 |
+
sum_weight +=
|
| 54 |
+
(tg_lookup(w, w_m1, w_m2, &ng, fb_list, &lu_prob, dbg)) ? W_func(lu_prob) : def_w;
|
| 55 |
+
nprob ++;
|
| 56 |
+
}
|
| 57 |
+
} else {
|
| 58 |
+
w_m2 = (WORD *)0;
|
| 59 |
+
if (dbg) printf(" w-1= %s w-2= No-context\n",w_m1->value);
|
| 60 |
+
sum_weight +=
|
| 61 |
+
(tg_lookup(w, w_m1, w_m2, &ng, fb_list, &lu_prob, dbg)) ? W_func(lu_prob) : def_w;
|
| 62 |
+
nprob ++;
|
| 63 |
+
}
|
| 64 |
+
}
|
| 65 |
+
} else {
|
| 66 |
+
w_m1 = w_m2 = (WORD *)0;
|
| 67 |
+
if (dbg) printf(" w-1= No-context w-2= No-context\n");
|
| 68 |
+
if (! w->opt_del)
|
| 69 |
+
sum_weight +=
|
| 70 |
+
(tg_lookup(w, w_m1, w_m2, &ng, fb_list, &lu_prob, dbg)) ? W_func(lu_prob) : def_w;
|
| 71 |
+
nprob ++;
|
| 72 |
+
}
|
| 73 |
+
if (dbg) printf(" AvgWeight= \t%g\n",sum_weight/nprob);
|
| 74 |
+
tw->weight = sum_weight / nprob;
|
| 75 |
+
#else
|
| 76 |
+
fprintf(scfp,"Error: a call to lookup_lm_word_weight() was made even though\n"
|
| 77 |
+
" the SLM toolkit has not been included in the compilation of SCTK\n");
|
| 78 |
+
exit(1);
|
| 79 |
+
#endif
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
#ifdef WITH_SLM
|
| 83 |
+
|
| 84 |
+
/*****************************************************************/
|
| 85 |
+
/* given upto three WORDS, lookup the N-gram in a language model */
|
| 86 |
+
|
| 87 |
+
int tg_lookup(WORD *w, WORD *w_m1, WORD *w_m2, ng_t *ng, fb_info *fb_list, double *prob, int dbg){
|
| 88 |
+
int32 h_lu, m1_lu, m2_lu;
|
| 89 |
+
id__t h_id, m_id[3];
|
| 90 |
+
int bo_case = 0, acl = 0;
|
| 91 |
+
int actual_context;
|
| 92 |
+
|
| 93 |
+
if (sih_lookup(ng->vocab_ht,
|
| 94 |
+
(char *)((w->opt_del)?w->intern_value:w->value),&h_lu) == 0){
|
| 95 |
+
if (dbg) printf(" Head Word Not in Vocab\n");
|
| 96 |
+
*prob = 0.0;
|
| 97 |
+
return(0);
|
| 98 |
+
}
|
| 99 |
+
h_id = (id__t)h_lu;
|
| 100 |
+
|
| 101 |
+
if (w_m1 != (WORD *)0){
|
| 102 |
+
sih_lookup(ng->vocab_ht,
|
| 103 |
+
(char *)((w_m1->opt_del)?w_m1->intern_value:w_m1->value),&m1_lu);
|
| 104 |
+
actual_context = 1;
|
| 105 |
+
m_id[0] = (id__t)m1_lu;
|
| 106 |
+
|
| 107 |
+
if (w_m2 != (WORD *)0){
|
| 108 |
+
sih_lookup(ng->vocab_ht,
|
| 109 |
+
(char *)((w_m2->opt_del)?w_m2->intern_value:w_m2->value),&m2_lu);
|
| 110 |
+
actual_context = 2;
|
| 111 |
+
m_id[0] = (id__t)m2_lu;
|
| 112 |
+
m_id[1] = (id__t)m1_lu;
|
| 113 |
+
}
|
| 114 |
+
} else {
|
| 115 |
+
actual_context = 0;
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
*prob = calc_prob_of(h_id,m_id,actual_context,ng,(arpa_lm_t *)0,
|
| 119 |
+
fb_list,&bo_case,&acl,0);
|
| 120 |
+
|
| 121 |
+
if (dbg){
|
| 122 |
+
printf(" Texts: P(%s | ",(char *)w->value);
|
| 123 |
+
if (ng->n > 2) printf("%s ",(w_m2 == (WORD *)0) ? "UNK" : (char *)w_m2->value);
|
| 124 |
+
if (ng->n > 1) printf("%s",(w_m1 == (WORD *)0) ? "UNK" : (char *)w_m1->value);
|
| 125 |
+
printf(") = %g bo_case ",*prob);
|
| 126 |
+
decode_bo_case(bo_case,acl,stdout);
|
| 127 |
+
}
|
| 128 |
+
return(1);
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
/*****************************************************************/
|
| 132 |
+
/* Read in a lanagauge model, an set up the structures. */
|
| 133 |
+
|
| 134 |
+
void initialize_lm(ng_t *ng, fb_info **fb_list, char *lm_file, int dbg){
|
| 135 |
+
|
| 136 |
+
if (lm_file != (char *)0){
|
| 137 |
+
if (dbg) printf("Loading LM file '%s'\n",lm_file);
|
| 138 |
+
load_lm(ng,lm_file); /* if it failes, it dies */
|
| 139 |
+
if (dbg) {
|
| 140 |
+
printf("LM read in -\n");
|
| 141 |
+
printf(" version: %d\n",ng->version);
|
| 142 |
+
printf(" #-gram order: %d\n",ng->n);
|
| 143 |
+
printf(" vocabulary size: %d\n",ng->vocab_size);
|
| 144 |
+
}
|
| 145 |
+
*fb_list = gen_fb_list(ng->vocab_ht,
|
| 146 |
+
ng->vocab_size,
|
| 147 |
+
ng->vocab,
|
| 148 |
+
ng->context_cue,
|
| 149 |
+
0, 0, 0, 0,
|
| 150 |
+
"");
|
| 151 |
+
|
| 152 |
+
/* This code works as a test, except the printout for bo_case is wrong for
|
| 153 |
+
the trigram. it output 3x2x1 instead of 3x2-1 */
|
| 154 |
+
|
| 155 |
+
if (dbg){
|
| 156 |
+
int32 lu1, lu2, lu3; id__t h_id, m_id[4]; double prob;
|
| 157 |
+
int bo_case = 0, acl = 0;
|
| 158 |
+
|
| 159 |
+
if (sih_lookup(ng->vocab_ht,"the",&lu1) == 0)
|
| 160 |
+
printf(" Head Word Not in Vocab\n");
|
| 161 |
+
m_id[0] = lu1;
|
| 162 |
+
h_id = lu1;
|
| 163 |
+
prob = calc_prob_of(h_id,m_id,0,ng,(arpa_lm_t *)0,*fb_list,&bo_case,&acl,0);
|
| 164 |
+
printf(" P(%s| ) = %g bo_case ",ng->vocab[lu1],prob);
|
| 165 |
+
decode_bo_case(bo_case,acl,stdout);
|
| 166 |
+
|
| 167 |
+
if (ng->n > 1) {
|
| 168 |
+
if (sih_lookup(ng->vocab_ht,"dow",&lu2) == 0)
|
| 169 |
+
printf(" Head Word Not in Vocab\n");
|
| 170 |
+
m_id[0] = lu1;
|
| 171 |
+
h_id = lu2;
|
| 172 |
+
prob = calc_prob_of(h_id,m_id,1,ng,(arpa_lm_t *)0,*fb_list,&bo_case,&acl,0);
|
| 173 |
+
printf(" P(%s | the) = %g bo_case ",ng->vocab[lu2],prob);
|
| 174 |
+
decode_bo_case(bo_case,acl,stdout);
|
| 175 |
+
|
| 176 |
+
if (ng->n > 2) {
|
| 177 |
+
if (sih_lookup(ng->vocab_ht,"jones",&lu3) == 0)
|
| 178 |
+
printf(" Head Word Not in Vocab\n");
|
| 179 |
+
m_id[0] = lu1;
|
| 180 |
+
m_id[1] = lu2;
|
| 181 |
+
h_id = lu3;
|
| 182 |
+
prob = calc_prob_of(h_id,m_id,2,ng,(arpa_lm_t *)0,*fb_list,&bo_case,&acl,0);
|
| 183 |
+
printf(" P(jones | the dow) = %g bo_case ",prob);
|
| 184 |
+
decode_bo_case(bo_case,acl,stdout);
|
| 185 |
+
}
|
| 186 |
+
}
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
|
| 190 |
+
} else {
|
| 191 |
+
fprintf(stderr,"Error: no lm_file name passed to alignment\n");
|
| 192 |
+
}
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
+
#endif
|
SCTK/src/sclite/statdist.o
ADDED
|
Binary file (24.8 kB). View file
|
|
|
SCTK/src/sclite/stm.h
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
typedef struct stm_seg_struct{
|
| 3 |
+
TEXT *file;
|
| 4 |
+
TEXT *chan;
|
| 5 |
+
TEXT *spkr;
|
| 6 |
+
double t1;
|
| 7 |
+
double t2;
|
| 8 |
+
int flag1;
|
| 9 |
+
TEXT *labels;
|
| 10 |
+
TEXT *text;
|
| 11 |
+
} STM_SEG;
|
| 12 |
+
|
| 13 |
+
typedef struct stm_struct{
|
| 14 |
+
int max;
|
| 15 |
+
int s;
|
| 16 |
+
int num;
|
| 17 |
+
STM_SEG *seg;
|
| 18 |
+
} STM;
|
| 19 |
+
|
| 20 |
+
STM *alloc_STM(int n);
|
| 21 |
+
void expand_STM(STM *stm);
|
| 22 |
+
void free_STM(STM *stm);
|
| 23 |
+
void fill_STM(FILE *fp, STM *stm, char *fname, boolean *end_of_file, int case_sense, int *perr);
|
| 24 |
+
void locate_STM_boundary(STM *stm, int start, int by_file, int by_chan, int *end);
|
| 25 |
+
void dump_STM_words(STM *stm,int s, int e, char *file);
|
| 26 |
+
void dump_STM(STM *stm, int s, int e);
|
| 27 |
+
void read_stm_line(TEXT **buf, int *len, FILE *fp);
|
| 28 |
+
void parse_stm_line(STM_SEG *seg, TEXT **buf_ptr, int *buf_len, int case_sense, int dbg);
|
| 29 |
+
void free_STM_SEG(STM_SEG *seg);
|
| 30 |
+
void convert_stm_to_word_list(char *file, char *words, int case_sense, int *num_ref);
|
| 31 |
+
void fill_STM_structure(STM *stm, FILE *fp_stm, char *stm_file, int *stm_file_end, int case_sense);
|