File Coverage

blib/lib/Lingua/YaTeA/Corpus.pm
Criterion Covered Total %
statement 405 766 52.8
branch 100 236 42.3
condition 45 117 38.4
subroutine 52 73 71.2
pod 49 56 87.5
total 651 1248 52.1


line stmt bran cond sub pod time code
1             package Lingua::YaTeA::Corpus;
2 3     3   56059 use strict;
  3         13  
  3         74  
3 3     3   14 use warnings;
  3         6  
  3         64  
4 3     3   506 use Data::Dumper;
  3         5494  
  3         125  
5 3     3   414 use UNIVERSAL;
  3         14  
  3         20  
6 3     3   88 use Scalar::Util qw(blessed);
  3         6  
  3         115  
7 3     3   15 use File::Path;
  3         5  
  3         139  
8 3     3   1461 use POSIX qw(log10);
  3         15786  
  3         14  
9              
10 3     3   4901 use Lingua::YaTeA::ForbiddenStructureMark;
  3         7  
  3         27  
11 3     3   1058 use Lingua::YaTeA::TestifiedTermMark;
  3         7  
  3         64  
12 3     3   1038 use Lingua::YaTeA::Sentence;
  3         6  
  3         26  
13 3     3   1052 use Lingua::YaTeA::Lexicon;
  3         6  
  3         24  
14 3     3   1029 use Lingua::YaTeA::DocumentSet;
  3         7  
  3         30  
15 3     3   1005 use Lingua::YaTeA::SentenceSet;
  3         7  
  3         976  
16 3     3   1083 use Lingua::YaTeA::WordFromCorpus;
  3         7  
  3         12  
17 3     3   381 use Lingua::YaTeA::XMLEntities;
  3         5  
  3         17  
18              
19 3     3   521 use Encode qw(:fallbacks);;
  3         7715  
  3         20494  
