Statistics
| Revision:

root / tmp / org.txm.analec.rcp / src / org / txm / macro / urs / democrat / VerificationsMacro.groovy @ 2108

History | View | Annotate | Download (8.2 kB)

1
// Auteur Matthieu Quignard, Alexey Lavrentev
2
// Date : 14 janvier 2019
3

    
4
/**********
5
Vérifications automatiques :
6
1. Repère les mentions sans catégorie : CHECK > CAT
7
2. Repère les mentions sans référent : CHECK > REF
8
3. Supprime les ponctuations en début et en fin de mention : CHECK > BORNES
9
4. Supprime les prépositions autres que 'de' en début de mention : CHECK > BORNES
10
5. Supprime automatiquement toutes les mentions vides = sans aucun mot = de longueur 0
11
6. Détecter les mentions qui ont exactement les mêmes bornes  : CHECK > DOUBLON
12
7 (option). Détecter les pronoms hors mention : CHECK > NEW
13
***********/
14

    
15
package org.txm.macro.urs.democrat
16

    
17
import org.apache.commons.lang.*
18
import org.kohsuke.args4j.*
19
import groovy.transform.*
20
import org.txm.*
21
import org.txm.rcpapplication.swt.widget.parameters.*
22
import org.txm.analec.*
23
import org.txm.searchengine.cqp.*
24
import org.txm.searchengine.cqp.corpus.*
25
import visuAnalec.Message.*
26
import visuAnalec.donnees.*
27
import visuAnalec.elements.*
28
import visuAnalec.vue.*
29

    
30
// TODO : ajouter les étiquettes équivalentes issues du tagset TreeTagger
31
// Ponctuations et Prépositions
32
def interditsAuDebut = ["PONfbl", "PONfrt", "PONpxx", "PRE"]
33
// Ponctuations
34
def interditsALaFin = ["PONfbl", "PONfrt", "PONpxx"]
35
// Pronoms en tous genres
36
def listePronoms = ["PROadv", "PROcar", "PROdem", "PROimp", "PROind", "PROint", "PROper", "PROpos", "PROrel"]
37

    
38
// CORPS DU SCRIPT
39

    
40
if (!(corpusViewSelection instanceof MainCorpus)) {
41
        println "Corpora selection is not a Corpus"
42
        return
43
}
44

    
45
// BEGINNING OF PARAMETERS
46
@Field @Option(name="unit_type", usage="Unité", widget="String", required=true, def="MENTION")
47
def unit_type
48
@Field @Option(name="pos_property_name", usage="Etiquette de morphosyntaxe", widget="String", required=true, def="frpos")
49
def pos_property_name
50
@Field @Option(name="cat_name", usage="Propriété CATEGORIE", widget="String", required=true, def="CATEGORIE")
51
def cat_name
52
@Field @Option(name="ref_name", usage="Propriété REF", widget="String", required=true, def="REF")
53
def ref_name
54
@Field @Option(name="checkPronouns", usage="Vérifier les pronoms oubliés", widget="Boolean", required=true, def="true")
55
def checkPronouns
56

    
57
if (!ParametersDialog.open(this)) return
58

    
59
corpus = corpusViewSelection
60
CQI = Toolbox.getCqiClient()
61
word = corpus.getWordProperty()
62
posProperty = corpus.getProperty(pos_property_name)
63
if (posProperty == null) {
64
        println "Error: CQP corpus does not contains the word property with name=$pos_property_name"
65
        return
66
}
67

    
68
analecCorpus = AnalecCorpora.getCorpus(corpus.getName())
69
vue = AnalecCorpora.getVue(corpus.getName())
70
structure = analecCorpus.getStructure()
71

    
72
if (!structure.getUnites().contains(unit_type)) { // check if the structure contains the unit_type units
73
        println "Error: corpus structure does not contains unit with name=$unit_type"
74
        return
75
}
76

    
77
if (!structure.getUniteProperties(unit_type).contains(cat_name)) { 
78
        println "Erreur : les unités $unit_type n'ont pas de propriété $cat_name"
79
        return
80
}
81

    
82
if (!structure.getUniteProperties(unit_type).contains(ref_name)) { 
83
        println "Erreur : les unités $unit_type n'ont pas de propriété $ref_name"
84
        return
85
}
86

    
87
println "Détection des pronoms oubliés : $checkPronouns"
88

    
89
// Reinitialiser la propriété CHECK
90
if (!structure.getUniteProperties(unit_type).contains("CHECK")) {
91
        analecCorpus.ajouterProp(Unite.class, unit_type, "CHECK")
92
} else {
93
        println "Nettoyage des anciennes annotations CHECK"
94
          def tmpvalues = new HashSet()
95
        tmpvalues.addAll(structure.getValeursProp(Unite.class, unit_type, "CHECK"));
96
        for (String val : tmpvalues) {
97
                structure.supprimerVal(Unite.class, unit_type, "CHECK", val);
98
                //println "suppression de l'étiquette $val"
99
        }
100
}
101

    
102
structure.ajouterVal(Unite.class, unit_type, "CHECK", "DONE")
103

    
104
        
