File Coverage

blib/lib/Brat/Handler/File.pm
Criterion Covered Total %
statement 208 310 67.1
branch 43 114 37.7
condition 3 9 33.3
subroutine 27 31 87.1
pod 10 10 100.0
total 291 474 61.3


line stmt bran cond sub pod time code
1             package Brat::Handler::File;
2              
3              
4 6     6   44 use utf8;
  6         10  
  6         226  
5 6     6   624 use strict;
  6         207  
  6         357  
6 6     6   272 use warnings;
  6         20  
  6         805  
7 6     6   25 use open qw(:utf8 :std);
  6         12  
  6         36  
8              
9             our $VERSION='0.1';
10              
11             sub new {
12              
13 17     17 1 1973 my ($class, $filename) = @_;
14 17         24 my $annotationFilename;
15             my $textFilename;
16 17         25 my $textSize = 0;
17 17         23 my @annFiles;
18             my @textFiles;
19 0         0 my @files;
20 0         0 my $f;
21 0         0 my $line;
22              
23             # print STDERR "\n==> $filename - " . ref($filename) . ";\n";
24 17 100       46 if (defined $filename) {
25 13 50       35 if (ref($filename) eq "") {
    0          
26 13         24 push @files, $filename;
27             } elsif (ref($filename) eq "ARRAY") {
28 0         0 push @files, @$filename;
29             }
30             }
31 17         31 foreach $f (@files) {
32             # warn "$f\n";
33 13         17 $annotationFilename = $f;
34 13         31 $annotationFilename =~ s/\.txt$/.ann/;
35 13         17 $textFilename = $f;
36 13         56 $textFilename =~ s/\.ann$/.txt/;
37 13         18 $textSize = 0;
38 13 50       401 open FILE, $textFilename or die "no such file $textFilename\n";
39 13         265 while($line = ) {
40 26         220 $textSize += length($line);
41             }
42 13         77 close FILE;
43             # my @s = stat($textFilename);
44             # $textSize += $s[7];
45 13         26 push @annFiles, $annotationFilename;
46 13         31 push @textFiles, $textFilename;
47             }
48 17         139 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 17         39 bless($bratfile, $class);
61              
62 17 100       39 if (defined $filename) {
63 13 50       31 if (ref($filename) eq "") {
    0          
64 13         73 $bratfile->loadBratFile;
65             } elsif (ref($filename) eq "ARRAY") {
66 0         0 warn "load of several brat files not implemented\n";
67             }
68             }
69 17         79 return($bratfile);
70             }
71              
72             sub _textFilename {
73 6     6   9 my $self = shift;
74              
75 6 100       11 if (@_) {
76 3         5 my $arg = shift;
77 3         3 push @{$self->{'textFilename'}}, $arg;
  3         6  
78             }
79 6         14 return($self->{'textFilename'});
80             }
81              
82             sub _textSize {
83 7     7   298 my $self = shift;
84              
85 7 100       18 if (@_) {
86 1         2 $self->{'textSize'} = shift;
87             }
88 7         21 return($self->{'textSize'});
89             }
90              
91             sub _annotationFilename {
92 19     19   25 my $self = shift;
93 19 100       43 if (@_) {
94 16         20 my $arg = shift;
95 16 100       69 if ($arg =~ /^\d+$/) {
96 13         331 return($self->{'annotationFilename'}->[$arg]);
97             } else {
98 3         3 push @{$self->{'annotationFilename'}}, $arg;
  3         7  
99             }
100             }
101 6         18 return($self->{'annotationFilename'});
102             }
103              
104             sub _terms {
105 3943     3943   4509 my $self = shift;
106              
107 3943 50       6348 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 3943         10880 return($self->{'terms'});
118             }
119              
120             sub _addTerm {
121 446     446   513 my $self = shift;
122              
123 446 50       870 if (@_) {
124 446         479 my $id = shift;
125 446         809 $self->_terms->{$id} = shift;
126             # max Term Id
127 446 100       844 if ($self->_maxTermId < $self->_terms->{$id}->{'numId'}) {
128 376         618 $self->_maxTermId($self->_terms->{$id}->{'numId'});
129             }
130 446         946 return($self->_getTermFromId($id));
131             }
132 0         0 return(undef);
133             }
134              
135             sub _maxTermId {
136 827     827   1139 my $self = shift;
137              
138 827 100       1381 if (@_) {
139 376         547 $self->{'maxTermId'} = shift;
140             }
141 827         1546 return($self->{'maxTermId'});
142             }
143              
144             sub _getTermFromId {
145 1330     1330   1387 my $self = shift;
146 1330         1439 my $id = shift;
147              
148 1330 50 33     3582 if ((defined $id) && (exists $self->_terms->{$id})) {
149 1330         2222 return($self->_terms->{$id});
150             }
151             }
152              
153             sub _relations {
154 726     726   714 my $self = shift;
155              
156 726 50       1175 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 726         2152 return($self->{'relations'});
166             }
167              
168             sub _addRelation {
169 70     70   81 my $self = shift;
170              
171 70 50       139 if (@_) {
172 70         79 my $id = shift;
173 70         125 $self->_relations->{$id} = shift;
174             # max Relation Id
175             # warn $self->_maxRelationId . " < " . $self->_relations->{$id}->{'numId'} . "\n";
176 70 100       134 if ($self->_maxRelationId < $self->_relations->{$id}->{'numId'}) {
177 61         105 $self->_maxRelationId($self->_relations->{$id}->{'numId'});
178             }
179 70         145 return($self->_getRelationFromId($id));
180             }
181 0         0 return(undef);
182             }
183              
184             sub _maxRelationId {
185 136     136   145 my $self = shift;
186              
187 136 100       262 if (@_) {
188 61         138 $self->{'maxRelationId'} = shift;
189             }
190 136         267 return($self->{'maxRelationId'});
191             }
192              
193             sub _getRelationFromId {
194 255     255   341 my $self = shift;
195 255         306 my $id = shift;
196              
197 255 50 33     670 if ((defined $id) && (exists $self->_relations->{$id})) {
198 255         441 return($self->_relations->{$id});
199             }
200             }
201              
202             sub _attributes {
203 69     69   90 my $self = shift;
204              
205 69 50       124 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 69         210 return($self->{'attributes'});
215             }
216              
217             sub _addAttribute {
218 10     10   18 my $self = shift;
219              
220 10 50       28 if (@_) {
221 10         19 my $id = shift;
222 10         30 $self->_attributes->{$id} = shift;
223             # max Attribute Id
224 10 50       46 if ($self->_maxAttributeId < $self->_attributes->{$id}->{'numId'}) {
225 10         22 $self->_maxAttributeId($self->_attributes->{$id}->{'numId'});
226             }
227 10         25 return($self->_getAttributeFromId($id));
228             }
229 0         0 return(undef);
230             }
231              
232             sub _maxAttributeId {
233 25     25   70 my $self = shift;
234              
235 25 100       52 if (@_) {
236 10         21 $self->{'maxAttributeId'} = shift;
237             }
238 25         60 return($self->{'maxAttributeId'});
239             }
240              
241             sub _getAttributeFromId {
242 17     17   23 my $self = shift;
243 17         23 my $id = shift;
244              
245 17 50 33     62 if ((defined $id) && (exists $self->_attributes->{$id})) {
246 17         33 return($self->_attributes->{$id});
247             }
248             }
249              
250             sub loadBratFile {
251 13     13 1 23 my ($self) = @_;
252 13         18 my $line;
253             my $id;
254 0         0 my $info;
255 0         0 my $str;
256 0         0 my $type;
257 0         0 my $termId;
258 0         0 my $value;
259 0         0 my $arg1;
260 0         0 my $arg2;
261 0         0 my $o;
262 0         0 my $s;
263 0         0 my $e;
264 0         0 my @starts;
265 0         0 my @ends;
266 0         0 my $numId;
267             # warn "===> " . $self->_filename . "\n";
268 13 50       40 open FILE, "<:utf8", $self->_annotationFilename(0) or die "no such file " . $self->_annotationFilename(0) . "\n";
269 13         171 while($line = ) {
270 429         488 chomp $line;
271 429         632 @starts = ();
272 429         487 @ends = ();
273              
274 429         1246 ($id, $info, $str) = split /\t/, $line;
275             # warn "$id\n";
276 429 100       1354 if ($id =~ /^T(?\d+)/) {
277 6     6   27306 $numId = $+{numid};
  6         9174  
  6         16483  
  363         1432  
278             # ($type, $start, $end) = split / /, $info;
279             # warn "info: $info\n";
280 363 50       1427 if ($info =~ /^(?[^ ]+) (?.*)/) {
281 363         1214 $type = $+{type};
282 363         1602 foreach $o (split /;/, $+{offsets}) {
283 368         1037 ($s, $e) = split / /, $o;
284             # warn "\t$s : $e\n";
285 368         608 push @starts, $s;
286 368         598 push @ends, $e;
287             }
288             # warn "->$id\n";
289 363         2553 $self->_addTerm($id, {
290             'id' => $id,
291             'numId' => $numId,
292             'type' => $type,
293             'start' => [@starts],
294             'end' => [@ends],
295             'str' => $str,
296             'attrlst' => [],
297             });
298             }
299             }
300 429 100       955 if ($id =~ /^A(?\d+)/) {
301 8         35 $numId = $+{numid};
302 8         37 ($type, $termId, $value) = split / /, $info;
303 8         58 $self->_addAttribute($id, {
304             'id' => $id,
305             'numId' => $numId,
306             'type' => $type,
307             'termId' => $termId,
308             'value' => $value,
309             });
310             # warn "termId: $start\n";
311 8         13 push @{$self->_getTermFromId($termId)->{'attrlst'}}, $id;
  8         21  
312            
313             }
314 429 100       1415 if ($id =~ /^R(?\d+)/) {
315             # warn "==> $id " . $+{numid} . "\n";
316 58         224 $numId = $+{numid};
317 58         194 ($type, $arg1, $arg2) = split / /, $info;
318 58         174 $arg1 =~ s/^Arg1://;
319 58         159 $arg2 =~ s/^Arg2://;
320 58         306 $self->_addRelation($id, {
321             'id' => $id,
322             'numId' => $numId,
323             'type' => $type,
324             'arg1' => $arg1,
325             'arg2' => $arg2,
326             });
327             }
328             }
329 13         105 close FILE;
330             }
331              
332             sub printStats {
333 0     0 1 0 my ($self, $filename, $addmode) = @_;
334              
335 0         0 my $id;
336             my %terms;
337 0         0 my %termTypes;
338 0         0 my %relations;
339 0         0 my %relationTypes;
340              
341 0         0 my $fh;
342 0 0       0 if ($filename eq "-") {
343 0         0 $fh = \*STDOUT;
344             } else {
345 0 0       0 if (defined $addmode) {
346 0 0       0 open $fh, ">>:utf8", $filename or die "no such file " . $filename . "\n";
347             } else {
348 0 0       0 open $fh, ">:utf8", $filename or die "no such file " . $filename . "\n";
349             }
350             }
351              
352 0         0 print $fh $self->getStats;
353              
354 0 0       0 if ($filename ne "-") {
355 0         0 close $fh;
356             }
357             }
358              
359             sub getStats {
360 2     2 1 614 my ($self) = @_;
361              
362 2         3 my $id;
363             my %terms;
364 0         0 my %termTypes;
365 0         0 my %relations;
366 0         0 my %relationTypes;
367 0         0 my $stats;
368              
369 2         4 foreach $id (keys %{$self->_terms}) {
  2         6  
370 119         214 $terms{$self->_getTermFromId($id)->{'str'}}++;
371 119         236 $termTypes{$self->_getTermFromId($id)->{'type'}}++;
372             }
373            
374 2         10 foreach $id (keys %{$self->_relations}) {
  2         6  
375 23         44 $relations{$self->_getTermFromId($self->_getRelationFromId($id)->{'arg1'})->{'str'} . " : " . $self->_getTermFromId($self->_getRelationFromId($id)->{'arg2'})->{'str'}}++;
376 23         59 $relationTypes{$self->_getRelationFromId($id)->{'type'}}++;
377             }
378              
379              
380 2         9 $stats = "number of annotated terms: " . scalar(keys %{$self->_terms}) . "\n";
  2         6  
381 2         4 $stats .= "number of annotated relations: " . scalar(keys %{$self->_relations}) . "\n";
  2         7  
382              
383 2         13 $stats .= "number of terms: " . scalar(keys %terms) . "\n";
384 2         7 $stats .= "number of term type: " . scalar(keys %termTypes) . "\n";
385              
386 2         13 $stats .= "number of relations: " . scalar(keys %relations) . "\n";
387 2         7 $stats .= "number of relation type: " . scalar(keys %relationTypes) . "\n";
388 2         35 return($stats);
389             # print "number of relations: " . scalar(keys %{$data->{'relations'}}) . "\n";
390             }
391              
392              
393             sub printTermList {
394 0     0 1 0 my ($self, $filename, $addmode) = @_;
395 0         0 my $id;
396              
397             my $fh;
398 0 0       0 if ($filename eq "-") {
399 0         0 $fh = \*STDOUT;
400             } else {
401            
402 0 0       0 if (defined $addmode) {
403 0 0       0 open $fh, ">>:utf8", $filename or die "no such file " . $filename . "\n";
404             } else {
405 0 0       0 open $fh, ">:utf8", $filename or die "no such file " . $filename . "\n";
406             }
407             }
408             # foreach $id (keys %{$self->_terms}) {
409             # print $fh $self->_getTermFromId($id)->{'str'} . " : : " . $self->_getTermFromId($id)->{$id}->{'type'} . " :\n";
410             # }
411 0         0 print $fh $self->getTermList;
412              
413 0 0       0 if ($filename ne "-") {
414 0         0 close $fh;
415             }
416              
417             }
418              
419             sub getTermList {
420 2     2 1 689 my ($self) = @_;
421 2         5 my $id;
422 2         4 my $termlistStr = "";
423              
424 2         3 foreach $id (keys %{$self->_terms}) {
  2         9  
425 119         264 $termlistStr .= $self->_getTermFromId($id)->{'str'} . " : : " . $self->_getTermFromId($id)->{'type'} . " :\n";
426             }
427 2         14 return($termlistStr);
428             }
429              
430              
431              
432             sub printRelationList {
433 0     0 1 0 my ($self, $filename, $addmode) = @_;
434 0         0 my $fh;
435            
436 0 0       0 if ($filename eq "-") {
437 0         0 $fh = \*STDOUT;
438             } else {
439 0 0       0 if (defined $addmode) {
440 0 0       0 open $fh, ">>:utf8", $filename or die "no such file " . $filename . "\n";
441             } else {
442 0 0       0 open $fh, ">:utf8", $filename or die "no such file " . $filename . "\n";
443             }
444             }
445 0         0 print $fh $self->getRelationList;
446 0 0       0 if ($filename ne "-") {
447 0         0 close $fh;
448             }
449             }
450              
451             sub getRelationList {
452 2     2 1 709 my ($self, $addmode) = @_;
453 2         4 my $id;
454 2         4 my $relationList = "";
455            
456 2         3 foreach $id (keys %{$self->_relations}) {
  2         7  
457 23         40 $relationList .= $self->_getTermFromId($self->_getRelationFromId($id)->{'arg1'})->{'str'} . " : " . $self->_getTermFromId($self->_getRelationFromId($id)->{'arg2'})->{'str'} . " : " . $self->_getRelationFromId($id)->{'type'} . "\n";
458             }
459 2         8 return($relationList);
460             }
461              
462             sub getAnnotationList {
463 4     4 1 858 my ($self) = @_;
464 4         7 my $id;
465             my $attrId;
466 0         0 my $elt;
467 0         0 my $attr;
468 4         7 my $annotations = "";
469 4         5 my $i;
470              
471 4         7 foreach $id (sort {&_sortId($a,$b)} keys %{$self->_terms}) {
  1061         1279  
  4         12  
472 223         397 $elt = $self->_getTermFromId($id);
473 223         414 $annotations .= $elt->{'id'} . "\t";
474 223         370 $annotations .= $elt->{'type'} . " ";
475 223         289 for($i=0; $i < scalar(@{$elt->{'start'}}); $i++) {
  449         963  
476 226         588 $annotations .= $elt->{'start'}->[$i] . " " . $elt->{'end'}->[$i] . ";";
477             }
478 223         241 chop $annotations;
479            
480 223         425 $annotations .= "\t" . $elt->{'str'} . "\n";
481 223         245 foreach $attrId (sort {&_sortId($a,$b)} @{$elt->{'attrlst'}}) {
  0         0  
  223         447  
482 5         12 $attr = $self->_getAttributeFromId($attrId);
483 5         12 $annotations .= $attr->{'id'} . "\t";
484 5         19 $annotations .= $attr->{'type'} . " " . $attr->{'termId'} . " " . $attr->{'value'} . "\n";
485             }
486             }
487 4         16 foreach $id (sort {&_sortId($a,$b)} keys %{$self->_relations}) {
  81         106  
  4         10  
488 35         59 $elt = $self->_getRelationFromId($id);
489 35         66 $annotations .= $elt->{'id'} . "\t";
490 35         113 $annotations .= $elt->{'type'} . " Arg1:" . $elt->{'arg1'} . " Arg2:" . $elt->{'arg2'} . "\n";
491             }
492 4         32 return($annotations);
493             }
494              
495             sub _sortId {
496 1142     1142   1212 my ($A, $B) = @_;
497              
498 1142         1241 my $idA = $a;
499 1142         2088 $idA =~ s/^[TAR]//;
500 1142         1319 my $idB = $b;
501 1142         1885 $idB =~ s/^[TAR]//;
502 1142         1956 return($idA <=> $idB);
503             }
504              
505             sub print {
506 0     0 1   my ($self, $filename, $addmode) = @_;
507 0           my $fh;
508             my $line;
509 0           my $file;
510 0           my $annotationFilename = $filename;
511 0           $annotationFilename =~ s/\.txt$/.ann/;
512 0           my $textFilename = $filename;
513 0           $textFilename =~ s/\.ann$/.txt/;
514              
515             # print/copy text
516 0 0         if ($filename eq "-") {
517 0           $fh = \*STDOUT;
518             } else {
519 0 0         if (defined $addmode) {
520 0 0         open $fh, ">>:utf8", $textFilename or die "no such file $textFilename\n";
521             } else {
522 0 0         open $fh, ">:utf8", $textFilename or die "no such file $textFilename\n";
523             }
524             }
525 0           foreach $file (@{$self->_textFilename}) {
  0            
526 0 0         open FILE, $file or die "no such file " . $file . "\n";
527 0           while($line = ) {
528 0           print $fh $line;
529             }
530 0           close FILE;
531             }
532 0 0         if ($filename ne "-") {
533 0           close $fh;
534             }
535              
536             # print annotations
537 0 0         if ($filename eq "-") {
538 0           $fh = \*STDOUT;
539             } else {
540 0 0         if (defined $addmode) {
541 0 0         open $fh, ">>:utf8", $annotationFilename or die "no such file $annotationFilename\n";
542             } else {
543 0 0         open $fh, ">:utf8", $annotationFilename or die "no such file $annotationFilename\n";
544             }
545             }
546 0           print $fh $self->getAnnotationList;
547 0 0         if ($filename ne "-") {
548 0           close $fh;
549             }
550             }
551              
552             1;
553              
554             __END__