20              
21              
22             our $VERSION=$Lingua::YaTeA::VERSION;
23              
24             our $forbidden_counter = 0;
25             our $tt_counter = 0;
26             our $split_counter = 0;
27              
28              
29             sub new
30             {
31 3     3 1 12 my ($class,$path,$option_set,$message_set) = @_;
32 3         6 my $this = {};
33 3         8 bless ($this,$class);
34 3         14 $this->{PATH} = $path;
35 3         7 $this->{NAME} = ();
36 3         20 $this->{LEXICON} = Lingua::YaTeA::Lexicon->new;
37 3         19 $this->{DOCUMENTS} = Lingua::YaTeA::DocumentSet->new;
38 3         20 $this->{SENTENCES} = Lingua::YaTeA::SentenceSet->new;
39 3         14 $this->{WORDS} = [];
40 3         10 $this->{OUTPUTS} = ();
41 3         13 $this->setName;
42              
43              
44 3         12 $this->setOutputFiles($option_set,$message_set);
45 3         9 return $this;
46             }
47              
48             sub preLoadLexicon
49             {
50 1     1 1 3 my ($this,$sentence_boundary,$document_boundary,$match_type) = @_;
51 1         4 my $fh = $this->getFileHandle;
52 1         2 my $word;
53             my %lexicon;
54 1         5 while (! $fh->eof)
55             {
56 299         5110 $word = $fh->getline;
57 299 100 100     6450 if(
      66        
58             ($word=~ /^([^\t]+)\t([^\t]+)\t([^\t]+)$/)
59             &&
60             ($2 ne $sentence_boundary)
61             &&
62             ($2 ne $document_boundary)
63             )
64             {
65 288 50       434 if($match_type ne "strict")
66             {
67 288         554 $lexicon{lc($1)}++; # record IF
68 288 50       391 if($match_type eq "loose")
69             {
70 288         660 $lexicon{lc($3)}++; # record LF
71             }
72             }
73             else
74             {
75 0         0 $lexicon{lc($1)."~".$2}++; # record IF + POS
76             }
77             }
78             }
79 1         26 return \%lexicon;
80             }
81              
82              
83             sub _normalizeInputCorpusLine {
84 20     20   1262 my ($this, $block, $language) = @_;
85              
86 20         44 my $line;
87             my @elems;
88 20         0 my @elems_out;
89 20         28 my $new_block = "";
90            
91 20         25 my @septags;
92              
93 20 50 33     76 if ((defined $language) && ($language eq "FR-Flemm")) {
94 0         0 foreach $line (split /\n/, $block) {
95 0         0 $line =~ s/
96 0         0 $line =~ s/>/SUP/go;
97 0         0 $line =~ s/\t:\t/\tCOLUMN\t/go;
98            
99 0         0 @elems = split /\t/, $line;
100              
101             # warn "-> $line" . scalar(@elems) . "\n";
102              
103              
104 0 0       0 if (scalar(@elems) > 3) {
105             # ambiguity in the pos tagging
106 0         0 my @tmp = split /\s\|\|\s/, $elems[2];
107 0         0 $elems[2] = shift @tmp;
108 0         0 $#elems = 2;
109             }
110 0 0       0 if (scalar(@elems) == 3) {
111 0         0 @septags = split /:/, $elems[1];
112 0         0 my $tag;
113 0 0       0 if (scalar(@septags) == 2) {
    0          
114 0         0 $tag = $septags[1];
115             } elsif (scalar(@septags) == 3) {
116 0         0 $tag = $septags[2];
117             } else {
118 0         0 $tag = $septags[0];
119             }
120             # if the tag is PUN(cit)
121 0 0       0 if ($tag eq "PUN(CIT)") {
122 0         0 $tag = "PUN";
123             }
124             # if the tag is Sp+Da, it is transformed as SpDa
125 0         0 $tag =~ s/\+D/D/;
126             # if the word is 'une', the postag is corrected
127 0 0       0 if ($elems[0] eq "une") {
128 0         0 $tag = "Da3fs---";
129             }
130             # if it's a present participle, the postag is then Vmpp-----
131 0 0       0 if ($tag =~ /Vmpp/) {
132 0         0 $tag = "Vmpp-----";
133             }
134             # if the word is 'l', the postag is corrected
135 0 0       0 if (lc($elems[0]) eq "l") {
136 0         0 $tag = "Da3-s---";
137             }
138 0         0 $elems[1] = $tag;
139             }
140 0 0       0 if (scalar(@elems) == 3) {
141 0         0 $new_block .= join("\t", @elems) . "\n";
142             }
143             }
144 0         0 return($new_block);
145             } else {
146             # warn "Language is $language, so nothing to do\n";
147              
148             # foreach $line (split /\n/, $block) {
149             # $line =~ s/
150             # $line =~ s/>/SUP/go;
151             # $line =~ s/\t:\t/\tCOLUMN\t/go;
152             # $line =~ s/\t\t+/\t/go;
153             # if($line !~ /^[^\t]*\t[^\t]+\t[^\t]*$/o){
154             # # warn "***********************************\n";
155             # # warn "Start correction of the line: $line\n";
156             # @elems = split /\t/, $line;
157             # if (scalar(@elems) > 3) {
158             # # ambiguity in the pos tagging
159             # # my @tmp = split /\s\|\|\s/, $elems[2];
160             # # $elems[2] = shift @tmp;
161             # $#elems = 2;
162             # } else {
163             # if (defined $elems[0]) {
164             # $elems[2] = $elems[0];
165             # if (!defined $elems[1]) {
166             # # $elems[1] = 'SYM';
167             # $elems[1] = $elems[0];
168             # }
169             # } else {
170             # @elems =();
171             # }
172              
173             # }
174             # if (scalar(@elems) == 3) {
175             # $new_block .= join("\t", @elems) . "\n";
176             # }
177             # } else {
178             # $new_block .= $line . "\n";
179             # }
180             # }
181             # $new_block .= join("\t", @elems) . "\n";
182             # return($new_block);
183 20         56 return($block);
184             }
185             }
186              
187              
188             sub read
189             {
190 2     2 1 7 my ($this,$sentence_boundary,$document_boundary,$FS_set,$testified_set,$match_type,$message_set,$display_language, $language,$debug_fh) = @_;
191 2         4 my $num_line = 0;
192 2         6 my $fh = $this->getFileHandle;
193 2         5 my $block;
194            
195             # local $/ = "\.\t". $sentence_boundary ."\t\.\n";
196 2         7 $this->getSentenceSet->addSentence($this->getDocumentSet);
197 2         8 while (! $fh->eof)
198             {
199 20         187 $block = $this->_normalizeInputCorpusLine(Encode::decode("UTF-8", $this->readSentence($fh,$sentence_boundary)), $language);
200 20         61 $this->WrapBlock(\$block);
201 20         56 $this->MarkForbiddenStructures(\$block,$FS_set);
202 20         71 $this->MarkTestifiedTerms(\$block,$testified_set,$match_type,$debug_fh);
203 20         54 $this->UnwrapBlock(\$block);
204            
205 20         53 $this->recordWords($block,$sentence_boundary,$document_boundary,\$num_line,$message_set,$display_language);
206             }
207             }
208              
209             sub readSentence {
210 20     20 0 35 my ($this, $fh, $sentence_boundary) = @_;
211              
212             # warn "in readsentence\n";
213 20         28 my $line;
214             my $sentence;
215 20 50       35 if (! $fh->eof) {
216 20   100     87 do {
217 598         11254 $line = $fh->getline;
218             # warn "line: $line;\n";
219 598         10734 $sentence .= $this->correctInputLine($line);
220             # $sentence .= $line;
221             } while ((!$fh->eof) && (index($line, "\t$sentence_boundary\t") == -1));
222             # warn "sentence: $sentence\n";
223             }
224 20         214 return($sentence);
225             }
226              
227             sub correctInputLine {
228 598     598 0 940 my ($line, $this) = reverse(@_);
229            
230 598         629 my @elems;
231 598         618 my $tail = "";
232 598 50       1541 if ($line =~ /(\n+)$/) {
233 598         893 $tail = $1;
234             }
235 598         797 chomp $line;
236              
237 598         751 $line =~ s/
238 598         652 $line =~ s/>/SUP/go;
239 598         711 $line =~ s/\t:\t/\tCOLUMN\t/go;
240 598         704 $line =~ s/\t\t+/\t/go;
241 598 100       1424 if($line !~ /^[^\t]*\t[^\t]+\t[^\t]*$/o){
242             # warn "***********************************\n";
243             # my $line2 = $line;
244             # $line2 =~ s/\t/\\t/go;
245             # warn "Start correction of the line: " . $line2 . "\n";
246 4         10 @elems = split /\t/, $line;
247 4 50       13 if (scalar(@elems) > 3) {
248             # ambiguity in the pos tagging
249             # my @tmp = split /\s\|\|\s/, $elems[2];
250             # $elems[2] = shift @tmp;
251 0         0 $#elems = 2;
252             } else {
253 4 50 33     26 if ((defined $elems[0]) && (length($elems[0])>0)) {
254 0         0 $elems[2] = $elems[0];
255 0 0       0 if (!defined $elems[1]) {
256             # $elems[1] = 'SYM';
257 0         0 $elems[1] = $elems[0];
258             }
259             } else {
260 4         5 @elems =();
261             }
262            
263             }
264 4 50       9 if (scalar(@elems) == 3) {
265             # warn "Corrected line: " . join('\t', @elems). "\n";
266             # warn "***********************************\n";
267 0         0 return(join("\t", @elems) . $tail);
268             } else {
269             # warn "Removing line\n";
270             # warn "***********************************\n";
271 4         15 return("");
272             }
273             } else {
274 594         1857 return($line . $tail);
275             }
276            
277 0         0 return($line . $tail);
278             }
279              
280             sub recordWords
281             {
282 20     20 1 58 my ($this,$block,$sentence_boundary,$document_boundary,$num_line,$message_set,$display_language) = @_;
283 20         22 my $word;
284 20         197 my @words = split /\n/,$block;
285            
286 20         35 foreach $word (@words)
287             { # record each word of the sentence
288 612         722 $$num_line++;
289 612 50       1689 if ($word !~ /^\s*$/)
290             {
291 612         953 $this->addWordFromCorpus($word,$sentence_boundary,$document_boundary,$num_line,$message_set,$display_language);
292             }
293             }
294             }
295              
296             sub addWordFromCorpus
297             {
298 612     612 1 1043 my ($this,$form,$sentence_boundary,$document_boundary,$num_line,$message_set,$display_language) = @_;
299 612         624 my $word;
300 612         876 chomp $form;
301            
302 612 100       1694 if($form =~ /^[^\t]*\t[^\t]+\t[^\t]*$/o){
303 594         988 $word = Lingua::YaTeA::WordFromCorpus->new($form,$this->getLexicon,$this->getSentenceSet);
304             }
305             else{
306 18 100       62 if($form =~ /\<\/?FORBIDDEN/)
307             {
308 12         44 $word = Lingua::YaTeA::ForbiddenStructureMark->new($form);
309             }
310             else
311             {
312 6 50       22 if($form =~ /\<\/?FRONTIER/)
313             {
314 6         19 $word = Lingua::YaTeA::TestifiedTermMark->new($form);
315             }
316             else
317             {
318 0         0 warn $message_set->getMessage('INVALID_TOKEN')->getContent($display_language) . $$num_line . $message_set->getMessage('IN_FILE')->getContent($display_language) . $this->getPath . " ($form)";
319 0         0 die "\n";
320             }
321             }
322             }
323 612         749 push @{$this->{WORDS}}, $word;
  612         1052  
324 612         1116 $this->incrementCounters($word,$sentence_boundary,$document_boundary);
325 612         1170 return $word;
326             }
327              
328             sub incrementCounters
329             {
330 612     612 1 942 my ($this,$word,$sentence_boundary,$document_boundary) = @_;
331            
332 612 100 66     2683 if ((blessed($word)) && ($word->isa('Lingua::YaTeA::WordFromCorpus')))
333             {
334 594         739 $Lingua::YaTeA::WordFromCorpus::counter++;
335 594 100       979 if ($word->isSentenceBoundary($sentence_boundary))
336             {
337 18         24 $Lingua::YaTeA::Sentence::counter++;
338 18         21 $Lingua::YaTeA::Sentence::in_doc_counter++;
339 18         44 Lingua::YaTeA::Sentence::resetStartChar;
340 18         29 $this->getSentenceSet->addSentence($this->getDocumentSet);
341             }
342             else{
343 576 50       968 if ($word->isDocumentBoundary($document_boundary))
344             {
345 0         0 $this->getDocumentSet->addDocument($word);
346 0         0 Lingua::YaTeA::Sentence->resetStartChar;
347 0         0 $this->getSentenceSet->addSentence($this->getDocumentSet);
348 0         0 Lingua::YaTeA::Sentence->resetInDocCounter;
349 0         0 $word->updateSentence($this->getSentenceSet);
350 0         0 $word->updateStartChar;
351            
352 0         0 $Lingua::YaTeA::Sentence::counter++;
353 0         0 $Lingua::YaTeA::Sentence::in_doc_counter++;
354 0         0 $this->getSentenceSet->addSentence($this->getDocumentSet);
355            
356             }
357             else{
358 576         1080 Lingua::YaTeA::Sentence->updateStartChar($word);
359             }
360             }
361             }
362            
363             }
364              
365             sub print
366             {
367 0     0 1 0 my ($this,$sentence_boundary,$document_boundary) = @_;
368 0         0 my $word;
369 0         0 foreach $word (@{$this->{WORDS}} )
  0         0  
370             {
371 0 0 0     0 if ((blessed($word)) && ($word->isa("Lingua::YaTeA::WordFromCorpus")))
372             {
373 0 0       0 if ($word->isSentenceBoundary($sentence_boundary))
374             {
375 0         0 print $word->getLexItem->getIF . "\n";
376             }
377             else
378             {
379 0 0       0 if($word->isDocumentBoundary($document_boundary))
380             {
381 0         0 print "\n" . $word->getLexItem->getIF . "\n";
382             }
383             else
384             {
385 0         0 print $word->getLexItem->getIF . " ";
386             }
387             }
388             }
389             else{
390 0         0 print $word->getForm . "\n";
391             }
392             }
393             }
394              
395              
396             sub selectTestifiedTerms {
397 20     20 1 32 my ($this,$block_r,$testified_set,$match_type) = @_;
398 20         230 my @block_lines = split ("\n", $$block_r);
399 20         56 my %block_lexicon;
400             my $word;
401 20         0 my $testified;
402 20         0 my %block_testified_set;
403              
404 20 100 66     92 if((defined $testified_set) && ($testified_set->size > 0)) {
405 10         19 foreach $word (@block_lines) {
406 313 100       866 if ($word=~ /^([^\t]+)\t([^\t]+)\t([^\t]+)$/) {
407 297 50       416 if($match_type ne "strict") {
408 297         607 $block_lexicon{lc($1)}++; # record IF
409 297 50       413 if($match_type eq "loose") {
410 297         505 $block_lexicon{lc($3)}++; # record LF
411             }
412             }
413             else {
414 0         0 $block_lexicon{lc($1)."~".$2}++; # record IF + POS
415             }
416             }
417             }
418 10         11 foreach $testified (values %{$testified_set->getTestifiedTerms}) {
  10         23  
419 10 100       32 if($testified->isInLexicon(\%block_lexicon,$match_type) == 1) {
420 3         9 $block_testified_set{$testified->getID} = $testified;
421             }
422             }
423             }
424 20         112 return \%block_testified_set;
425             }
426              
427              
428              
429              
430             sub MarkTestifiedTerms
431             {
432 20     20 1 44 my ($this,$block_r,$testified_set,$match_type,$debug_fh) = @_;
433 20         31 my $testified;
434             my $reg_exp;
435 20         27 my $id = 0;
436             # print $debug_fh $$block_r . "\n";
437 20         44 my $selected_TTs_h = $this->selectTestifiedTerms($block_r,$testified_set,$match_type);
438              
439 20 50       44 if (defined $selected_TTs_h)
440             {
441 20         68 foreach $testified (values %$selected_TTs_h)
442             {
443             # print $debug_fh $testified->getIF . "\n";
444 3         10 $reg_exp = $testified->getRegExp;
445 3         382 $$block_r =~ s/($reg_exp)/$this->createAnnotation($1,\$id,$testified)/gei;
  3         12  
446 3         32 $$block_r =~ s/\n\n/\n/g;
447             }
448             }
449             }
450              
451             sub createAnnotation
452             {
453 3     3 1 10 my ($this,$match,$id_r,$testified) = @_;
454 3         5 my $type;
455            
456 3         11 my $annotation = "\n\\n" . $match . "\n<\/FRONTIER ID=" . $$id_r . " TT=" . $testified->getID ."\>\n";
457 3         7 $$id_r++;
458            
459 3         165 return $annotation;
460             }
461              
462              
463             sub MarkForbiddenStructures
464             {
465 20     20 1 30 my ($this,$block_r,$FS_set) = @_;
466 20         61 my $FS_any_a = $FS_set->getSubset("ANY");
467 20         25 my $FS;
468 20         30 my $ID = 0;
469 20         38 my $reg_exp;
470             my $action;
471 20         0 my $split_after;
472              
473 20         35 foreach $FS (@$FS_any_a)
474             {
475 860         1840 $action = $FS->getAction;
476 860         1408 $reg_exp = $FS->getRegExp;
477 860 100       1348 if ($action eq "delete"){
478 580         40782 $$block_r =~ s/($reg_exp)/\n\$1\<\/FORBIDDEN ID=$ID ACTION=$action\>\n/ig;
479             }
480             else{
481 280 50       442 if ($action eq "split"){
482 280         442 $split_after = $FS->getSplitAfter;
483 280         27986 $$block_r =~ s/($reg_exp)/\n\$1\<\/FORBIDDEN ID=$ID ACTION=$action SPLIT\_AFTER=$split_after\>\n/ig;
484             }
485             }
486 860         2357 $ID++;
487             }
488             }
489              
490             sub WrapBlock
491             {
492 20     20 1 33 my ($this,$block_r) = @_;
493 20         86 $$block_r =~ s/\r//g;
494 20         116 $$block_r =~ s/^/\n/;
495 20         124 $$block_r =~ s/$/\n/;
496             }
497              
498             sub UnwrapBlock
499             {
500 20     20 1 34 my ($this,$block_r) = @_;
501 20         134 $$block_r =~ s/^\n//;
502 20         141 $$block_r =~ s/\n$//;
503             }
504              
505              
506              
507              
508              
509             sub chunk
510             {
511 2     2 1 8 my ($this,$phrase_set,$sentence_boundary,$document_boundary,$chunking_data,$FS_set,$tag_set,$parsing_pattern_set,$testified_term_set,$option_set,$fh) = @_;
512 2         181 my $word;
513             my $i;
514 2         0 my @words;
515 2         0 my $action;
516 2         9 my $split_after = -1;
517 2         7 my $valid;
518             my $num_content_words;
519 2         0 my @clean_corpus;
520 2         0 my $term_frontiers_h;
521 2         10 my $compulsory = $option_set->getCompulsory;
522 2         7 my $max_length = $option_set->getMaxLength;
523              
524 2         43 print STDERR "MAX_LENGTH: " . $max_length . "\n";
525 2         12 for ($i = 0; $i <= $this->size; $i++){
526 614         897 $word = $this->getWord($i);
527 614 100 66     1545 if ((defined $fh) && (defined $word))
528             {
529 612         1139 $word->print($fh);
530             }
531             # if (defined $word) {
532             # print STDERR "> ($word)";
533             # $word->print(\*STDERR);
534             # }
535 614 100 100     1010 if(
536             ($i == $this->size) # last word of the corpus
537             ||
538             ($word->isChunkEnd(\$action,\$split_after,$sentence_boundary,$document_boundary,$chunking_data) == 1)
539             )
540             {
541 248         637 ($valid,$num_content_words,$term_frontiers_h) = $this->cleanChunk(\@words,$chunking_data,$FS_set,$option_set->getCompulsory,$tag_set,$fh);
542             # print STDERR "====$valid\n";
543             # foreach my $w (@words) {
544             # $w->print(\*STDERR);
545             # }
546             # print STDERR "====\n";
547            
548 248 100       490 if ($valid == 1)
549             {
550 122         239 $phrase_set->recordOccurrence(\@words,$num_content_words,$tag_set,$parsing_pattern_set,$option_set,$term_frontiers_h,$testified_term_set,$this->getLexicon,$this->getSentenceSet,$fh);
551 122         220 $Lingua::YaTeA::Corpus::tt_counter = 0;
552             }
553            
554 248         356 @words = ();
555            
556             }
557             else{
558 366         508 push @words, $word;
559             }
560              
561              
562             # warn "ref= " . ref($word) . "\n";
563 614 100 66     3002 if((defined $word) && ((blessed($word)) && ($word->isa('Lingua::YaTeA::WordFromCorpus'))))
      100        
564             {
565 594         1400 push @clean_corpus,$word;
566             }
567             }
568              
569 2         79 $this->{WORDS} = \@clean_corpus;
570              
571             }
572              
573              
574             sub cleanChunk
575             {
576 248     248 1 441 my ($this,$words_a,$chunking_data,$FS_set,$compulsory,$tag_set,$fh) = @_;
577 248         315 my $num_content_words;
578             my $term_frontiers_h;
579            
580 248 100       403 if ($this->pruneFromStart($words_a,$chunking_data,$FS_set,$fh) == 1)
581             {
582            
583 124 100       261 if($this->pruneFromEnd($words_a,$chunking_data,$FS_set,$fh) == 1)
584             {
585 122 50       223 if($this->checkCompulsory($words_a,$compulsory,$fh) == 1)
586             {
587 122         259 ($num_content_words,$term_frontiers_h) = $this->deleteAnnotationMarks($words_a,$tag_set,$fh);
588 122         323 return (1,$num_content_words,$term_frontiers_h);
589             }
590 0         0 return (0,0);
591             }
592 2         7 return (0,0); # no words left
593             }
594 124         243 return (0,0); # no words left
595             }
596              
597              
598             sub deleteAnnotationMarks
599             {
600 122     122 1 189 my ($class,$words_a,$tag_set,$fh) = @_;
601 122         142 my $word;
602             my @tmp;
603 122         145 my $content_words = 0;
604 122         125 my $index = 0;
605 122         141 my %term_frontiers;
606             my $frontier;
607              
608 122         163 foreach $word (@$words_a){
609 292 100 66     1010 if ((blessed($word)) && ($word->isa("Lingua::YaTeA::WordFromCorpus")))
610             {
611 286 100       499 if ($tag_set->existTag('CANDIDATES',$word->getPOS))
612             {
613 250         295 $content_words++;
614             }
615 286         447 push @tmp, $word;
616 286         411 $index++;
617             }
618             else
619             {
620 6 50 33     25 if ((blessed($word)) && ($word->isa("Lingua::YaTeA::TestifiedTermMark")))
621             {
622 6 100       13 if($word->isOpener)
623             {
624 3         10 $term_frontiers{$word->getID} = $word;
625 3         10 $word->{START} = $index; # should use setStart
626             }
627             else
628             {
629 3 50       6 if($word->isCloser)
630             {
631 3         8 $frontier = $term_frontiers{$word->getID};
632 3         7 $frontier->{END} = $index; # should use setEnd
633             }
634             }
635             }
636             }
637             }
638 122         215 @$words_a = @tmp;
639            
640 122         336 return ($content_words,\%term_frontiers);
641             }
642              
643              
644              
645              
646             sub pruneFromStart
647             {
648 248     248 1 355 my ($this,$words_a,$chunking_data,$FS_set,$fh) = @_;
649 248         269 my $i =0;
650 248         323 my $word;
651             my $potential_FS_a;
652 248         275 my $inside_testified = 0;
653 248         304 my %testified_frontiers;
654            
655              
656 248         431 while ($i < scalar @$words_a)
657             {
658 188         263 $word = $words_a->[$i];
659              
660 188 100 66     938 if ((blessed($word)) && ($word->isa('Lingua::YaTeA::TestifiedTermMark')))
661             {
662 2         7 return 1;
663             }
664             else
665             {
666 186 100 66     667 if ((blessed($word)) && ($word->isa('Lingua::YaTeA::WordFromCorpus')))
667             {
668            
669 182 100       334 if ($word->isCleaningFrontier($chunking_data))
670             {
671 122 100       307 if(
672             # ($inside_testified == 0)
673             # &&
674             # ($word->isa('Lingua::YaTeA::WordFromCorpus'))
675             # &&
676             ($potential_FS_a = $word->isStartTrigger($FS_set->getTriggerSet("START")))
677             )
678             {
679 25 50       75 if(!$this->expandStartTriggers($potential_FS_a,$words_a,$fh))
680             {
681 25         40 last;
682             }
683             }
684             else
685             {
686 97         141 last;
687             }
688             }
689            
690            
691             }
692 64         142 shift @$words_a; # delete element
693             }
694             }
695 246 100       518 if(scalar @$words_a > 0)
696             {
697 122         287 return 1;
698             }
699 124         263 return 0;
700             }
701              
702             sub pruneFromEnd
703             {
704 124     124 1 201 my ($this,$words_a,$chunking_data,$FS_set,$fh) = @_;
705 124         164 my $i = $#$words_a;
706 124         188 my $word;
707             my $potential_FS_a;
708 124         137 my $inside_testified = 0;
709 124         128 my %testified_frontiers;
710 124         143 my $deleted = 0;
711            
712 124         204 while ($i >= 0)
713             {
714 132         169 $word = $words_a->[$i];
715              
716 132 50 33     618 if ((blessed($word)) && ($word->isa('Lingua::YaTeA::TestifiedTermMark')))
717             {
718 0         0 return 1;
719             }
720             else
721             {
722 132 50 33     456 if ((blessed($word)) && ($word->isa('Lingua::YaTeA::WordFromCorpus')))
723             {
724 132 100       236 if ($word->isCleaningFrontier($chunking_data))
725            
726             {
727 126 100 33     755 if(
      33        
      66        
728             ($inside_testified == 0)
729             &&
730             ((blessed($word)) && ($word->isa('Lingua::YaTeA::WordFromCorpus')))
731             &&
732             ($potential_FS_a = $word->isEndTrigger($FS_set->getTriggerSet("END")))
733             )
734             {
735 4 50       15 if(!$this->expandEndTriggers($potential_FS_a,$words_a,$fh))
736             {
737 0         0 last;
738             }
739             else
740             {
741 4         6 $deleted = 1;
742 4 100       9 if(scalar @$words_a == 0)
743             {
744 2         8 return 0;
745             }
746             else
747             {
748 2         5 $i = $#$words_a;
749             }
750             }
751             }
752             else
753             {
754 122         170 last;
755             }
756             }
757             }
758 8 50 33     57 if ((blessed($word)) && ($word->isa('Lingua::YaTeA::ForbiddenStructureMark')))
759             {
760 0         0 my $del = pop @$words_a; # delete element
761 0         0 $i--;
762             }
763             else
764             {
765 8 100       26 if($deleted == 0)
766             {
767 6         16 my $del = pop @$words_a; # delete element
768 6         11 $i--;
769             }
770             }
771 8         17 $deleted = 0;
772            
773            
774             }
775             }
776 122 50       282 if(scalar @$words_a > 0)
777             {
778 122         261 return 1;
779             }
780 0         0 return 0;
781             }
782              
783              
784              
785              
786             sub checkCompulsory
787             {
788 122     122 1 189 my ($this,$words_a,$compulsory,$fh) = @_;
789 122         140 my $word;
790 122         169 foreach $word (@$words_a)
791             {
792 147 50 33     703 if (!((blessed($word)) && ($word->isa('Lingua::YaTeA::ForbiddenStructureMark'))))
793             {
794            
795 147 100 66     621 if (
      100        
796             ((blessed($word)) && ($word->isa('Lingua::YaTeA::TestifiedTermMark')))
797             ||
798             ($word->isCompulsory($compulsory))
799             )
800             {
801 122         269 return 1;
802             }
803             }
804             }
805 0         0 return 0;
806             }
807              
808              
809              
810             sub getWord
811             {
812 614     614 1 776 my ($this,$i) = @_;
813 614         856 return $this->{WORDS}->[$i];
814             }
815              
816             sub size
817             {
818 1230     1230 1 1546 my ($this) = @_;
819 1230         1299 return scalar @{$this->{WORDS}};
  1230         2827  
820             }
821              
822              
823             sub expandStartTriggers
824             {
825 25     25 1 47 my ($this,$potential_FS_a,$words_a,$fh) = @_;
826 25         87 my $FS;
827             my $i;
828 25         0 my $j;
829 25         0 my $to_find;
830 25         0 my $to_delete;
831              
832 25         40 foreach $FS (@$potential_FS_a)
833             {
834            
835 50 100       126 if($FS->getLength <= scalar @$words_a)
836             {
837 46         101 $to_delete = $FS->apply($words_a);
838 46 50       106 if(defined $to_delete)
839             {
840 0         0 last;
841             }
842            
843             }
844             }
845 25 50       48 if(defined $to_delete)
846             {
847 0         0 while($to_delete != 1)
848             {
849 0 0 0     0 if ((blessed($words_a->[0])) && ($words_a->[0]->isa('Lingua::YaTeA::TestifiedTermMark')))
850             {
851 0         0 return 1;
852             }
853             else
854             {
855 0         0 my $del = shift @$words_a;
856 0         0 $to_delete--;
857             }
858             }
859 0         0 return 1;
860             }
861 25         56 return 0;
862             }
863              
864              
865             sub expandEndTriggers
866             {
867 4     4 1 10 my ($this,$potential_FS_a,$words_a,$fh) = @_;
868 4         19 my $FS;
869             my $i;
870 4         0 my $j;
871 4         0 my $to_find;
872 4         0 my $to_delete;
873              
874 4         10 foreach $FS (@$potential_FS_a)
875             {
876            
877 4 50       12 if($FS->getLength <= scalar @$words_a)
878             {
879 4         30 $to_delete = $FS->apply($words_a);
880 4 50       10 if(defined $to_delete)
881             {
882 4         10 last;
883             }
884             }
885             }
886 4 50       8 if(defined $to_delete)
887             {
888 4         18 while($to_delete != 0)
889             {
890 4 50 33     41 if ((blessed($words_a->[$#$words_a])) && ($words_a->[$#$words_a]->isa('Lingua::YaTeA::TestifiedTermMark')))
891             {
892 0         0 return 1;
893             }
894             else
895             {
896 4         9 my $w = pop @$words_a;
897 4         11 $to_delete--;
898             }
899             }
900 4         12 return 1;
901             }
902 0         0 return 0;
903             }
904              
905             sub getSentenceSet
906             {
907 738     738 1 1161 my ($this) = @_;
908 738         1523 return $this->{SENTENCES};
909             }
910              
911             sub getDocumentSet
912             {
913 22     22 1 30 my ($this) = @_;
914 22         77 return $this->{DOCUMENTS};
915             }
916              
917             sub getFileHandle
918             {
919 3     3 1 5 my ($this) = @_;
920 3         14 my $path = $this->getPath;
921             # print STDERR "corpus :" . $path . "\n";
922 3         18 my $fh = FileHandle->new("<$path");
923             # binmode($fh, ":utf8");
924 3         190 return $fh;
925             }
926              
927             sub getPath
928             {
929 6     6 1 11 my ($this) = @_;
930 6         37 return $this->{PATH};
931             }
932              
933             sub getName
934             {
935 6     6 1 13 my ($this) = @_;
936 6         36 return $this->{NAME};
937             }
938              
939             sub getOutputFileSet
940             {
941 16     16 1 33 my ($this) = @_;
942 16         67 return $this->{OUTPUT};
943             }
944              
945             sub getLexicon
946             {
947 718     718 1 918 my ($this) = @_;
948 718         1365 return $this->{LEXICON};
949             }
950              
951             # the name of the file is what appears after the last "/" and before the last "." if any
952             sub setName
953             {
954 3     3 1 6 my ($this) = @_;
955            
956 3 50       10 if($this->getPath =~ /\/?([^\/]+)\.[^\.]+$/)
957             {
958 3         10 $this->{NAME} = $1;
959             }
960             else
961             {
962 0         0 $this->getPath =~ /\/?([^\/]+)$/;
963 0         0 $this->{NAME} = $1;
964             }
965             }
966              
967             sub setOutputFiles
968             {
969 3     3 1 9 my ($this,$option_set,$message_set) = @_;
970 3         17 my $sub_dir;
971             my $option;
972 3         0 my $file;
973 3         0 my @files;
974 3         0 my $file_info;
975 3         0 my $output_path;
976 3         4 my $no_output_defined = 1;
977 3         30 my %match_to_option= (
978             'xmlout'=>'xml:candidates.xml',
979             'TT-for-BioLG'=>'xml:TTforBioLG.xml',
980             'TC-for-BioLG'=>'xml:TCforBioLG.xml',
981             'termList'=>'raw:termList.txt',
982             'termAndHeadList'=>'raw:termAndHeadList.txt',
983             'printChunking'=>'html:candidatesAndUnparsedInCorpus.html',
984             'debug'=>'raw:debug,unparsable,unparsed',
985             'TTG-style-term-candidates' => 'raw:termCandidates.ttg',
986             'XML-corpus-for-BioLG' => 'xml:corpusForBioLG.xml',
987             'bootstrap' => 'raw:parsedTerms.txt',
988             'XML-corpus-raw' => 'xml:corpusRaw.xml',
989             );
990            
991 3         21 $output_path = $option_set->getOutputPath ."/". $this->getName . "/" . $option_set->getSuffix;
992              
993 3 100       85 if(-d $output_path)
994             {
995 1         6 print STDERR $message_set->getMessage('OVER_WRITE_REP')->getContent($option_set->getDisplayLanguage) . $output_path . "/\n";
996 1         2078 rmtree $output_path;
997             }
998             # else
999             # {
1000 3         644 mkpath $output_path;
1001 3         22 print STDERR $message_set->getMessage('CREATE_REP')->getContent($option_set->getDisplayLanguage) . $output_path . "/\n";
1002             # }
1003 3         20 $this->{OUTPUT} = Lingua::YaTeA::FileSet->new($this->getName);
1004            
1005 3         19 while (($option,$file_info) = each (%match_to_option))
1006             {
1007 33 100       76 if($option_set->optionExists($option))
1008             {
1009 24         52 $this->setFilesForOption($file_info,$output_path);
1010 24         72 $no_output_defined = 0;
1011             }
1012             }
1013 3 50       17 if($no_output_defined == 1)
1014             {
1015 0         0 $this->setFilesForOption($match_to_option{'xmlout'},$output_path);
1016             }
1017 3         16 $option_set->addOption('default_output',$no_output_defined);
1018             }
1019              
1020             sub setFilesForOption
1021             {
1022 24     24 1 33 my ($this,$file_info,$sub_dir) = @_;
1023 24         45 my @files;
1024             my $file;
1025 24         0 my $sub_sub_dir;
1026 24         72 $file_info =~ /^([^:]+):(.+)$/;
1027 24         64 @files = split (/,/,$2);
1028 24         52 $sub_sub_dir = $sub_dir . "/" . $1;
1029 24 100       314 if(! -d $sub_sub_dir)
1030             {
1031 9         264 mkdir $sub_sub_dir;
1032             }
1033 24         66 foreach $file (@files)
1034             {
1035 30         99 $this->{OUTPUT}->addFile($sub_sub_dir,$file);
1036             }
1037             }
1038              
1039             sub printCorpusForLGPwithTCs
1040             {
1041 0     0 1 0 my ($this,$term_candidates_h,$output_file,$sentence_boundary,$document_boundary,$lgp_mapping_file,$chained_links,$tag_set) = @_;
1042            
1043 0         0 my ($occurrences_h,$mapping_to_TCs_h) = $this->orderOccurrencesForXML($term_candidates_h);
1044 0         0 my $LGPmapping_h = $this->loadLGPmappingFile($lgp_mapping_file->getPath);
1045 0         0 $this->printXMLcorpus($occurrences_h,$output_file->getPath,$sentence_boundary,$document_boundary,$mapping_to_TCs_h,$LGPmapping_h,$chained_links,$tag_set);
1046             }
1047              
1048              
1049             sub printCorpusForLGPwithTTs
1050             {
1051 0     0 1 0 my ($this,$testified_terms_h,$output_file,$sentence_boundary,$document_boundary,$lgp_mapping_file,$parsing_direction,$chained_links,$tag_set) = @_;
1052              
1053 0         0 my ($occurrences_h,$mapping_to_TTs_h) = $this->orderOccurrencesForXML($testified_terms_h);
1054 0         0 $this->getBestOccurrences($occurrences_h,$parsing_direction);
1055 0         0 my $LGPmapping_h = $this->loadLGPmappingFile($lgp_mapping_file->getPath);
1056 0         0 $this->printXMLcorpus($occurrences_h,$output_file->getPath,$sentence_boundary,$document_boundary,$mapping_to_TTs_h,$LGPmapping_h,$chained_links,$tag_set);
1057             }
1058              
1059              
1060             sub getBestOccurrences
1061             {
1062 0     0 1 0 my ($this,$occurrences_h,$parsing_direction) = @_;
1063 0         0 my $doc;
1064             my $sentence;
1065 0         0 my @occurrences;
1066 0         0 my $occurrence;
1067 0         0 my $occurrence_set;
1068 0         0 my $same_start;
1069 0         0 foreach $doc (values %$occurrences_h)
1070             {
1071 0         0 foreach $sentence (values %$doc)
1072             {
1073 0         0 @occurrences = ();
1074 0         0 foreach $same_start (values %$sentence)
1075             {
1076 0         0 foreach $occurrence (@$same_start){
1077 0         0 push @occurrences, $occurrence;
1078             }
1079            
1080             }
1081 0         0 foreach $occurrence (@occurrences)
1082             {
1083 0 0       0 if($occurrence->isNotBest(\@occurrences,$parsing_direction))
1084             {
1085 0         0 $this->removeOccurrence($occurrences_h,$occurrence->getDocument->getID,$occurrence->getSentence->getID,$occurrence->getStartChar,$occurrence->getID);
1086            
1087             }
1088             }
1089            
1090             }
1091             }
1092            
1093             }
1094              
1095              
1096             sub removeOccurrence
1097             {
1098 0     0 1 0 my ($this,$occurrences_h,$doc,$sentence,$start_char,$occ_id) = @_;
1099 0         0 my @tmp;
1100             my $occurrence;
1101 0         0 my $occurrences_set = $occurrences_h->{$doc}{$sentence}{$start_char};
1102 0 0       0 if(scalar @$occurrences_set == 1)
1103             {
1104 0         0 delete $occurrences_h->{$doc}{$sentence}{$start_char};
1105             }
1106             else
1107             {
1108 0         0 foreach $occurrence (@$occurrences_set)
1109             {
1110 0 0       0 if($occurrence->getID != $occ_id)
1111             {
1112 0         0 push @tmp, $occurrence;
1113             }
1114             }
1115 0         0 @{$occurrences_h->{$doc}{$sentence}{$start_char}} = @tmp;
  0         0  
1116             }
1117             }
1118              
1119             sub printCorpusForBioLG{
1120 0     0 0 0 my ($this,$output_file,$sentence_boundary,$document_boundary,$chained_links) = @_;
1121            
1122 0         0 my %occurrences;
1123             my %BioLGmapping;
1124 0         0 my %mapping_to_TTs;
1125            
1126 0         0 $this->printXMLcorpus(\%occurrences,$output_file->getPath,$sentence_boundary,$document_boundary,\%mapping_to_TTs,\%BioLGmapping,$chained_links);
1127             }
1128              
1129              
1130              
1131             sub printXMLcorpus
1132             {
1133 0     0 1 0 my ($this,$occurrences_h,$output_file_path,$sentence_boundary,$document_boundary,$mapping_to_TCs_h,$LGPmapping_h,$chained_links,$tag_set) = @_;
1134 0         0 my $word;
1135             my $sentence;
1136 0         0 my $sentence_id;
1137 0         0 my $document_id;
1138 0         0 my $occurrence;
1139 0         0 my $tc;
1140 0         0 my $head_word;
1141 0         0 my $head_index;
1142 0         0 my $local_occurrences_a;
1143 0         0 my $links_a;
1144 0         0 my $counter = 0;
1145 0         0 my $pos;
1146             my $if;
1147 0         0 my $i;
1148 0         0 my $tc_length;
1149 0         0 my $occurrence_set;
1150            
1151 0         0 my $fh = FileHandle->new(">" . $output_file_path);
1152 0         0 binmode($fh, ":utf8");
1153 0         0 $this->printXMLheader($fh);
1154            
1155 0         0 for ($i=0; $i < scalar @{$this->getWords}; $i++)
  0         0  
1156             {
1157 0         0 $word = $this->getWords->[$i];
1158 0 0       0 if(! $word->isDocumentBoundary($document_boundary))
1159             {
1160              
1161 0 0       0 if(exists $occurrences_h->{$word->getDocumentID}{$word->getSentenceID}{$word->getStartChar})
1162             {
1163 0         0 $occurrence_set = $occurrences_h->{$word->getDocumentID}{$word->getSentenceID}{$word->getStartChar};
1164 0         0 $occurrence = $occurrence_set->[0];
1165              
1166 0         0 $tc = $mapping_to_TCs_h->{$occurrence->getID};
1167 0         0 $tc_length = $tc->getLength;
1168            
1169             # previous and next words are not coordinations: to be removed when coordination will be handled ?
1170 0 0 0     0 if(
      0        
      0        
1171             (
1172             ($i == 0)
1173             ||
1174             (!($tag_set->existTag('COORDINATIONS',$this->getWords->[$i-1]->getPOS)))
1175             )
1176             &&
1177             (
1178             ($i == (scalar @{$this->getWords} -1))
1179             ||
1180             (!($tag_set->existTag('COORDINATIONS',$this->getWords->[$i + $tc_length]->getPOS)))
1181             )
1182             )
1183             {
1184            
1185 0         0 ($head_word,$head_index,$links_a) = $tc->getHeadAndLinks($LGPmapping_h,$chained_links);
1186 0         0 $counter++;
1187 0         0 $pos = $head_word->getPOS;
1188 0         0 $if = $head_word->getIF;
1189 0         0 Lingua::YaTeA::XMLEntities::encode($pos);
1190 0         0 Lingua::YaTeA::XMLEntities::encode($if);
1191 0         0 $sentence .= "
1192 0 0       0 if(scalar $links_a > 0)
1193             {
1194 0         0 $sentence .= " internal=\"" . join ("",@$links_a) . "\"";
1195             }
1196 0         0 $sentence .= " head=\"" . $head_index . "\">";
1197            
1198             }
1199             else
1200             {
1201 0         0 undef $occurrence;
1202             }
1203             }
1204 0         0 $pos = $word->getPOS;
1205 0         0 $if = $word->getIF;
1206 0         0 Lingua::YaTeA::XMLEntities::encode($pos);
1207 0         0 Lingua::YaTeA::XMLEntities::encode($if);
1208 0         0 $sentence .= "" . $if . " ";
1209            
1210 0 0 0     0 if (
1211             (defined $occurrence)
1212             &&
1213             ($occurrence->getEndChar == $word->getStartChar + $word->getLexItem->getLength)
1214             )
1215             {
1216 0         0 undef $occurrence;
1217 0         0 $sentence .= "";
1218             }
1219 0 0       0 if($word->isSentenceBoundary($sentence_boundary))
1220             {
1221 0         0 $sentence =~ s/\s*$//;
1222 0         0 $sentence .= "";
1223 0         0 $sentence_id = $word->getSentence->getID;
1224 0         0 $document_id = $word->getDocument->getID;
1225 0         0 $local_occurrences_a = $occurrences_h->{$document_id}{$sentence_id};
1226            
1227 0         0 print $fh $sentence . "\n";
1228 0         0 $sentence = "";
1229             }
1230             }
1231            
1232             }
1233             # corpus ended without a final dot
1234 0 0       0 if($sentence ne "")
1235             {
1236 0         0 $sentence .= "";
1237 0         0 print $fh $sentence;
1238             }
1239 0         0 print STDERR $counter . " terms marked\n";
1240 0         0 $this->printXMLtrailer($fh);
1241             }
1242              
1243             sub printXMLheader
1244             {
1245 0     0 1 0 my ($this,$fh) = @_;
1246 0         0 print $fh "\n";
1247             }
1248              
1249             sub printXMLtrailer
1250             {
1251 0     0 1 0 my ($this,$fh) = @_;
1252 0         0 print $fh "\n\n";
1253             }
1254              
1255             sub loadLGPmappingFile
1256             {
1257 0     0 1 0 my ($this,$file_path) = @_;
1258            
1259 0         0 my $fh = FileHandle->new("<$file_path");
1260 0         0 my %mapping;
1261             my $line;
1262 0         0 while ($line= $fh->getline)
1263             {
1264 0 0 0     0 if(($line !~ /^\s*$/)&&($line !~ /^\s*#/)) # line is not empty nor commented
1265             {
1266 0         0 $line =~ /^([^\t]+)\t([^\t]+)\s*\n$/;
1267 0         0 $mapping{$1} = $2;
1268             }
1269             }
1270 0         0 return \%mapping;
1271             }
1272              
1273              
1274             sub printCandidatesAndUnparsedInCorpus
1275             {
1276 0     0 1 0 my ($this,$term_candidates_h,$unparsable_a,$file,$sentence_boundary,$document_boundary,$color_blind_option, $parsed_color, $unparsed_color) = @_;
1277 0         0 my %ids_for_parsed;
1278            
1279             # my $fh = FileHandle->new(">".$file->getPath);
1280              
1281             my $fh;
1282 0 0       0 if ($file eq "stdout") {
1283 0         0 $fh = \*STDOUT;
1284             } else {
1285 0 0       0 if ($file eq "stderr") {
1286 0         0 $fh = \*STDERR;
1287             } else {
1288 0         0 $fh = FileHandle->new(">".$file->getPath);
1289             }
1290             }
1291 0         0 binmode($fh, ":utf8");
1292              
1293              
1294 0         0 $this->printHTMLheader($fh);
1295 0         0 my $occurrences_h = $this->orderOccurrences($term_candidates_h,$unparsable_a,\%ids_for_parsed);
1296            
1297 0         0 $this->printHTMLCorpus($occurrences_h,\%ids_for_parsed,$fh,$sentence_boundary,$document_boundary,$color_blind_option, $parsed_color, $unparsed_color);
1298 0         0 $this->printHTMLtrailer($fh);
1299             }
1300              
1301              
1302             sub printHTMLheader
1303             {
1304 0     0 1 0 my ($this,$fh) = @_;
1305 0         0 print $fh
1306             "\n\nTerm Candidates and unparsed phrases in Corpus\n";
1307             }
1308              
1309             sub printHTMLtrailer
1310             {
1311 0     0 1 0 my ($this,$fh) = @_;
1312 0         0 print $fh
1313             "";
1314             }
1315              
1316             sub printXMLRawCorpus
1317             {
1318 0     0 0 0 my ($this,$file,$sentence_boundary,$document_boundary) = @_;
1319 0         0 my $sentence_id;
1320             my $document_id;
1321 0         0 my $document_name;
1322 0         0 my $word;
1323 0         0 my $first_sentence = 1;
1324 0         0 my $in_doc = 0;
1325 0         0 my $string;
1326             my $last_word;
1327 0         0 my $fh = FileHandle->new(">".$file->getPath);
1328 0         0 binmode($fh,":utf8");
1329 0         0 $this->printXMLheader($fh);
1330 0         0 print $fh " \n";
1331 0         0 foreach $word (@{$this->getWords})
  0         0  
1332             {
1333 0 0       0 if($word->isDocumentBoundary($document_boundary)) # new document is started
1334             {
1335 0 0       0 if($in_doc == 1)
1336             {
1337 0 0       0 if(!$last_word->isSentenceBoundary($sentence_boundary)) # last word of document is not a sentence boundary
1338             {
1339 0         0 $string =~ s/ $//;
1340 0         0 Lingua::YaTeA::XMLEntities::encode($string);
1341 0         0 print $fh " getSentence->getID . "\" inDocID=\"" . $word->getSentence->getInDocID . "\">" . $string . "\n";
1342 0         0 $string = "";
1343             }
1344 0         0 print $fh " \n";
1345             }
1346 0         0 print $fh " getDocument->getID . "\"";
1347 0 0       0 if($word->getDocument->getName ne 'no_name')
1348             {
1349 0         0 print $fh " name=\"". $word->getDocument->getName . "\"";
1350             }
1351 0         0 print $fh ">\n";
1352 0         0 $in_doc = 1 ;
1353             }
1354             else
1355             {
1356             # rebuild the sentence from occurrences of words from the corpus
1357 0         0 $string .= $word->getIF . " ";
1358 0         0 $last_word = $word;
1359 0 0       0 if($in_doc == 0) # if no explicit marker of document boundary in the input document
1360             {
1361 0         0 print $fh " getDocument->getID . "\"";
1362 0 0       0 if($word->getDocument->getName ne 'no_name')
1363             {
1364 0         0 print $fh " name=\"". $word->getDocument->getName . "\"";
1365             }
1366 0         0 print $fh ">\n";
1367 0         0 $in_doc = 1;
1368             }
1369 0 0 0     0 if (
1370             ($word->isSentenceBoundary($sentence_boundary)) # new sentence is started
1371             ||
1372 0         0 ($word == $this->getWords->[$#{$this->getWords}]) # last word of the corpus (no final dot)
1373             )
1374             {
1375 0         0 $string =~ s/ $//;
1376 0         0 Lingua::YaTeA::XMLEntities::encode($string);
1377 0         0 print $fh " getSentence->getID . "\" inDocID=\"" . $word->getSentence->getInDocID . "\">" . $string . "\n";
1378 0         0 $string = "";
1379 0 0       0 if($word == $this->getWords->[$#{$this->getWords}])
  0         0  
1380             {
1381 0         0 print $fh " \n";
1382             }
1383             }
1384             }
1385              
1386             }
1387 0         0 print $fh " \n";
1388             }
1389              
1390              
1391             sub printHTMLCorpus
1392             {
1393 0     0 1 0 my ($this,$parsed_occurrences_h,$ids_for_parsed_h,$fh,$sentence_boundary,$document_boundary,$color_blind_option, $parsed_color, $unparsed_color) = @_;
1394 0         0 my $sentence_id;
1395             my $document_id;
1396 0         0 my $document_name;
1397 0         0 my $word;
1398 0         0 my $occurrence;
1399 0         0 my $local_occurrences_a;
1400 0         0 my $string;
1401 0         0 my $offset = 0;
1402 0         0 my $string_copy;
1403             my $color;
1404            
1405            
1406 0         0 foreach $word (@{$this->getWords})
  0         0  
1407             {
1408 0 0       0 if($word->isDocumentBoundary($document_boundary)) # new sentence is started
1409             {
1410 0         0 print $fh "
Document " . $word->getDocument->getID;
1411 0 0       0 if($word->getDocument->getName ne 'no_name')
1412             {
1413 0         0 print $fh " - ". $word->getDocument->getName;
1414             }
1415 0         0 print $fh "
";
1416             }
1417             else
1418             {
1419             # rebuild the sentence from occurrences of words from the corpus
1420 0         0 $string .= $word->getIF . " ";
1421 0 0 0     0 if (
1422             ($word->isSentenceBoundary($sentence_boundary)) # new sentence is started
1423             ||
1424 0         0 ($word == $this->getWords->[$#{$this->getWords}]) # last word of the corpus (no final dot)
1425             )
1426             {
1427 0         0 $string =~ s/ $//;
1428             # get the term candidates occurrences for the next sentence
1429 0         0 $sentence_id = $word->getSentence->getID;
1430 0         0 $document_id = $word->getDocument->getID;
1431 0         0 $document_name = $word->getDocument->getName;
1432            
1433 0         0 $local_occurrences_a = $parsed_occurrences_h->{$document_id}{$sentence_id};
1434             # mark term candidates on the rebuilt sentence
1435 0         0 foreach $occurrence (@$local_occurrences_a)
1436             {
1437 0         0 $color = $this->setColor($occurrence->getID,$ids_for_parsed_h,$color_blind_option, $parsed_color, $unparsed_color);
1438 0 0       0 if(!defined $offset)
1439             {
1440 0         0 die;
1441             }
1442 0         0 $string_copy .= substr($string,$offset,$occurrence->getStartChar - $offset). "";
1443 0         0 $string_copy .= substr($string,$occurrence->getStartChar,$occurrence->getEndChar - $occurrence->getStartChar) . "";
1444 0         0 $offset = $occurrence->getEndChar;
1445            
1446 0 0       0 if(! substr($string,$offset-1))
1447             {
1448 0         0 print STDERR "problem d'offset pour la phrase DOC:" . $document_id . " - SENT: " . $sentence_id . "\n";
1449 0         0 print STDERR $string . "\n";
1450             }
1451             }
1452              
1453 0         0 $string_copy .= substr($string,$offset);
1454 0         0 print $fh $word->getSentence->getInDocID . ":" . $string_copy . "
\n";
1455 0         0 $string = "";
1456 0         0 $string_copy = "";
1457 0         0 $offset = 0;
1458             }
1459             }
1460             }
1461             }
1462              
1463              
1464             sub setColor
1465             {
1466 0     0 1 0 my ($this,$occurrence_id,$ids_for_parsed_h,$color_blind_option, $parsed_color, $unparsed_color) = @_;
1467 0         0 my $color;
1468            
1469 0 0       0 if(exists $ids_for_parsed_h->{$occurrence_id})
1470             {
1471 0 0       0 if($color_blind_option->getValue eq 'yes')
1472             {
1473 0 0       0 if (defined $parsed_color) {
1474 0         0 $color = $parsed_color->getValue;
1475             } else {
1476 0         0 $color = "FF0099";
1477             }
1478             }
1479             else
1480             {
1481 0 0       0 if (defined $parsed_color) {
1482 0         0 $color = $parsed_color->getValue;
1483             } else {
1484 0         0 $color = "CC0066";
1485             }
1486             }
1487             }
1488             else
1489             {
1490 0 0       0 if($color_blind_option->getValue eq 'yes')
1491             {
1492 0 0       0 if (defined $unparsed_color) {
1493 0         0 $color = $unparsed_color->getValue;
1494             } else {
1495 0         0 $color = "0000CC";
1496             }
1497             }
1498             else
1499             {
1500 0 0       0 if (defined $unparsed_color) {
1501 0         0 $color = $unparsed_color->getValue;
1502             } else {
1503 0         0 $color = "3366CC";
1504             }
1505             }
1506             }
1507 0         0 return $color;
1508             }
1509              
1510             sub orderOccurrencesForXML
1511             {
1512 0     0 1 0 my ($this,$term_h) = @_;
1513 0         0 my %occurrences;
1514             my %mapping_to_TCs;
1515 0         0 my $document;
1516 0         0 my $sentence;
1517 0         0 my $occurrence;
1518 0         0 my $term;
1519 0         0 my $unparsable;
1520 0         0 my $sent_hash;
1521 0         0 my $occurrences_a;
1522              
1523 0         0 foreach $term (values (%$term_h))
1524             {
1525              
1526 0         0 foreach $occurrence (@{$term->getOccurrences})
  0         0  
1527             {
1528             # only the occurrences covering an entire phrase are selected
1529 0 0 0     0 if(
      0        
1530             ((blessed($term)) && ($term->isa('Lingua::YaTeA::TestifiedTerm')))
1531             ||
1532             ($occurrence->isMaximal)
1533             )
1534             {
1535 0         0 push @{$occurrences{$occurrence->getDocument->getID}{$occurrence->getSentence->getID}{$occurrence->getStartChar}}, $occurrence;
  0         0  
1536 0         0 $mapping_to_TCs{$occurrence->getID} = $term;
1537             }
1538            
1539             }
1540             }
1541 0         0 return (\%occurrences,\%mapping_to_TCs);
1542             }
1543              
1544              
1545              
1546             sub orderOccurrences
1547             {
1548 0     0 1 0 my ($this,$term_candidates_h,$unparsable_a,$ids_for_parsed_h) = @_;
1549 0         0 my %occurrences;
1550             my $document;
1551 0         0 my $sentence;
1552 0         0 my $occurrence;
1553 0         0 my $term_candidate;
1554 0         0 my $unparsable;
1555 0         0 my $sent_hash;
1556 0         0 my $occurrences_a;
1557              
1558              
1559 0         0 foreach $term_candidate (values (%$term_candidates_h))
1560             {
1561 0         0 foreach $occurrence (@{$term_candidate->getOccurrences})
  0         0  
1562             {
1563 0 0       0 if($occurrence->isMaximal)
1564             {
1565 0         0 push @{$occurrences{$occurrence->getDocument->getID}{$occurrence->getSentence->getID}}, $occurrence;
  0         0  
1566 0         0 $ids_for_parsed_h->{$occurrence->getID}++;
1567             }
1568             }
1569             }
1570 0         0 foreach $unparsable (@$unparsable_a)
1571             {
1572 0         0 foreach $occurrence (@{$unparsable->getOccurrences})
  0         0  
1573             {
1574 0 0       0 if($occurrence->isMaximal)
1575             {
1576 0         0 push @{$occurrences{$occurrence->getDocument->getID}{$occurrence->getSentence->getID}}, $occurrence;
  0         0  
1577             }
1578             }
1579             }
1580 0         0 while (($document,$sent_hash) = each (%occurrences))
1581             {
1582 0         0 while (($sentence,$occurrences_a) = each (%$sent_hash))
1583             {
1584 0         0 @$occurrences_a = sort ({$a->getStartChar <=> $b->getStartChar} @$occurrences_a);
  0         0  
1585             }
1586            
1587             }
1588 0         0 return \%occurrences;
1589             }
1590              
1591             sub getWords
1592             {
1593 0     0 1 0 my ($this) = @_;
1594 0         0 return $this->{WORDS};
1595             }
1596              
1597             sub selectOnTermListStyle {
1598 0     0 0 0 my ($this, $term_candidates_h,$term_list_style,$debug_fh) = @_;
1599              
1600 0         0 my $tc;
1601             # warn "selectOnTermListStyle ($term_list_style)\n";
1602 0         0 foreach $tc (values (%$term_candidates_h))
1603             {
1604             # warn $tc->getIF . "\n";
1605             # warn ($tc->isa('Lingua::YaTeA::MultiWordTermCandidate') * 1) . "\n";
1606 0 0 0     0 if (($term_list_style ne "") && ($term_list_style ne "all") &&
      0        
      0        
1607             (($term_list_style ne "multi") || ((blessed($tc)) && ($tc->isa('Lingua::YaTeA::MultiWordTermCandidate') != 1)))) {
1608 0         0 $tc->setTermStatus(0);
1609             }
1610             # warn "" . (1 * $tc->getTermStatus) . "\n";
1611             # warn " " . ($tc->isTerm * 1) . "\n";
1612             }
1613             }
1614              
1615             sub makeDDW
1616             {
1617 2     2 0 5 my ($this,$term_candidates_h,$fh) = @_;
1618 2         5 my $tc_weight;
1619             my $mean_occ;
1620 2         3 my $total_occ = 0;
1621 2         8 my $total_doc = $this->getDocumentSet->getDocumentNumber;
1622 2         9 my %doc_by_tc;
1623             my %docs_for_this_tc;
1624 2         0 my $tc;
1625 2         0 my $occ;
1626              
1627              
1628 2         13 foreach $tc (values (%$term_candidates_h))
1629             {
1630 240         352 %docs_for_this_tc = ();
1631 240         247 foreach $occ (@{$tc->getOccurrences})
  240         370  
1632             {
1633 330         700 $docs_for_this_tc{$occ->getDocument->getID}++;
1634 330         455 $total_occ++;
1635             }
1636 240         397 $doc_by_tc{$tc->getKey} = scalar keys(%docs_for_this_tc);
1637             }
1638 2 50       9 if (scalar(keys(%$term_candidates_h)) > 0) {
1639 2         8 $mean_occ = $total_occ / scalar keys %$term_candidates_h;
1640             } else {
1641 0         0 $mean_occ = 0;
1642             }
1643 2         21 foreach $tc (values (%$term_candidates_h))
1644             {
1645             ##### measure 'descriptor discriminating weight' described in 'Building back-of-the-book indexes', Nazarenko, Ait El Mekki (2005)
1646             ##### PROBLEM: each time there is only one document in the corpus, the value is 0 (log10(1/1) = 0)
1647 240         388 $tc_weight = ($tc->getFrequency/$mean_occ) * log10 ($total_doc/$doc_by_tc{$tc->getKey});
1648 240         808 $tc->setWeight($tc_weight);
1649             }
1650             }
1651              
1652             sub processTotalDocOccurrences
1653             {
1654 0     0 0   my ($this,$occurrences_h) = @_;
1655 0           my $total;
1656             my $occ;
1657             # print STDERR $occurrences_h. "\n";
1658 0           foreach $occ (values (%$occurrences_h))
1659             {
1660 0           $total += $occ;
1661             }
1662 0           return $total;
1663             }
1664              
1665              
1666             1;
1667              
1668             __END__