105

    
106
def nModified = 0
107
def nIgnored = 0
108
def nDeleted = 0
109
def nAdded = 0
110

    
111
def garbageBin = []
112

    
113
def nToks = corpus.getSize()
114
def tokenIndex = new int[nToks]
115

    
116
def i = 0
117
for (i=0 ; i< nToks ; i++) tokenIndex[i] = 1
118

    
119
errors = new HashMap()
120
def units = analecCorpus.getUnites(unit_type)
121
units.sort() { a, b -> a.getDeb() <=> b.getDeb() ?: a.getFin() <=> b.getFin() }
122

    
123
// pour les doublons
124
def lastUnit = null
125

    
126
for (Unite unit : units) { // process all units
127
        def erreur = ""
128
        
129
        // 1. Catégories vides
130
        def cat = unit.getProp( cat_name );
131
        if (cat == "") erreur += "CAT "
132
        
133
        // 2. Référents vides (plus grave) ; pas besoin de catégories
134
        def ref = unit.getProp( ref_name );
135
        if (ref == "") erreur += "REF "
136
        
137
        // 3. Suppression des erreurs initiales ; besoin de catégories
138
        int[] positions = null
139
        if (unit.getDeb() == unit.getFin()) positions = [unit.getDeb()]
140
        else positions = (unit.getDeb()..unit.getFin())
141
        def Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
142
        
143
        def isOK = false
144
        while (isOK == false) {
145
           if (interditsAuDebut.contains(Mention[0])) {
146
              if (positions.size() == 1) {
147
                 erreur += "SUPPR"
148
                 isOK = true
149
              } else {
150
                 def debut = unit.getDeb()
151
                 unit.setDeb(  debut + 1 )
152
                 
153
                 if (unit.getDeb() == unit.getFin()) positions = [unit.getDeb()]
154
                         else positions = (unit.getDeb()..unit.getFin())
155
                         Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
156
                         if (!erreur.contains("BORNESG")) erreur += "BORNESG "
157
              }
158
           } else { 
159
              isOK = true
160
           } 
161
        }
162
        
163
        
164
        // 4. Suppression des erreurs de borne de fin ; besoin de catégories
165
        if (unit.getDeb() == unit.getFin()) positions = [unit.getDeb()]
166
        else positions = (unit.getDeb()..unit.getFin())
167
        Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
168
        
169
        isOK = false
170
        while ((isOK == false) && (erreur != "remove")) {
171
                def n = Mention.size()
172
                if (interditsALaFin.contains(Mention[ n-1 ])) {
173
                        if (positions.size() == 1) {
174
                 if (!erreur.contains("SUPPR")) erreur += "SUPPR"
175
                 isOK = true
176
              } else {
177
                 def fin = unit.getFin()
178
                 unit.setFin(  fin - 1 )
179
                 
180
                 if (unit.getDeb() == unit.getFin()) positions = [unit.getDeb()]
181
                         else positions = (unit.getDeb()..unit.getFin())
182
                         Mention = CQI.cpos2Str(posProperty.getQualifiedName(), positions)
183
                         if (!erreur.contains("BORNESD")) erreur += "BORNESD "
184
              }
185
                } else isOK = true
186
        }
187
        
188
        // 5. Suppression des unités problématiques (bornes incohérentes ou mot vide) ; pas besoin de catégories
189
        def forme = CQI.cpos2Str(word.getQualifiedName(), positions)[0].trim().toLowerCase()
190
        
191
        if (erreur == "remove") {}
192
        else if (unit.getFin() < unit.getDeb()) {
193
           println "ERREUR GRAVE : segmentation incohérente"
194
           erreur = "remove"
195
        } else if ( forme.length() == 0 ) {
196
           println "ERREUR GRAVE : unité sans mot"
197
           erreur = "remove"
198
        }
199
        
200
        // 6. Détection des doublons ; pas besoin de catégories
201
        if (lastUnit != null) {
202
           if ((unit.getDeb() == lastUnit.getDeb()) && (unit.getFin() == lastUnit.getFin()) ) {
203
                           erreur += " DOUBLON "
204
           }
205
        }
206
        lastUnit = unit
207
        
208
        
209
        erreur = erreur.trim()
210
        if (erreur == "remove") {
211
            garbageBin.add( unit )
212
                nDeleted++
213
        } else if (erreur != "") {
214
                vue.setValeurChamp(unit, "CHECK", erreur)
215
                nModified++
216
        } else {
217
                nIgnored++
218
        }
219
        
220
        // mise à jour des tokens couverts
221
        for (int p=unit.getDeb() ; p <= unit.getFin() ; p++) {
222
           tokenIndex[p] = 0
223
        }
224
}
225

    
226
// Suppression effective des unités incohérentes
227
garbageBin.each {
228
   analecCorpus.supUnite( it )
229
}
230

    
231
// 7. Ajouter les pronoms non couverts par une annotation ; besoin de catégories
232
// Parcourir les tokens non couverts ; obtenir leur POS et créer une unité si c'est un pronom
233

    
234
if (checkPronouns) {
235
        println "Détection des pronoms oubliés"
236
        for (i=0 ; i < nToks ; i++) {
237
            if (tokenIndex[i] > 0) {
238
                        Mention = CQI.cpos2Str(posProperty.getQualifiedName(), i)
239
                        if (listePronoms.contains(Mention[0])) {
240
                            def props = [:]
241
                        props["CHECK"] = "NEW"
242
                        Unite u = analecCorpus.addUniteSaisie(unit_type, i, i, props)
243
                        vue.setValeurChamp(u, "CHECK", "NEW")
244
                            nAdded++
245
                    }
246
                }
247
        }
248
}
249

    
250
if (nAdded + nModified + nDeleted > 0) corpus.setIsModified(true);
251

    
252
println "Result:"
253
println "- $nModified units of type $unit_type have been modified."
254
println "- $nDeleted units of type $unit_type have been deleted."
255
println "- $nIgnored units of type $unit_type have not been modified."
256
println "- $nAdded forgotten pronominal units of type $unit_type have been added.\n"
257

    
258
AnalecCorpora.getVue(analecCorpus).retablirVueParDefaut()