#!/usr/bin/perl
#  PhraseLM10AutourPivot2CooccurrencesGraphML.pl

<<DOC; 
B. Habert
mar mar  7 15:05:07 CET 2006

               PhraseLM10AutourPivot2CooccurrencesGraphML.pl :


Format d'entrée : 

Fichier tabulé de la forme :

<doc>  <par.>   <phrase><lemme> <forme> <cat>   <POS>
683121  2       4       le      L'      DetMS   D
683121  2       4       accalmie        accalmie        NomFS   N
683121  2       4       permettre       devrait permettre       VCONJS  V
683121  2       4       de      de      Prep    O
683121  2       4       récupérer       récupérer       VINF    V
683121  2       4       de      d'      Prep    O
683121  2       4       autre   autres  AdjFP   A
683121  2       4       trace   traces  NomFP   N
683121  2       4       de      de      Prep    O
683121  2       4       fioul   fioul   NomMS   N

Etiquetage par le TreeTagger des phrases contenant un pivot donné.

Les POS (Part Of Speech) sont les suivantes :

A   Adjectif
Cc  Conjonction de coordination
Cs  Conjonction de subordination
D   Déterminant
E   Erreur 
N   Nom commun
NP  Nom propre
O   PrépOsition
P   Pronom
R   AdveRbe
T   PoncTuation
V   Verbe

Exemple d'appel : 
     PhraseLM10AutourPivot2CooccurrencesGraphML.pl fragment essaiB.xml barrage A 2

Format de sortie :
  Un fichier GraphML du graphe correspondant.

A faire :

Bugs et problèmes :

DOC



$ChaineUsage = "Usage : PhraseLM10AutourPivot2CooccurrencesGraphML.pl <fichier d'entrée><fichier de sortie><pivot><POS gardées><cooccurrence plancher>\n" ; 
if (@ARGV != 5) {die $ChaineUsage ; }  
$FichierEntree = $ARGV[0] ;  
$FichierSortie = $ARGV[1] ;  
$Pivot         = $ARGV[2] ;  
$POSGardees    = $ARGV[3] ; 
$Plancher      = $ARGV[4] ; 
$NumeroPhrase  = 1 ;
%Cooccurrence2Frequence = () ;
%Lemme2Frequence        = () ;
%Lemme2NumeroLemme      = () ;

open(ENTREE, $FichierEntree) ;  

$DocumentPrecedent   = 0 ;
$ParagraphePrecedent = 0 ;
$PhrasePrecedente    = 0 ;

@LemmesGardes = () ;
$EntreesWindows = 1 ;
$SortiesWindows = 1 ;
if ($SortiesWindows == 0) {
  $FinLigne     = "\n" ; 
}
else {
  $FinLigne     = "\r\n" ; 
}

$Trace = 0 ; 

while ($Ligne = <ENTREE>){
  if ($Trace == 1) {print $Ligne ; }
  # On enlève le \n
  chomp($Ligne) ; 
  # On enlève si nécessaire le \r
  if ($EntreesWindows == 1) {
    chomp($Ligne) ; 
  }
  @ListeChamps = split(/\t/, $Ligne) ;

  $DocumentCourant     = $ListeChamps[0] ; 
  $ParagrapheCourant   = $ListeChamps[1] ; 
  $PhraseCourante      = $ListeChamps[2] ; 
  $Lemme               = $ListeChamps[3] ; 
  $Forme               = $ListeChamps[4] ; 
  $Categorie           = $ListeChamps[5] ; 
  $POS                 = $ListeChamps[6] ;  
  
  if ($DocumentCourant  == $DocumentPrecedent
      && $ParagrapheCourant   == $ParagraphePrecedent
      && $PhraseCourante      == $PhrasePrecedente) {


      $InitialePOS = substr($POS, 0, 1) ; 

      if ($Trace == 1) {print "$POS\t$InitialePOS\t$Ligne$FinLigne" ;  }

      if ($InitialePOS =~ /[$POSGardees]/ && $Lemme ne $Pivot) {
        if ($Trace == 1) {print "\t===== $Ligne$FinLigne" ; }
        push(@LemmesGardes, $Lemme) ;
      }

  }
  else {
     if ($NumeroPhrase > 1) {
        if ($Trace == 1) {
           print "\tLemmes gardés : " ;
           for ($l = 0 ; $l <= $#LemmesGardes ; $l++) {
             print "\t$LemmesGardes[$l]" ; 
           }
           print "$FinLigne" ; 
         }
         if ($#LemmesGardes > 0) {
           for ($l1 = 0 ; $l1 <= $#LemmesGardes ; $l1++) {
             $Lemme2Frequence{$LemmesGardes[$l1]}++ ;
           }
           for ($l1 = 0 ; $l1 < $#LemmesGardes ; $l1++) {
              for ($l2 = $l1 + 1 ; $l2 <= $#LemmesGardes ; $l2++) {
                 $Cooccurrence = "$LemmesGardes[$l1]\t$LemmesGardes[$l2]" ;
                 if ($Trace == 1) {print "\t$Cooccurrence\n" ;  }
                 $Cooccurrence2Frequence{$Cooccurrence}++ ;
              }
           }
         }

     }

     @LemmesGardes = () ;
     $NumeroPhrase++ ;
     if ($InitialePOS =~ /[$POSGardees]/ && $Lemme ne $Pivot) {
        if ($Trace == 1) {print "\t===== $Ligne$FinLigne" ; }
        push(@LemmesGardes, $Lemme) ;
     }

  }

  $DocumentPrecedent   = $DocumentCourant ;
  $ParagraphePrecedent = $ParagrapheCourant ;
  $PhrasePrecedente    = $PhraseCourante ;
 
  
}

