Statistics
| Revision:

root / tmp / org.txm.analec.rcp / src / org / txm / macro / urs / edit / Frpos2CattexMacro.groovy @ 1217

History | View | Annotate | Download (10.7 kB)

1 671 mdecorde
// @author Matthieu Quignard
2 671 mdecorde
// Date : 04 Mai 2017
3 671 mdecorde
4 671 mdecorde
/*
5 671 mdecorde
Définit la catégorie grammaticale des mentions d'après le champ `frpos'
6 671 mdecorde
(tagset de TreeTagger).
7 671 mdecorde

8 671 mdecorde
La liste des catégories grammaticales est celle de CATTEX2009
9 671 mdecorde
-- Groupes nominaux :
10 671 mdecorde
        GN.NAM (noms propres) : Henri II
11 671 mdecorde
        GN.DEF (définis) : Le roi, du roi
12 671 mdecorde
        GN.IND (indéfinis) : Un roi
13 671 mdecorde
        GN.POS (possessifs) : [Mon roi]
14 671 mdecorde
        GN.DEM (demonstratif) : Ce roi
15 671 mdecorde
        GN.NUM (numéraux) : Deux rois
16 671 mdecorde
        GN.CHECK (GN indéterminés)
17 671 mdecorde
-- Déterminants
18 671 mdecorde
        DET.POS (possessifs) : [mon] roi
19 671 mdecorde
-- Pronoms
20 671 mdecorde
        PRO.PER (personnels) : je, moi, me, on, il, etc.
21 671 mdecorde
        PRO.ADV (adverbiaux) : y, en
22 671 mdecorde
        PRO.IND (indéfinis) : tout, tous, certains, plusieurs, etc.
23 671 mdecorde
        PRO.DEM (demonstratifs) : ceci, cela, ce, ça...
24 671 mdecorde
        PRO.POS (possessifs) : le mien, les nôtres...
25 671 mdecorde
        PRO.NUM (cardinaux, ordinaux) : les deux...
26 671 mdecorde
        PRO.REL (relatifs) : qui, que, quoi, duquel, etc.
27 671 mdecorde
        PRO.INT (interrogatifs)
28 671 mdecorde
        PRO.CHECK (pronoms indéterminés)
29 671 mdecorde
-- Sujet Zéro : verbes conjugués, éventuellement pronominal
30 671 mdecorde

31 671 mdecorde
-- ERREUR : erreur (a priori) de mention
32 671 mdecorde

33 671 mdecorde

34 671 mdecorde
*/
35 671 mdecorde
36 1217 mdecorde
package org.txm.macro.urs.edit
37 671 mdecorde
38 671 mdecorde
import org.apache.commons.lang.*
39 671 mdecorde
import org.kohsuke.args4j.*
40 671 mdecorde
import groovy.transform.*
41 671 mdecorde
import org.txm.*
42 671 mdecorde
import org.txm.rcp.swt.widget.parameters.*
43 1217 mdecorde
import org.txm.annotation.urs.*
44 671 mdecorde
import org.txm.searchengine.cqp.*
45 671 mdecorde
import org.txm.searchengine.cqp.corpus.*
46 671 mdecorde
import visuAnalec.Message.*
47 671 mdecorde
import visuAnalec.donnees.*
48 671 mdecorde
import visuAnalec.elements.*
49 671 mdecorde
import visuAnalec.vue.*
50 671 mdecorde
51 671 mdecorde
// Propriété donnant le lemme
52 671 mdecorde
def lemmaProperty = "frlemma"
53 671 mdecorde
54 671 mdecorde
/*
55 671 mdecorde
   TODO : TreeTagger fait un mauvais étiquetage des premiers mots de la phrase.
56 671 mdecorde
   La majuscule lui fait croire qu'il s'agit d'un nom propre.
57 671 mdecorde
   Vérifier que ce mot n'est pas en fait un pronom en testant sa présence dans une des listes de formes particulières
58 671 mdecorde
*/
59 671 mdecorde
60 671 mdecorde
61 671 mdecorde
/**
62 671 mdecorde
  * Liste de formes utile à la catégorisation des mentions
63 671 mdecorde
  * TreeTagger n'est pas forcément très performant sur des états plus anciens de la langue
64 671 mdecorde
***/
65 671 mdecorde
66 671 mdecorde
formesArticlesDéfinis = ["le", "la", "les", "l'", "au", "aux", "du", "des"]
67 671 mdecorde
formesArticlesIndéfinis = ["un", "une", "des"]
68 671 mdecorde
formesDéterminantsPossessifs = ["ma", "ta", "sa", "mon", "ton", "son", "mes", "tes", "ses", "notre", "votre", "leur", "nos", "vos", "leurs"]
69 671 mdecorde
formesAdjectifsDémonstratifs = ["ce", "cet", "cette", "ces"]
70 671 mdecorde
71 671 mdecorde
formesPronomsPersonnels = ["je", "tu", "il", "elle", "on", "nous", "vous", "ils", "elles", "moi", "toi", "eux", "me", "te", "se", "lui", "leur"]
72 671 mdecorde
formesPronomsAdverbiaux = ["en", "y"]
73 671 mdecorde
formesPronomsPossessifs = ["mien", "mienne", "miens", "miennes", "tien", "tienne", "tiens", "tiennes", "sien", "sienne", "siens", "siennes", "nôtre", "nôtres", "vôtre", "vôtres", "leur", "leurs"]
74 671 mdecorde
formesPronomsDémonstratifs = ["ce", "c'", "celui", "celle", "ceux", "celles", "ci", "ça", "ceci", "cela", "tel", "telle", "tels", "telles"]
75 671 mdecorde
76 671 mdecorde
toutesLesFormes = []
77 671 mdecorde
toutesLesFormes += formesArticlesDéfinis
78 671 mdecorde
toutesLesFormes += formesArticlesIndéfinis
79 671 mdecorde
toutesLesFormes += formesDéterminantsPossessifs
80 671 mdecorde
toutesLesFormes += formesAdjectifsDémonstratifs
81 671 mdecorde
toutesLesFormes += formesPronomsPersonnels
82 671 mdecorde
toutesLesFormes += formesPronomsAdverbiaux
83 671 mdecorde
toutesLesFormes += formesPronomsPossessifs
84 671 mdecorde
toutesLesFormes += formesPronomsDémonstratifs
85 671 mdecorde
86 671 mdecorde
/** Fin de la déclaration des formes **/
87 671 mdecorde
88 671 mdecorde
89 671 mdecorde
90 671 mdecorde
def testRules(def positions, def Mention) {
91 671 mdecorde
        def catégorie = null
92 671 mdecorde
    def forme = CQI.cpos2Str(word.getQualifiedName(), positions)[0].toLowerCase()
93 671 mdecorde
94 671 mdecorde
        if (Mention.length == 1) {
95 671 mdecorde
96 671 mdecorde
                     if (Mention.first() == "NAM"    ) catégorie = "GN.NAM"
97 671 mdecorde
                else if (Mention.first() == "DET:POS") catégorie = "DET.POS"
98 671 mdecorde
                else if (Mention.first() == "PRO:PER") {
99 671 mdecorde
                        if (formesPronomsAdverbiaux.contains(forme)) catégorie = "PRO.ADV"
100 671 mdecorde
                        else catégorie = "PRO.PER"
101 671 mdecorde
                }
102 671 mdecorde
                else if (Mention.first() == "PRO:DEM") catégorie = "PRO.DEM"
103 671 mdecorde
                else if (Mention.first() == "PRO:IND") catégorie = "PRO.IND"
104 671 mdecorde
                else if (Mention.first() == "PRO:REL") catégorie = "PRO.REL"
105 671 mdecorde
                else if (Mention.first().contains("VER:")) catégorie = "SUJ.ZERO"
106 671 mdecorde
                else if (Mention.first() == "PRO") catégorie = "PRO.INT"
107 671 mdecorde
108 671 mdecorde
                // GN indéfinis sans articles
109 671 mdecorde
                else if (Mention.first() == "NOM") catégorie = "GN.IND"
110 671 mdecorde
                else if (Mention.first() == "ADJ") catégorie = "GN.IND"
111 671 mdecorde
112 671 mdecorde
                // gestion des erreurs de TreeTagger
113 671 mdecorde
                else if (Mention.first() == "KON") catégorie = "PRO.REL" // Le 'que' dans une mention simple est un relatif
114 671 mdecorde
                else if (Mention.first() == "DET:ART") catégorie = "PRO.PER" // le, les
115 671 mdecorde
                else if (forme == "en") catégorie = "PRO.ADV"
116 671 mdecorde
117 671 mdecorde
                else if (Mention.first() == "ADV") catégorie = "ERREUR"  // un adverbe seul n'est jamais référentiel
118 671 mdecorde
                else if (Mention.first() == "PRE") catégorie = "ERREUR"  // une preposition seule n'est jamais référentielle
119 671 mdecorde
                else if (Mention.first() == "ADJ") catégorie = "ERREUR"  // un adjectif seul n'est jamais référentiel
120 671 mdecorde
                else if (Mention.first() == "INT") catégorie = "ERREUR"  // une interjection seule n'est jamais référentielle
121 671 mdecorde
122 671 mdecorde
                else catégorie = "PRO.CHECK"
123 671 mdecorde
        }
124 671 mdecorde
125 671 mdecorde
        else if (Mention.length == 2) {
126 671 mdecorde
                     if (Mention.contains("NAM")) catégorie = "GN.NAM"
127 671 mdecorde
                else if (Mention[1] == "PRO:POS") catégorie = "PRO.POS"  // "les miens"
128 671 mdecorde
                else if (Mention[1] == "NUM"    ) catégorie = "PRO.NUM"  // "les deux"
129 671 mdecorde
                else if (Mention[1] == "PRO:DEM") catégorie = "PRO.DEM"  // "Tout cela"
130 671 mdecorde
                else if (Mention[0] == "PRO:IND") catégorie = "GN.IND"   // "Quelques trucs"
131 671 mdecorde
                else if (Mention.contains("PRO:REL")) catégorie = "PRO.REL"
132 671 mdecorde
                else if ((Mention[0].contains("DET")) && (Mention[1] == "PROind")) catégorie = "PRO.IND" // des autres
133 671 mdecorde
                else if (Mention[1].contains("VER:")) catégorie = "SUJ.ZERO"
134 671 mdecorde
                else if (!Mention.contains("NOM") && !Mention.contains("ADJ")) {
135 671 mdecorde
                        if (Mention[0] == "PRO:DEM") catégorie = "PRO.DEM"
136 671 mdecorde
                        else catégorie = "PRO.CHECK"
137 671 mdecorde
                }
138 671 mdecorde
                else catégorie = "GN.CHECK"
139 671 mdecorde
        }
140 671 mdecorde
141 671 mdecorde
        if ( (catégorie == null) || (catégorie == "GN.CHECK") ) {
142 671 mdecorde
                // on est dans les GN
143 671 mdecorde
                     if (Mention[0] == "DET:POS" ) catégorie = "GN.POS"
144 671 mdecorde
                else if (Mention[0] == "NUM"     ) catégorie = "GN.NUM"
145 671 mdecorde
                else if (Mention[0] == "PRO:DEM" ) catégorie = "GN.DEM"
146 671 mdecorde
                else if (Mention[0] == "PRP:det" ) catégorie = "GN.DEF"
147 671 mdecorde
                else if (formesArticlesIndéfinis.contains(forme) || (forme == "une")) catégorie = "GN.IND"
148 671 mdecorde
                else if (formesArticlesDéfinis.contains(forme))   catégorie = "GN.DEF"
149 671 mdecorde
                else if (Mention[0] == "PRO:IND" ) catégorie = "GN.IND"
150 671 mdecorde
                else if (Mention[0] == "PRP" ) catégorie = "GN.IND"
151 671 mdecorde
                else if (Mention[0] == "ADJ" ) catégorie = "GN.IND"
152 671 mdecorde
                else if (Mention[0] == "NOM" ) catégorie = "GN.IND"
153 671 mdecorde
                else if (Mention.contains("NAM")) catégorie = "GN.NAM"
154 671 mdecorde
                else catégorie = "TEST"
155 671 mdecorde
        }
156 671 mdecorde
157 671 mdecorde
        return catégorie
158 671 mdecorde
}
159 671 mdecorde
160 671 mdecorde
//
161 671 mdecorde
// FIN DE LA DÉFINITION DES RÈGLES
162 671 mdecorde
//
163 671 mdecorde
164 671 mdecorde
// CORPS DU SCRIPT
165 671 mdecorde
166 671 mdecorde
if (!(corpusViewSelection instanceof MainCorpus)) {
167 671 mdecorde
        println "Corpora selection is not a Corpus"
168 671 mdecorde
        return
169 671 mdecorde
}
170 671 mdecorde
171 671 mdecorde
// BEGINNING OF PARAMETERS
172 671 mdecorde
@Field @Option(name="unit_type", usage="", widget="String", required=true, def="MENTION")
173 671 mdecorde
def unit_type
174 671 mdecorde
@Field @Option(name="pos_property_name", usage="", widget="String", required=true, def="pos")
175 671 mdecorde
def pos_property_name
176 671 mdecorde
@Field @Option(name="reset", usage="", widget="Boolean", required=true, def="true")
177 671 mdecorde
def reset
178 671 mdecorde
if (!ParametersDialog.open(this)) return
179 671 mdecorde
180 671 mdecorde
corpus = corpusViewSelection
181 786 sjacqu01
CQI = CQPSearchEngine.getCqiClient()
182 671 mdecorde
word = corpus.getWordProperty()
183 671 mdecorde
posProperty = corpus.getProperty(pos_property_name)
184 671 mdecorde
if (posProperty == null) {
185 671 mdecorde
        println "Error: CQP corpus does not contains the word property with name=$pos_property_name"
186 671 mdecorde
        return
187 671 mdecorde
}
188 1217 mdecorde
analecCorpus = URSCorpora.getCorpus(corpus)
189 1217 mdecorde
vue = URSCorpora.getVue(corpus)
190 671 mdecorde
structure = analecCorpus.getStructure()
191 671 mdecorde
if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
192 671 mdecorde
        println "Error: corpus structure does not contains unit with name=$unit_type"
