File Coverage

blib/lib/Brat/Handler/File.pm
Criterion Covered Total %
statement 244 336 72.6
branch 43 114 37.7
condition 3 9 33.3
subroutine 29 35 82.8
pod 14 14 100.0
total 333 508 65.5


line stmt bran cond sub pod time code
1             package Brat::Handler::File;
2              
3              
4 9     9   396 use utf8;
  9         25  
  9         53  
5 9     9   293 use strict;
  9         20  
  9         191  
6 9     9   45 use warnings;
  9         17  
  9         438  
7 9     9   66 use open qw(:utf8 :std);
  9         51  
  9         60  
8              
9             our $VERSION='0.11';
10              
11             sub new {
12              
13 27     27 1 6775 my ($class, $filename) = @_;
14 27         70 my $annotationFilename;
15             my $textFilename;
16 27         63 my $textSize = 0;
17 27         157 my @annFiles;
18             my @textFiles;
19 27         0 my @files;
20 27         0 my $f;
21 27         0 my $line;
22              
23             # print STDERR "\n==> $filename - " . ref($filename) . ";\n";
24 27 100       96 if (defined $filename) {
25 21 50       89 if (ref($filename) eq "") {
    0          
26 21         62 push @files, $filename;
27             } elsif (ref($filename) eq "ARRAY") {
28 0         0 push @files, @$filename;
29             }
30             }
31 27         69 foreach $f (@files) {
32             # warn "$f\n";
33 21         48 $annotationFilename = $f;
34 21         68 $annotationFilename =~ s/\.txt$/.ann/;
35 21         44 $textFilename = $f;
36 21         120 $textFilename =~ s/\.ann$/.txt/;
37 21         54 $textSize = 0;
38 21 50       828 open FILE, $textFilename or die "no such file $textFilename\n";
39 21         456 while($line = ) {
40 42         414 $textSize += length($line);
41             }
42 21         164 close FILE;
43             # my @s = stat($textFilename);
44             # $textSize += $s[7];
45 21         101 push @annFiles, $annotationFilename;
46 21         66 push @textFiles, $textFilename;
47             }
48 27         299 my $bratfile = {
49             'annotationFilename' => [@annFiles],
50             'textFilename' => [@textFiles],
51             'terms' => {},
52             'relations' => {},
53             'attributes' => {},
54             'maxTermId' => 0,
55             'maxRelationId' => 0,
56             'maxAttributeId' => 0,
57             'textSize' => $textSize,
58             };
59            
60 27         85 bless($bratfile, $class);
61              
62 27 100       90 if (defined $filename) {
63 21 50       80 if (ref($filename) eq "") {
    0          
64 21         98 $bratfile->loadBratFile;
65             } elsif (ref($filename) eq "ARRAY") {
66 0         0 warn "load of several brat files not implemented\n";
67             }
68             }
69 27         554 return($bratfile);
70             }
71              
72             sub _textFilename {
73 6     6   8 my $self = shift;
74              
75 6 100       13 if (@_) {
76 3         4 my $arg = shift;
77 3         4 push @{$self->{'textFilename'}}, $arg;
  3         6  
78             }
79 6         13 return($self->{'textFilename'});
80             }
81              
82             sub _textSize {
83 7     7   633 my $self = shift;
84              
85 7 100       20 if (@_) {
86 1         3 $self->{'textSize'} = shift;
87             }
88 7         22 return($self->{'textSize'});
89             }
90              
91             sub _annotationFilename {
92 27     27   72 my $self = shift;
93 27 100       87 if (@_) {
94 24         49 my $arg = shift;
95 24 100       159 if ($arg =~ /^\d+$/) {
96 21         648 return($self->{'annotationFilename'}->[$arg]);
97             } else {
98 3         4 push @{$self->{'annotationFilename'}}, $arg;
  3         6  
99             }
100             }
101 6         13 return($self->{'annotationFilename'});
102             }
103              
104             sub _terms {
105 5577     5577   9116 my $self = shift;
106              
107 5577 50       9709 if (@_) {
108 0         0 my $list = shift;
109 0         0 my $term;
110 0         0 foreach $term (@$list) {
111 0         0 $self->_addTerm($term->{'id'}, $term);
112             }
113             # $self->{'terms'} = shift;
114              
115             # max Term Id
116             }
117 5577         16178 return($self->{'terms'});
118             }
119              
120             sub _addTerm {
121 669     669   1385 my $self = shift;
122              
123 669 50       1428 if (@_) {
124 669         1024 my $id = shift;
125 669         1275 $self->_terms->{$id} = shift;
126             # max Term Id
127 669 100       1392 if ($self->_maxTermId < $self->_terms->{$id}->{'numId'}) {
128 596         1206 $self->_maxTermId($self->_terms->{$id}->{'numId'});
129             }
130 669         1466 return($self->_getTermFromId($id));
131             }
132 0         0 return(undef);
133             }
134              
135             sub _maxTermId {
136 1270     1270   2469 my $self = shift;
137              
138 1270 100       2411 if (@_) {
139 596         1168 $self->{'maxTermId'} = shift;
140             }
141 1270         2599 return($self->{'maxTermId'});
142             }
143              
144             sub _getTermFromId {
145 1812     1812   2567 my $self = shift;
146 1812         2492 my $id = shift;
147              
148 1812 50 33     4039 if ((defined $id) && (exists $self->_terms->{$id})) {
149 1812         3155 return($self->_terms->{$id});
150             }
151             }
152              
153             sub _relations {
154 1044     1044   1443 my $self = shift;
155              
156 1044 50       1836 if (@_) {
157 0         0 my $list = shift;
158 0         0 my $relation;
159 0         0 foreach $relation (@$list) {
160 0         0 $self->_addRelation($relation->{'id'}, $relation);
161             }
162             # $self->{'relations'} = shift;
163             # max Relation Id
164             }
165 1044         3360 return($self->{'relations'});
166             }
167              
168             sub _addRelation {
169 105     105   177 my $self = shift;
170              
171 105 50       231 if (@_) {
172 105         159 my $id = shift;
173 105         222 $self->_relations->{$id} = shift;
174             # max Relation Id
175             # warn $self->_maxRelationId . " < " . $self->_relations->{$id}->{'numId'} . "\n";
176 105 100       246 if ($self->_maxRelationId < $self->_relations->{$id}->{'numId'}) {
177 97         197 $self->_maxRelationId($self->_relations->{$id}->{'numId'});
178             }
179 105         238 return($self->_getRelationFromId($id));
180             }
181 0         0 return(undef);
182             }
183              
184             sub _maxRelationId {
185 207     207   306 my $self = shift;
186              
187 207 100       413 if (@_) {
188 97         181 $self->{'maxRelationId'} = shift;
189             }
190 207         427 return($self->{'maxRelationId'});
191             }
192              
193             sub _getRelationFromId {
194 359     359   520 my $self = shift;
195 359         487 my $id = shift;
196              
197 359 50 33     853 if ((defined $id) && (exists $self->_relations->{$id})) {
198 359         680 return($self->_relations->{$id});
199             }
200             }
201              
202             sub _attributes {
203 94     94   150 my $self = shift;
204              
205 94 50       202 if (@_) {
206 0         0 my $list = shift;
207 0         0 my $attribute;
208 0         0 foreach $attribute (@$list) {
209 0         0 $self->_addAttribute($attribute->{'id'}, $attribute);
210             }
211             # $self->{'attributes'} = shift;
212             # max Attribute Id
213             }
214 94         350 return($self->{'attributes'});
215             }
216              
217             sub _addAttribute {
218 15     15   37 my $self = shift;
219              
220 15 50       64 if (@_) {
221 15         34 my $id = shift;
222 15         60 $self->_attributes->{$id} = shift;
223             # max Attribute Id
224 15 50       61 if ($self->_maxAttributeId < $self->_attributes->{$id}->{'numId'}) {
225 15         45 $self->_maxAttributeId($self->_attributes->{$id}->{'numId'});
226             }
227 15         58 return($self->_getAttributeFromId($id));
228             }
229 0         0 return(undef);
230             }
231              
232             sub _maxAttributeId {
233 35     35   75 my $self = shift;
234              
235 35 100       90 if (@_) {
236 15         45 $self->{'maxAttributeId'} = shift;
237             }
238 35         125 return($self->{'maxAttributeId'});
239             }
240              
241             sub _getAttributeFromId {
242 22     22   43 my $self = shift;
243 22         45 my $id = shift;
244              
245 22 50 33     106 if ((defined $id) && (exists $self->_attributes->{$id})) {
246 22         58 return($self->_attributes->{$id});
247             }
248             }
249              
250             sub loadBratFile {
251 21     21 1 83 my ($self) = @_;
252 21         279 my $line;
253             my $id;
254 21         0 my $info;
255 21         0 my $str;
256 21         0 my $type;
257 21         0 my $termId;
258 21         0 my $value;
259 21         0 my $arg1;
260 21         0 my $arg2;
261 21         0 my $o;
262 21         0 my $s;
263 21         0 my $e;
264 21         0 my @starts;
265 21         0 my @ends;
266 21         0 my $numId;
267             # warn "===> " . $self->_filename . "\n";
268 21 50       78 open FILE, "<:utf8", $self->_annotationFilename(0) or die "no such file " . $self->_annotationFilename(0) . "\n";
269 21         314 while($line = ) {
270 692         1395 chomp $line;
271 692         1291 @starts = ();
272 692         1058 @ends = ();
273              
274 692         2891 ($id, $info, $str) = split /\t/, $line;
275 692 100       2922 if ($id =~ /^TS?(?[\d]+)/) {
276 9     9   23572 $numId = $+{numid};
  9         3971  
  9         28036  
  586         3087  
277             # ($type, $start, $end) = split / /, $info;
278             # warn "info: $info\n";
279 586 50       2745 if ($info =~ /^(?[^ ]+) (?.*)/) {
280 586         2478 $type = $+{type};
281 586         3194 foreach $o (split /;/, $+{offsets}) {
282 594         1967 ($s, $e) = split / /, $o;
283             # warn "\t$s : $e\n";
284 594         1353 push @starts, $s;
285 594         1196 push @ends, $e;
286             }
287             # warn "->$id\n";
288 586         4220 $self->_addTerm($id, {
289             'id' => $id,
290             'numId' => $numId,
291             'type' => $type,
292             'start' => [@starts],
293             'end' => [@ends],
294             'str' => $str,
295             'attrlst' => [],
296             });
297             }
298             }
299 692 100       1861 if ($id =~ /^A(?\d+)/) {
300 13         85 $numId = $+{numid};
301 13         96 ($type, $termId, $value) = split / /, $info;
302 13         137 $self->_addAttribute($id, {
303             'id' => $id,
304             'numId' => $numId,
305             'type' => $type,
306             'termId' => $termId,
307             'value' => $value,
308             });
309             # warn "termId: $start\n";
310 13         25 push @{$self->_getTermFromId($termId)->{'attrlst'}}, $id;
  13         44  
311            
312             }
313 692 100       2717 if ($id =~ /^R(?\d+)/) {
314             # warn "==> $id " . $+{numid} . "\n";
315 93         464 $numId = $+{numid};
316 93         412 ($type, $arg1, $arg2) = split / /, $info;
317 93         397 $arg1 =~ s/^Arg1://;
318 93         321 $arg2 =~ s/^Arg2://;
319 93         485 $self->_addRelation($id, {
320             'id' => $id,
321             'numId' => $numId,
322             'type' => $type,
323             'arg1' => $arg1,
324             'arg2' => $arg2,
325             });
326             }
327             }
328 21         229 close FILE;
329             }
330              
331             sub printStats {
332 0     0 1 0 my ($self, $filename, $addmode) = @_;
333              
334 0         0 my $id;
335             my %terms;
336 0         0 my %termTypes;
337 0         0 my %relations;
338 0         0 my %relationTypes;
339              
340 0         0 my $fh;
341 0 0       0 if ($filename eq "-") {
342 0         0 $fh = \*STDOUT;
343             } else {
344 0 0       0 if (defined $addmode) {
345 0 0       0 open $fh, ">>:utf8", $filename or die "no such file " . $filename . "\n";
346             } else {
347 0 0       0 open $fh, ">:utf8", $filename or die "no such file " . $filename . "\n";
348             }
349             }
350              
351 0         0 print $fh $self->getStats;
352              
353 0 0       0 if ($filename ne "-") {
354 0         0 close $fh;
355             }
356             }
357              
358             sub getTermTypes {
359 0     0 1 0 my ($self) = @_;
360              
361 0         0 my $id;
362             my %termTypes;
363 0         0 foreach $id (keys %{$self->_terms}) {
  0         0  
364 0         0 $termTypes{$self->_getTermFromId($id)->{'type'}}++;
365             }
366 0         0 return(%termTypes);
367             }
368              
369             sub getRelationTypes {
370 0     0 1 0 my ($self) = @_;
371              
372 0         0 my $id;
373             my %relationTypes;
374 0         0 foreach $id (keys %{$self->_relations}) {
  0         0  
375 0         0 $relationTypes{$self->_getRelationFromId($id)->{'type'}}++;
376             }
377 0         0 return(%relationTypes);
378             }
379              
380             sub getStats {
381 2     2 1 882 my ($self) = @_;
382              
383 2         16 my $id;
384             my %terms;
385 2         0 my %termTypes;
386 2         0 my %relations;
387 2         0 my %relationTypes;
388 2         0 my $stats;
389              
390 2         4 foreach $id (keys %{$self->_terms}) {
  2         7  
391 119         210 $terms{$self->_getTermFromId($id)->{'str'}}++;
392 119         215 $termTypes{$self->_getTermFromId($id)->{'type'}}++;
393             }
394            
395 2         10 foreach $id (keys %{$self->_relations}) {
  2         7  
396 23         54 $relations{$self->_getTermFromId($self->_getRelationFromId($id)->{'arg1'})->{'str'} . " : " . $self->_getTermFromId($self->_getRelationFromId($id)->{'arg2'})->{'str'}}++;
397 23         64 $relationTypes{$self->_getRelationFromId($id)->{'type'}}++;
398             }
399              
400              
401 2         9 $stats = "number of annotated terms: " . scalar(keys %{$self->_terms}) . "\n";
  2         8  
402 2         7 $stats .= "number of annotated relations: " . scalar(keys %{$self->_relations}) . "\n";
  2         8  
403              
404 2         11 $stats .= "number of terms: " . scalar(keys %terms) . "\n";
405 2         11 $stats .= "number of term type: " . scalar(keys %termTypes) . "\n";
406              
407 2         9 $stats .= "number of relations: " . scalar(keys %relations) . "\n";
408 2         16 $stats .= "number of relation type: " . scalar(keys %relationTypes) . "\n";
409 2         41 return($stats);
410             # print "number of relations: " . scalar(keys %{$data->{'relations'}}) . "\n";
411             }
412              
413              
414             sub printTermList {
415 0     0 1 0 my ($self, $filename, $addmode) = @_;
416 0         0 my $id;
417              
418             my $fh;
419 0 0       0 if ($filename eq "-") {
420 0         0 $fh = \*STDOUT;
421             } else {
422            
423 0 0       0 if (defined $addmode) {
424 0 0       0 open $fh, ">>:utf8", $filename or die "no such file " . $filename . "\n";
425             } else {
426 0 0       0 open $fh, ">:utf8", $filename or die "no such file " . $filename . "\n";
427             }
428             }
429             # foreach $id (keys %{$self->_terms}) {
430             # print $fh $self->_getTermFromId($id)->{'str'} . " : : " . $self->_getTermFromId($id)->{$id}->{'type'} . " :\n";
431             # }
432 0         0 print $fh $self->getTermList;
433              
434 0 0       0 if ($filename ne "-") {
435 0         0 close $fh;
436             }
437              
438             }
439              
440             sub getTermList {
441 2     2 1 1083 my ($self) = @_;
442 2         4 my $id;
443 2         7 my $termlistStr = "";
444              
445 2         4 foreach $id (keys %{$self->_terms}) {
  2         7  
446 119         208 $termlistStr .= $self->_getTermFromId($id)->{'str'} . " : : " . $self->_getTermFromId($id)->{'type'} . " :\n";
447             }
448 2         13 return($termlistStr);
449             }
450              
451              
452             sub getTerms {
453 4     4 1 723 my ($self) = @_;
454 4         9 my $id;
455             my @terms;
456              
457 4         8 foreach $id (keys %{$self->_terms}) {
  4         16  
458 104         229 push @terms, {"str" => $self->_getTermFromId($id)->{'str'}, "lmstr" => undef, "type" => $self->_getTermFromId($id)->{'type'}};
459             }
460 4         27 return(\@terms);
461             }
462              
463             sub printRelationList {
464 0     0 1 0 my ($self, $filename, $addmode) = @_;
465 0         0 my $fh;
466            
467 0 0       0 if ($filename eq "-") {
468 0         0 $fh = \*STDOUT;
469             } else {
470 0 0       0 if (defined $addmode) {
471 0 0       0 open $fh, ">>:utf8", $filename or die "no such file " . $filename . "\n";
472             } else {
473 0 0       0 open $fh, ">:utf8", $filename or die "no such file " . $filename . "\n";
474             }
475             }
476 0         0 print $fh $self->getRelationList;
477 0 0       0 if ($filename ne "-") {
478 0         0 close $fh;
479             }
480             }
481              
482             sub getRelationList {
483 2     2 1 952 my ($self, $addmode) = @_;
484 2         5 my $id;
485 2         28 my $relationList = "";
486            
487 2         5 foreach $id (keys %{$self->_relations}) {
  2         8  
488 23         55 $relationList .= $self->_getTermFromId($self->_getRelationFromId($id)->{'arg1'})->{'str'} . " : " . $self->_getTermFromId($self->_getRelationFromId($id)->{'arg2'})->{'str'} . " : " . $self->_getRelationFromId($id)->{'type'} . "\n";
489             }
490 2         10 return($relationList);
491             }
492              
493              
494             sub getRelations {
495 4     4 1 733 my ($self, $addmode) = @_;
496 4         8 my $id;
497 4         9 my $relationList = "";
498 4         10 my @relations;
499            
500 4         6 foreach $id (keys %{$self->_relations}) {
  4         15  
501             push @relations, {'str1' => $self->_getTermFromId($self->_getRelationFromId($id)->{'arg1'})->{'str'},
502             'str2' => $self->_getTermFromId($self->_getRelationFromId($id)->{'arg2'})->{'str'},
503 23         44 'type' => $self->_getRelationFromId($id)->{'type'}};
504             # $relationList .= $self->_getTermFromId($self->_getRelationFromId($id)->{'arg1'})->{'str'} . " : " . $self->_getTermFromId($self->_getRelationFromId($id)->{'arg2'})->{'str'} . " : " . $self->_getRelationFromId($id)->{'type'} . "\n";
505             }
506 4         19 return(\@relations);
507             }
508              
509              
510             sub getAnnotationList {
511 4     4 1 879 my ($self) = @_;
512 4         14 my $id;
513             my $attrId;
514 4         0 my $elt;
515 4         0 my $attr;
516 4         6 my $annotations = "";
517 4         7 my $i;
518              
519 4         5 foreach $id (sort {&_sortId($a,$b)} keys %{$self->_terms}) {
  1084         1331  
  4         11  
520 223         339 $elt = $self->_getTermFromId($id);
521 223         402 $annotations .= $elt->{'id'} . "\t";
522 223         369 $annotations .= $elt->{'type'} . " ";
523 223         295 for($i=0; $i < scalar(@{$elt->{'start'}}); $i++) {
  449         927  
524 226         518 $annotations .= $elt->{'start'}->[$i] . " " . $elt->{'end'}->[$i] . ";";
525             }
526 223         292 chop $annotations;
527            
528 223         413 $annotations .= "\t" . $elt->{'str'} . "\n";
529 223         275 foreach $attrId (sort {&_sortId($a,$b)} @{$elt->{'attrlst'}}) {
  0         0  
  223         410  
530 5         15 $attr = $self->_getAttributeFromId($attrId);
531 5         11 $annotations .= $attr->{'id'} . "\t";
532 5         20 $annotations .= $attr->{'type'} . " " . $attr->{'termId'} . " " . $attr->{'value'} . "\n";
533             }
534             }
535 4         14 foreach $id (sort {&_sortId($a,$b)} keys %{$self->_relations}) {
  87         121  
  4         12  
536 35         68 $elt = $self->_getRelationFromId($id);
537 35         67 $annotations .= $elt->{'id'} . "\t";
538 35         107 $annotations .= $elt->{'type'} . " Arg1:" . $elt->{'arg1'} . " Arg2:" . $elt->{'arg2'} . "\n";
539             }
540 4         37 return($annotations);
541             }
542              
543             sub _sortId {
544 1171     1171   1521 my ($A, $B) = @_;
545              
546 1171         1283 my $idA = $a;
547 1171         2064 $idA =~ s/^[TAR]//;
548 1171         1513 my $idB = $b;
549 1171         1930 $idB =~ s/^[TAR]//;
550 1171         1963 return($idA <=> $idB);
551             }
552              
553             sub print {
554 0     0 1   my ($self, $filename, $addmode) = @_;
555 0           my $fh;
556             my $line;
557 0           my $file;
558 0           my $annotationFilename = $filename;
559 0           $annotationFilename =~ s/\.txt$/.ann/;
560 0           my $textFilename = $filename;
561 0           $textFilename =~ s/\.ann$/.txt/;
562              
563             # print/copy text
564 0 0         if ($filename eq "-") {
565 0           $fh = \*STDOUT;
566             } else {
567 0 0         if (defined $addmode) {
568 0 0         open $fh, ">>:utf8", $textFilename or die "no such file $textFilename\n";
569             } else {
570 0 0         open $fh, ">:utf8", $textFilename or die "no such file $textFilename\n";
571             }
572             }
573 0           foreach $file (@{$self->_textFilename}) {
  0            
574 0 0         open FILE, $file or die "no such file " . $file . "\n";
575 0           while($line = ) {
576 0           print $fh $line;
577             }
578 0           close FILE;
579             }
580 0 0         if ($filename ne "-") {
581 0           close $fh;
582             }
583              
584             # print annotations
585 0 0         if ($filename eq "-") {
586 0           $fh = \*STDOUT;
587             } else {
588 0 0         if (defined $addmode) {
589 0 0         open $fh, ">>:utf8", $annotationFilename or die "no such file $annotationFilename\n";
590             } else {
591 0 0         open $fh, ">:utf8", $annotationFilename or die "no such file $annotationFilename\n";
592             }
593             }
594 0           print $fh $self->getAnnotationList;
595 0 0         if ($filename ne "-") {
596 0           close $fh;
597             }
598             }
599              
600             1;
601              
602             __END__