# Traitement de la dernière phrase
if ($Trace == 1) {
  print "\tLemmes gardés : " ;
  for ($l = 0 ; $l <= $#LemmesGardes ; $l++) {
    print "\t$LemmesGardes[$l]" ; 
  }
  print "$FinLigne" ; 
}
if ($#LemmesGardes > 0) {
  for ($l1 = 0 ; $l1 <= $#LemmesGardes ; $l1++) {
   $Lemme2Frequence{$LemmesGardes[$l1]}++ ;
  }
  for ($l1 = 0 ; $l1 < $#LemmesGardes ; $l1++) {
    for ($l2 = $l1 + 1 ; $l2 <= $#LemmesGardes ; $l2++) {
            $Cooccurrence = "$LemmesGardes[$l1]\t$LemmesGardes[$l2]" ;
            if ($Trace == 1) {print "\t$Cooccurrence\n" ;  }
            $Cooccurrence2Frequence{$Cooccurrence}++ ;
    }
  }
}
# Suppression des cooccurrences inférieures au plancher
foreach $Cooc (keys %Cooccurrence2Frequence) {
  if ($Cooccurrence2Frequence{$Cooc} < $Plancher) {
    delete $Cooccurrence2Frequence{$Cooc} ;
  }
}
# Calcul des noeuds restants. Convention : 1 comme valeur associée
%LemmesRestants = () ;
foreach $Cooc (keys %Cooccurrence2Frequence) {
  @ListeLemmes = split(/\t/, $Cooc) ;
  $Lemme1 = $ListeLemmes[0] ;
  $Lemme2 = $ListeLemmes[1] ;  
  $LemmesRestants{$Lemme1} = 1 ;  
  $LemmesRestants{$Lemme2} = 1 ;  
}
# Elimination des noeuds qui ne figurent pas dans $LemmesRestants
foreach $Lemme (keys %Lemme2Frequence) {
  if (!exists($LemmesRestants{$Lemme})) {
    delete $Lemme2Frequence{$Lemme} ; 
  }
}


# Numérotation des noeuds
$NumeroLemme = 1 ;
foreach $Lemme (keys %Lemme2Frequence) {
  $Lemme2NumeroLemme{$Lemme} = $NumeroLemme ;
  $NumeroLemme++ ;
}

# Impression du graphe résultant
open(SORTIE, ">$FichierSortie") ;  
imprimeEnTeteGraphML() ;
foreach $Lemme (keys %Lemme2Frequence) {
  if ($Trace == 1) {print "$Lemme\t$Lemme2Frequence{$Lemme}($Lemme2NumeroLemme{$Lemme})$FinLigne" ; }
  print SORTIE "    <node id=\"$Lemme2NumeroLemme{$Lemme}\"><data key=\"d0\">$Lemme</data></node>$FinLigne" ;
}
foreach $Cooc (keys %Cooccurrence2Frequence) {
  @ListeLemmes = split(/\t/, $Cooc) ;
  $Lemme1 = $ListeLemmes[0] ;
  $Lemme2 = $ListeLemmes[1] ;  
  if ($Trace == 1) {print "$Cooc\t$Cooccurrence2Frequence{$Cooc}\t$Lemme1($Lemme2NumeroLemme{$Lemme1})\t$Lemme2($Lemme2NumeroLemme{$Lemme2})$FinLigne" ; }
  print SORTIE "     <edge source=\"$Lemme2NumeroLemme{$Lemme1}\" target=\"$Lemme2NumeroLemme{$Lemme2}\"><data key=\"d1\">$Cooccurrence2Frequence{$Cooc}</data></edge>$FinLigne" ;
}
imprimeEnPiedGraphML() ;
close(SORTIE) ;

sub imprimeEnTeteGraphML{
  print SORTIE "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>
<graphml>
 <key id=\"d0\" for=\"node\" attr.name=\"nom\" attr.type=\"string\"/>
 <key id=\"d1\" for=\"edge\" attr.name=\"poids\" attr.type=\"double\"/>
 <graph edgedefault=\"undirected\">
" ; 
}

sub imprimeEnPiedGraphML{
  print SORTIE " </graph>
</graphml>
" ;
}