193 671 mdecorde
        return
194 671 mdecorde
}
195 671 mdecorde
196 671 mdecorde
CATEGORIE = "CATEGORIE"
197 671 mdecorde
// Si la structure d'annotation ne contient pas CATEGORIE, on la crée avec ses valeurs
198 671 mdecorde
if (!structure.getUniteProperties(unit_type).contains(CATEGORIE)) {
199 671 mdecorde
200 671 mdecorde
// FIXME: dans le script original (see also
201 671 mdecorde
// http://forge.cbp.ens-lyon.fr/redmine/issues/2065), on utilise
202 671 mdecorde
// analecCorpus.ajouterProp/Val, mais cela ne marche pas dans ma version de
203 671 mdecorde
// TXM-Analec --> je retourne donc à structure.ajouterProp/Val
204 671 mdecorde
205 671 mdecorde
// la propriété
206 671 mdecorde
        structure.ajouterProp(Unite.class, unit_type, CATEGORIE)
207 671 mdecorde
// les valeurs
208 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.NAM")
209 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.DEF")
210 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.IND")
211 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.POS")
212 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.DEM")
213 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.NUM")
214 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "GN.CHECK")
215 671 mdecorde
216 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "DET.POS")
217 671 mdecorde
218 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.PER")
219 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.ADV")
220 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.IND")
221 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.DEM")
222 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.POS")
223 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.NUM")
224 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.INT")
225 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.REL")
226 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "PRO.CHECK")
227 671 mdecorde
228 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "SUJ.ZERO")
229 671 mdecorde
230 671 mdecorde
        structure.ajouterVal(Unite.class, unit_type, CATEGORIE, "ERREUR")
