File Coverage

blib/lib/Brat/Handler.pm
Criterion Covered Total %
statement 177 294 60.2
branch 16 66 24.2
condition 7 9 77.7
subroutine 21 25 84.0
pod 11 11 100.0
total 232 405 57.2


line stmt bran cond sub pod time code
1             package Brat::Handler;
2              
3              
4 9     9   624421 use utf8;
  9         140  
  9         48  
5 9     9   307 use strict;
  9         23  
  9         225  
6 9     9   52 use warnings;
  9         25  
  9         348  
7 9     9   4460 use open qw(:utf8 :std);
  9         14313  
  9         72  
8              
9 9     9   5741 use Brat::Handler::File;
  9         39  
  9         33623  
10              
11             our $VERSION='0.11';
12              
13             sub new {
14              
15 6     6 1 608 my ($class) = @_;
16              
17 6         41 my $bratHandler = {
18             'inputDir' => undef,
19             # 'outputFile' => undef,
20             'inputFiles' => [],
21             'bratAnnotations' => [],
22             };
23 6         20 bless($bratHandler, $class);
24              
25 6         23 return($bratHandler);
26             }
27              
28             # sub _inputDir {
29             # my $self = shift;
30              
31             # if (@_) {
32             # $self->{'inputDir'} = shift;
33             # }
34             # return($self->{'inputDir'});
35             # }
36              
37             sub _scanDir {
38 4     4   12 my $self = shift;
39 4         11 my $inputDir = shift;
40 4         9 my $file;
41 4 50       19 if (defined ($inputDir)) {
42 4 50       181 opendir DIR, $inputDir or die "no such dir $inputDir\n";
43 4         110 while($file = readdir DIR) {
44 36 100 100     246 if (($file ne ".") && ($file ne "..") && ($file =~ /\.ann$/)) {
      100        
45 12         67 $self->_inputFiles($inputDir . "/$file");
46             }
47             }
48 4         74 closedir DIR;
49             }
50             }
51              
52              
53             # sub _outputFile {
54             # my $self = shift;
55              
56             # if (@_) {
57             # $self->{'outputFile'} = shift;
58             # }
59             # return($self->{'outputFile'});
60             # }
61              
62              
63             sub _inputFiles {
64 22     22   69 my $self = shift;
65              
66 22 100       75 if (@_) {
67 13         27 my $fileList = shift;
68 13 100       54 if (ref($fileList) eq 'ARRAY') {
69 1         1 push @{$self->{'inputFiles'}}, @$fileList;
  1         6  
70             } else {
71 12         20 push @{$self->{'inputFiles'}}, $fileList;
  12         50  
72             }
73             }
74 22         98 return($self->{'inputFiles'});
75             }
76              
77             sub _bratAnnotations {
78 25     25   51 my $self = shift;
79              
80 25 100       79 if (@_) {
81 15         30 my $bratAnn = shift;
82 15         30 push @{$self->{'bratAnnotations'}}, $bratAnn;
  15         81  
83             }
84 25         107 return($self->{'bratAnnotations'});
85             }
86              
87             sub _bratAnnotationSize {
88 4     4   7 my $self = shift;
89              
90 4         6 return(scalar(@{$self->_bratAnnotations}));
  4         8  
91             }
92              
93             sub _getBratAnnotationsFromId {
94 3     3   5 my $self = shift;
95            
96 3 50       8 if (@_) {
97 3         4 my $id = shift;
98 3         8 return $self->{'bratAnnotations'}->[$id];
99             }
100 0         0 return(undef);
101             }
102              
103             sub loadDir {
104 4     4 1 2820 my ($self, $inputDir) = @_;
105 4         10 my $file;
106              
107 4         26 $self->_scanDir($inputDir);
108 4         11 foreach $file (@{$self->_inputFiles}) {
  4         18  
109 12         53 $self->_bratAnnotations($self->loadFile($file));
110             }
111             }
112              
113             sub loadList {
114 1     1 1 596 my ($self, $list) = @_;
115 1         2 my $file;
116             my @files;
117 1 50       29 open LIST, $list or die "no such file $list\n";
118 1         19 @files = ;
119 1         3 map {chomp;} @files;
  3         7  
120 1         6 close LIST;
121 1         5 $self->_inputFiles(\@files);
122 1         2 foreach $file (@{$self->_inputFiles}) {
  1         2  
123 3         7 $self->_bratAnnotations($self->loadFile($file));
124             }
125             }
126              
127             sub loadFile {
128 15     15 1 49 my ($self, $file) = @_;
129            
130 15 50 33     133 if (($file =~ /\.ann$/) || ($file =~ /\.txt$/)) {
131 15         116 my $ann = Brat::Handler::File->new($file);
132 15         99 return($ann);
133             }
134 0         0 return(undef);
135             }
136              
137             sub concat {
138 1     1 1 9 my ($self) = @_;
139 1         4 my $i;
140 1         4 my $offset = 0;
141 1         3 my $termIdOffset = 0;
142 1         3 my $relationIdOffset = 0;
143 1         3 my $attributeIdOffset = 0;
144 1         23 my $currentBratAnnotations;
145 1         6 my $concatAnn = Brat::Handler::File->new();
146 1         3 my %Term2newTerm;
147 1         6 for($i=0; $i < $self->_bratAnnotationSize; $i++) {
148 3         12 %Term2newTerm = ();
149 3         11 $currentBratAnnotations = $self->_getBratAnnotationsFromId($i);
150             # warn "Read file: " . $currentBratAnnotations->_textFilename . "\n";
151 3         11 $self->_copyTermsWithOffsetShift($currentBratAnnotations, $concatAnn, $termIdOffset, $offset, \%Term2newTerm);
152 3         10 $self->_copyAttributesWithOffsetShift($currentBratAnnotations, $concatAnn, $attributeIdOffset, $offset, \%Term2newTerm);
153 3         10 $self->_copyRelationsWithOffsetShift($currentBratAnnotations, $concatAnn, $relationIdOffset, $offset, \%Term2newTerm);
154 3         8 $offset += $currentBratAnnotations->_textSize;
155 3         8 $termIdOffset += $currentBratAnnotations->_maxTermId;
156 3         7 $attributeIdOffset += $currentBratAnnotations->_maxAttributeId;
157 3         5 $relationIdOffset += $currentBratAnnotations->_maxRelationId;
158 3         4 $concatAnn->_textFilename(@{$currentBratAnnotations->_textFilename});
  3         7  
159 3         5 $concatAnn->_annotationFilename(@{$currentBratAnnotations->_annotationFilename});
  3         6  
160             }
161 1         3 $concatAnn->_textSize($offset);
162            
163              
164 1         6 return($concatAnn);
165             }
166              
167             sub _copyTermsWithOffsetShift {
168 3     3   7 my ($self, $ann, $concatAnn, $termIdOffset, $offset, $Term2newTerm) = @_;
169 3         21 my $elt;
170             my $id;
171 3         0 my $newNumId;
172 3         0 my @starts;
173 3         0 my @ends;
174 3         0 my @newStarts;
175 3         0 my @newEnds;
176 3         0 my $s;
177 3         0 my $e;
178 3         6 my $i = 0;
179              
180 3         4 foreach $id (keys %{$ann->_terms}) {
  3         13  
181 83         113 @newStarts = ();
182 83         101 @newEnds = ();
183 83         133 $elt = $ann->_getTermFromId($id);
184 83         132 $newNumId = $elt->{'numId'} + $termIdOffset;
185 83         192 $Term2newTerm->{$elt->{'id'}} = "T$newNumId";
186 83         101 foreach $s (@{$elt->{'start'}}) {
  83         140  
187 84         160 push @newStarts, ($s+$offset);
188             }
189 83         110 foreach $e (@{$elt->{'end'}}) {
  83         136  
190 84         131 push @newEnds, ($e+$offset);
191             }
192              
193             $concatAnn->_addTerm("T$newNumId", {
194             'id' => "T$newNumId",
195             'numId' => $newNumId,
196             'type' => $elt->{'type'},
197             'start' => [@newStarts],
198             'end' => [@newEnds],
199 83         524 'str' => $elt->{'str'},
200             'attrlst' => [], # TODO
201             });
202 83         140 $i++;
203             }
204 3         11 return($i);
205             }
206              
207             sub _copyAttributesWithOffsetShift {
208 3     3   6 my ($self, $ann, $concatAnn, $attributeIdOffset, $offset, $Term2newTerm) = @_;
209 3         9 my $attr;
210             my $id;
211 3         0 my $newNumId;
212 3         0 my $newTermId;
213              
214 3         4 foreach $id (keys %{$ann->_attributes}) {
  3         7  
215 2         6 $attr = $ann->_getAttributeFromId($id);
216 2         4 $newNumId = $attr->{'numId'} + $attributeIdOffset;
217             $concatAnn->_addAttribute("A$newNumId", {
218             'id' => "A$newNumId",
219             'numId' => $newNumId,
220             'type' => $attr->{'type'},
221             'termId' => $Term2newTerm->{$attr->{'termId'}},
222 2         14 'value' => $attr->{'value'},
223             });
224             # warn "termId: $start\n";
225 2         3 push @{$concatAnn->_getTermFromId($Term2newTerm->{$attr->{'termId'}})->{'attrlst'}}, "A$newNumId";
  2         5  
226             }
227             }
228              
229             sub _copyRelationsWithOffsetShift {
230 3     3   6 my ($self, $ann, $concatAnn, $relationIdOffset, $offset, $Term2newTerm) = @_;
231 3         9 my $relation;
232             my $id;
233 3         0 my $newNumId;
234 3         0 my $newTermId1;
235 3         0 my $newTermId2;
236              
237 3         3 foreach $id (keys %{$ann->_relations}) {
  3         8  
238 12         21 $relation = $ann->_getRelationFromId($id);
239 12         18 $newNumId = $relation->{'numId'} + $relationIdOffset;
240             $concatAnn->_addRelation("R$newNumId", {
241             'id' => "R$newNumId",
242             'numId' => $newNumId,
243             'type' => $relation->{'type'},
244             'arg1' => $Term2newTerm->{$relation->{'arg1'}},
245 12         56 'arg2' => $Term2newTerm->{$relation->{'arg2'}},
246             });
247             }
248            
249             }
250              
251             sub printTermList {
252 0     0 1 0 my ($self, $filename, $addmode) = @_;
253 0         0 my $id;
254              
255             my $fh;
256 0 0       0 if ($filename eq "-") {
257 0         0 $fh = \*STDOUT;
258             } else {
259            
260 0 0       0 if (defined $addmode) {
261 0 0       0 open $fh, ">>:utf8", $filename or die "no such file " . $filename . "\n";
262             } else {
263 0 0       0 open $fh, ">:utf8", $filename or die "no such file " . $filename . "\n";
264             }
265             }
266 0         0 print $fh $self->getTermList;
267              
268 0 0       0 if ($filename ne "-") {
269 0         0 close $fh;
270             }
271             }
272              
273             sub getTermList {
274 1     1 1 5 my ($self) = @_;
275 1         4 my $termlistStr = "";
276 1         6 my $bratFile;
277             my %termList;
278 1         0 my $term;
279              
280 1         3 foreach $bratFile (@{$self->_bratAnnotations}) {
  1         4  
281 3         8 foreach $term (@{$bratFile->getTerms}) {
  3         22  
282 83 100       23684 if (!exists $termList{$term->{'str'}}) {
283 74         397 $termList{lc($term->{'str'})} = {'str' => $term->{'str'}, 'lmstr' => undef, 'type' => {$term->{'type'} => 1}};
284             } else {
285 9         34 $termList{lc($term->{'str'})}->{'type'}->{$term->{'type'}}++;
286             }
287             }
288             }
289 1         23 foreach $term (keys %termList) {
290 74         137 $termlistStr .= $termList{$term}->{'str'} . " : : " . join(';', keys%{$termList{$term}->{'type'}}) . " :\n";
  74         206  
291             # foreach $id (keys %{$self->_terms}) {
292             # $termlistStr .= $self->_getTermFromId($id)->{'str'} . " : : " . $self->_getTermFromId($id)->{'type'} . " :\n";
293             }
294 1         42 return($termlistStr);
295             }
296              
297             sub getRelationList {
298 1     1 1 4 my ($self) = @_;
299 1         2 my $relation;
300 1         2 my $relationListStr = "";
301 1         3 my %relationList;
302             my $bratFile;
303 1         0 my $key;
304              
305 1         3 foreach $bratFile (@{$self->_bratAnnotations}) {
  1         3  
306 3         7 foreach $relation (@{$bratFile->getRelations}) {
  3         18  
307 12     2   142 $key = lc($relation->{'str1'} . '_' . $relation->{'str2'} . '_' . $relation->{'type'});
  2         28  
  2         11  
  2         32  
308 12 50       30956 if (!exists $relationList{$key}) {
309 12         74 $relationList{$key} = [$relation->{'str1'}, $relation->{'str2'}, $relation->{'type'}];
310             }
311             }
312             }
313            
314 1         12 foreach $key (keys %relationList) {
315 12         26 $relationListStr .= join(' : ', @{$relationList{$key}}) . "\n";
  12         63  
316             }
317 1         15 return($relationListStr);
318             }
319              
320             sub printRelationList {
321 0     0 1 0 my ($self, $filename, $addmode) = @_;
322 0         0 my $id;
323              
324             my $fh;
325 0 0       0 if ($filename eq "-") {
326 0         0 $fh = \*STDOUT;
327             } else {
328            
329 0 0       0 if (defined $addmode) {
330 0 0       0 open $fh, ">>:utf8", $filename or die "no such file " . $filename . "\n";
331             } else {
332 0 0       0 open $fh, ">:utf8", $filename or die "no such file " . $filename . "\n";
333             }
334             }
335 0         0 print $fh $self->getRelationList;
336              
337 0 0       0 if ($filename ne "-") {
338 0         0 close $fh;
339             }
340             }
341              
342             sub getStats {
343 0     0 1 0 my ($self) = @_;
344              
345 0         0 my $stats = "";
346 0         0 my $nbFiles;
347             my $bratFile;
348 0         0 my $nbTerms = 0;
349 0         0 my $nbRels = 0;
350 0         0 my $sumTextSize = 0;
351 0         0 my $minTextSize = 0;
352 0         0 my $maxTextSize = 0;
353 0         0 my $minTerms = 0;
354 0         0 my $maxTerms = 0;
355 0         0 my $minRels = 0;
356 0         0 my $maxRels = 0;
357              
358             # my %Terms;
359             # my %Relations;
360 0         0 my %termTypes;
361             my %relationTypes;
362 0         0 my %tmp;
363 0         0 my $k;
364              
365 0         0 $nbFiles = scalar(@{$self->_bratAnnotations});
  0         0  
366 0 0       0 if ($nbFiles > 0) {
367 0         0 $minTextSize = $self->_bratAnnotations->[0]->_textSize;
368 0         0 $minTerms = scalar(keys(%{$self->_bratAnnotations->[0]->_terms}));
  0         0  
369 0         0 $minRels = scalar(keys(%{$self->_bratAnnotations->[0]->_relations}));
  0         0  
370             }
371            
372 0         0 foreach $bratFile (@{$self->_bratAnnotations}) {
  0         0  
373 0         0 $sumTextSize += $bratFile->_textSize;
374 0 0       0 if ($minTextSize > $bratFile->_textSize) {
375 0         0 $minTextSize = $bratFile->_textSize
376             }
377 0 0       0 if ($maxTextSize < $bratFile->_textSize) {
378 0         0 $maxTextSize = $bratFile->_textSize
379             }
380 0         0 $nbTerms += scalar(keys(%{$bratFile->_terms}));
  0         0  
381 0 0       0 if ($minTerms > scalar(keys(%{$bratFile->_terms}))) {
  0         0  
382 0         0 $minTerms = scalar(keys(%{$bratFile->_terms}));
  0         0  
383             }
384 0 0       0 if ($maxTerms < scalar(keys(%{$bratFile->_terms}))) {
  0         0  
385 0         0 $maxTerms = scalar(keys(%{$bratFile->_terms}));
  0         0  
386             }
387 0         0 $nbRels += scalar(keys(%{$bratFile->_relations}));
  0         0  
388 0 0       0 if ($minRels > scalar(keys(%{$bratFile->_relations}))) {
  0         0  
389 0         0 $minRels = scalar(keys(%{$bratFile->_relations}));
  0         0  
390             }
391 0 0       0 if ($maxRels < scalar(keys(%{$bratFile->_relations}))) {
  0         0  
392 0         0 $maxRels = scalar(keys(%{$bratFile->_relations}));
  0         0  
393             }
394 0         0 %tmp = $bratFile->getTermTypes;
395 0         0 foreach $k (keys %tmp) {
396 0         0 $termTypes{$k}+=$tmp{$k};
397             }
398 0         0 %tmp = $bratFile->getRelationTypes;
399 0         0 foreach $k (keys %tmp) {
400 0         0 $relationTypes{$k}+=$tmp{$k};
401             }
402             # map {$relationTypes{$_}++;} $bratFile->getRelationTypes;
403             }
404            
405 0         0 $stats .= "Number of documents: $nbFiles\n";
406 0         0 $stats .= "Text Size sum: $sumTextSize\n";
407 0         0 $stats .= "Number of Terms: $nbTerms\n";
408 0         0 $stats .= "Number of Relations: $nbRels\n";
409 0         0 $stats .= "\n";
410 0         0 $stats .= "Minimal Text Size: $minTextSize\n";
411 0         0 $stats .= "Maximal Text Size: $maxTextSize\n";
412 0         0 $stats .= "Average of Text Size: " . ($sumTextSize/$nbFiles) . "\n";
413 0         0 $stats .= "\n";
414 0         0 $stats .= "Minimal number of Terms: $minTerms\n";
415 0         0 $stats .= "Maximal number of Terms: $maxTerms\n";
416 0         0 $stats .= "Average number of Terms: " . ($nbTerms/$nbFiles) . "\n";
417 0         0 $stats .= "\n";
418 0         0 $stats .= "Minimal number of Relations: $minRels\n";
419 0         0 $stats .= "Maximal number of Relations: $maxRels\n";
420 0         0 $stats .= "Average number of Relations: " . ($nbRels/$nbFiles) . "\n";
421 0         0 $stats .= "\n";
422 0         0 $stats .= "Term types:" . "\n";
423 0         0 foreach $k (sort keys %termTypes) {
424 0         0 $stats .= "\t$k: " . $termTypes{$k} . "\n";
425             }
426 0         0 $stats .= "\n";
427 0         0 $stats .= "Relation types:" . "\n";
428 0         0 foreach $k (sort keys %relationTypes) {
429 0         0 $stats .= "\t$k: " . $relationTypes{$k} . "\n";
430             }
431            
432             # $stats .= "" . "\n";
433             # $stats .= "" . "\n";
434             # $stats .= "" . "\n";
435             # $stats .= "" . "\n";
436             # $stats .= "" . "\n";
437              
438              
439 0         0 return($stats);
440             }
441              
442             sub printStats {
443 0     0 1 0 my ($self, $filename, $addmode) = @_;
444              
445 0         0 my $id;
446             my %terms;
447 0         0 my %termTypes;
448 0         0 my %relations;
449 0         0 my %relationTypes;
450              
451 0         0 my $fh;
452 0 0       0 if ($filename eq "-") {
453 0         0 $fh = \*STDOUT;
454             } else {
455 0 0       0 if (defined $addmode) {
456 0 0       0 open $fh, ">>:utf8", $filename or die "no such file " . $filename . "\n";
457             } else {
458 0 0       0 open $fh, ">:utf8", $filename or die "no such file " . $filename . "\n";
459             }
460             }
461              
462 0         0 print $fh $self->getStats;
463              
464 0 0       0 if ($filename ne "-") {
465 0         0 close $fh;
466             }
467             }
468              
469              
470             1;
471              
472             __END__