231 671 mdecorde
}
232 671 mdecorde
233 671 mdecorde
def nModified = 0
234 671 mdecorde
def nIgnored = 0
235 671 mdecorde
236 671 mdecorde
errors = new HashMap()
237 671 mdecorde
def units = analecCorpus.getUnites(unit_type)
238 671 mdecorde
units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
239 671 mdecorde
for (Unite unit : units) { // process all units
240 671 mdecorde
241 671 mdecorde
        def prop = unit.getProp(CATEGORIE)
242 671 mdecorde
        if (!reset && prop != null && prop.length() > 0) continue // l'unité a déjà une CATEGORIE
243 671 mdecorde
244 671 mdecorde
        int[] positions = null
245 671 mdecorde
        if (unit.getDeb() == unit.getFin()) positions = [unit.getDeb()]
246 671 mdecorde
        else positions = (unit.getDeb()..unit.getFin())
247 671 mdecorde
248 671 mdecorde
        def Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
249 671 mdecorde
        def cat = testRules(positions, Mention)
250 671 mdecorde
251 671 mdecorde
        if (cat != null) {
252 671 mdecorde
                // following line in the original script but doesn't work for me:
253 671 mdecorde
      // vue.setValeurChamp(unit, CATEGORIE, cat)
254 671 mdecorde
      unit.getProps().put(CATEGORIE, cat)
255 671 mdecorde
                nModified++
256 671 mdecorde
        } else {
257 671 mdecorde
                nIgnored++
258 671 mdecorde
        }
259 671 mdecorde
}
260 671 mdecorde
261 671 mdecorde
println "Result:"
262 671 mdecorde
println "- $nModified units of type $unit_type have been modified."
263 671 mdecorde
println "- $nIgnored units of type $unit_type have not been modified.\n"
264 671 mdecorde
265 671 mdecorde
if (errors.size() > 0) {
266 671 mdecorde
        println "Some rules should be added to this macro to process the following remaining 'FROPOS / words' values:"
267 671 mdecorde
        errors.keySet().each { println "fropos="+it+"\twords="+errors[it].join(" | ") }
268 671 mdecorde
}
269 671 mdecorde
270 671 mdecorde
// udpate the view (also see also
271 671 mdecorde
// http://forge.cbp.ens-lyon.fr/redmine/issues/2065)
272 1217 mdecorde
URSCorpora.getVue(analecCorpus).retablirVueParDefaut()